diff --git a/nixos/doc/manual/configuration/x-windows.xml b/nixos/doc/manual/configuration/x-windows.xml index 4008e89fceac..95e66f0c70c0 100644 --- a/nixos/doc/manual/configuration/x-windows.xml +++ b/nixos/doc/manual/configuration/x-windows.xml @@ -73,6 +73,25 @@ hardware.opengl.driSupport32Bit = true; +AMD Graphics Cards + +AMD provides a proprietary driver for its graphics cards that +has better 3D performance than the X.org drivers. It is not enabled +by default because it’s not free software. You can enable it as follows: + +services.xserver.videoDrivers = [ "ati_unfree" ]; + +You will need to reboot after enabling this driver to prevent a clash +with other kernel modules. + +On 64-bit systems, if you want full acceleration for 32-bit +programs such as Wine, you should also set the following: + +hardware.opengl.driSupport32Bit = true; + + + + Touchpads diff --git a/nixos/modules/hardware/opengl.nix b/nixos/modules/hardware/opengl.nix index f894c830eb6c..1777c200dd11 100644 --- a/nixos/modules/hardware/opengl.nix +++ b/nixos/modules/hardware/opengl.nix @@ -46,7 +46,8 @@ in description = '' On 64-bit systems, whether to support Direct Rendering for 32-bit applications (such as Wine). This is currently only - supported for the nvidia driver and for + supported for the nvidia and + ati_unfree drivers, as well as Mesa. ''; }; @@ -104,22 +105,9 @@ in environment.sessionVariables.LD_LIBRARY_PATH = [ "/run/opengl-driver/lib" "/run/opengl-driver-32/lib" ]; - # FIXME: move this into card-specific modules. - hardware.opengl.package = mkDefault - (if elem "ati_unfree" videoDrivers then - kernelPackages.ati_drivers_x11 - else - makePackage pkgs); - + hardware.opengl.package = mkDefault (makePackage pkgs); hardware.opengl.package32 = mkDefault (makePackage pkgs_i686); - boot.extraModulePackages = - optional (elem "virtualbox" videoDrivers) kernelPackages.virtualboxGuestAdditions ++ - optional (elem "ati_unfree" videoDrivers) kernelPackages.ati_drivers_x11; - - environment.etc = - optionalAttrs (elem "ati_unfree" videoDrivers) { - "ati".source = "${kernelPackages.ati_drivers_x11}/etc/ati"; - }; + boot.extraModulePackages = optional (elem "virtualbox" videoDrivers) kernelPackages.virtualboxGuestAdditions; }; } diff --git a/nixos/modules/hardware/video/ati.nix b/nixos/modules/hardware/video/ati.nix new file mode 100644 index 000000000000..033e49d2233e --- /dev/null +++ b/nixos/modules/hardware/video/ati.nix @@ -0,0 +1,37 @@ +# This module provides the proprietary ATI X11 / OpenGL drivers. + +{ config, lib, pkgs, pkgs_i686, ... }: + +with lib; + +let + + drivers = config.services.xserver.videoDrivers; + + enabled = elem "ati_unfree" drivers; + + ati_x11 = config.boot.kernelPackages.ati_drivers_x11; + +in + +{ + + config = mkIf enabled { + + services.xserver.drivers = singleton + { name = "fglrx"; modules = [ ati_x11 ]; libPath = [ "${ati_x11}/lib" ]; }; + + hardware.opengl.package = ati_x11; + hardware.opengl.package32 = pkgs_i686.linuxPackages.ati_drivers_x11.override { libsOnly = true; kernel = null; }; + + environment.systemPackages = [ ati_x11 ]; + + boot.extraModulePackages = [ ati_x11 ]; + + boot.blacklistedKernelModules = [ "radeon" ]; + + environment.etc."ati".source = "${ati_x11}/etc/ati"; + + }; + +} diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 25827656608d..82e3dfe4525d 100755 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -38,6 +38,7 @@ ./hardware/pcmcia.nix ./hardware/video/bumblebee.nix ./hardware/video/nvidia.nix + ./hardware/video/ati.nix ./installer/tools/nixos-checkout.nix ./installer/tools/tools.nix ./misc/assertions.nix diff --git a/nixos/modules/services/x11/xserver.nix b/nixos/modules/services/x11/xserver.nix index 21eaf6bb6b76..c08afe2041f4 100644 --- a/nixos/modules/services/x11/xserver.nix +++ b/nixos/modules/services/x11/xserver.nix @@ -13,7 +13,6 @@ let # Map video driver names to driver packages. FIXME: move into card-specific modules. knownVideoDrivers = { - ati_unfree = { modules = [ kernelPackages.ati_drivers_x11 ]; driverName = "fglrx"; }; nouveau = { modules = [ pkgs.xf86_video_nouveau ]; }; unichrome = { modules = [ pkgs.xorgVideoUnichrome ]; }; virtualbox = { modules = [ kernelPackages.virtualboxGuestAdditions ]; driverName = "vboxvideo"; }; @@ -444,8 +443,7 @@ in pkgs.xterm pkgs.xdg_utils ] - ++ optional (elem "virtualbox" cfg.videoDrivers) xorg.xrefresh - ++ optional (elem "ati_unfree" cfg.videoDrivers) kernelPackages.ati_drivers_x11; + ++ optional (elem "virtualbox" cfg.videoDrivers) xorg.xrefresh; environment.pathsToLink = [ "/etc/xdg" "/share/xdg" "/share/applications" "/share/icons" "/share/pixmaps" ]; @@ -465,8 +463,6 @@ in XORG_DRI_DRIVER_PATH = "/run/opengl-driver/lib/dri"; # !!! Depends on the driver selected at runtime. LD_LIBRARY_PATH = concatStringsSep ":" ( [ "${xorg.libX11}/lib" "${xorg.libXext}/lib" ] - ++ optionals (elem "ati_unfree" cfg.videoDrivers) - [ "${kernelPackages.ati_drivers_x11}/lib" "${kernelPackages.ati_drivers_x11}/X11R6/lib64/modules/linux" ] ++ concatLists (catAttrs "libPath" cfg.drivers)); } // cfg.displayManager.job.environment; diff --git a/pkgs/os-specific/linux/ati-drivers/builder.sh b/pkgs/os-specific/linux/ati-drivers/builder.sh index d1ca1b354522..c91274c50bf1 100644 --- a/pkgs/os-specific/linux/ati-drivers/builder.sh +++ b/pkgs/os-specific/linux/ati-drivers/builder.sh @@ -8,126 +8,129 @@ die(){ echo $@; exit 1; } # custom unpack: unzip $src -run_file=$(echo amd-catalyst-*) +run_file=$(echo fglrx-*/amd-driver-installer-*) sh $run_file --extract . eval "$patchPhase" -kernelVersion=$(cd ${kernel}/lib/modules && ls) -kernelBuild=$(echo ${kernel}/lib/modules/$kernelVersion/build) -linuxsources=$(echo ${kernel}/lib/modules/$kernelVersion/source) +case "$system" in + x86_64-linux) + arch=x86_64 + lib_arch=lib64 + DIR_DEPENDING_ON_XORG_VERSION=xpic_64a + ;; + i686-linux) + arch=x86 + lib_arch=lib + DIR_DEPENDING_ON_XORG_VERSION=xpic + ;; + *) exit 1;; +esac +# Handle/Build the kernel module. +if test -z "$libsOnly"; then -# note: maybe the .config file should be used to determine this ? -# current kbuild infrastructure allows using CONFIG_* defines -# but ati sources don't use them yet.. -# copy paste from make.sh -setSMP(){ + kernelVersion=$(cd ${kernel}/lib/modules && ls) + kernelBuild=$(echo ${kernel}/lib/modules/$kernelVersion/build) + linuxsources=$(echo ${kernel}/lib/modules/$kernelVersion/source) - linuxincludes=$kernelBuild/include + # note: maybe the .config file should be used to determine this ? + # current kbuild infrastructure allows using CONFIG_* defines + # but ati sources don't use them yet.. + # copy paste from make.sh + setSMP(){ - # copied and stripped. source: make.sh: + linuxincludes=$kernelBuild/include - # 3 - # linux/autoconf.h may contain this: #define CONFIG_SMP 1 + # copied and stripped. source: make.sh: + # 3 + # linux/autoconf.h may contain this: #define CONFIG_SMP 1 - # Before 2.6.33 autoconf.h is under linux/. - # For 2.6.33 and later autoconf.h is under generated/. - if [ -f $linuxincludes/generated/autoconf.h ]; then - autoconf_h=$linuxincludes/generated/autoconf.h - else - autoconf_h=$linuxincludes/linux/autoconf.h - fi - src_file=$autoconf_h + # Before 2.6.33 autoconf.h is under linux/. + # For 2.6.33 and later autoconf.h is under generated/. + if [ -f $linuxincludes/generated/autoconf.h ]; then + autoconf_h=$linuxincludes/generated/autoconf.h + else + autoconf_h=$linuxincludes/linux/autoconf.h + fi + src_file=$autoconf_h - [ -e $src_file ] || die "$src_file not found" + [ -e $src_file ] || die "$src_file not found" - if [ `cat $src_file | grep "#undef" | grep "CONFIG_SMP" -c` = 0 ]; then - SMP=`cat $src_file | grep CONFIG_SMP | cut -d' ' -f3` - echo "file $src_file says: SMP=$SMP" - fi + if [ `cat $src_file | grep "#undef" | grep "CONFIG_SMP" -c` = 0 ]; then + SMP=`cat $src_file | grep CONFIG_SMP | cut -d' ' -f3` + echo "file $src_file says: SMP=$SMP" + fi - if [ "$SMP" = 0 ]; then - echo "assuming default: SMP=$SMP" - fi + if [ "$SMP" = 0 ]; then + echo "assuming default: SMP=$SMP" + fi - # act on final result - if [ ! "$SMP" = 0 ]; then - smp="-SMP" - def_smp=-D__SMP__ - fi + # act on final result + if [ ! "$SMP" = 0 ]; then + smp="-SMP" + def_smp=-D__SMP__ + fi -} + } -setModVersions(){ - ! grep CONFIG_MODVERSIONS=y $kernel/config || - def_modversions="-DMODVERSIONS" - # make.sh contains much more code to determine this whether its enabled -} + setModVersions(){ + ! grep CONFIG_MODVERSIONS=y $kernelBuild/.config || + def_modversions="-DMODVERSIONS" + # make.sh contains much more code to determine this whether its enabled + } -# ============================================================== -# resolve if we are building for a kernel with a fix for CVE-2010-3081 -# On kernels with the fix, use arch_compat_alloc_user_space instead -# of compat_alloc_user_space since the latter is GPL-only + # ============================================================== + # resolve if we are building for a kernel with a fix for CVE-2010-3081 + # On kernels with the fix, use arch_compat_alloc_user_space instead + # of compat_alloc_user_space since the latter is GPL-only -COMPAT_ALLOC_USER_SPACE=arch_compat_alloc_user_space + COMPAT_ALLOC_USER_SPACE=arch_compat_alloc_user_space -for src_file in \ + for src_file in \ $kernelBuild/arch/x86/include/asm/compat.h \ $linuxsources/arch/x86/include/asm/compat.h \ $kernelBuild/include/asm-x86_64/compat.h \ $linuxsources/include/asm-x86_64/compat.h \ $kernelBuild/include/asm/compat.h; -do - if [ -e $src_file ]; - then - break + do + if [ -e $src_file ]; + then + break + fi + done + if [ ! -e $src_file ]; + then + echo "Warning: x86 compat.h not found in kernel headers" + echo "neither arch/x86/include/asm/compat.h nor include/asm-x86_64/compat.h" + echo "could be found in $kernelBuild or $linuxsources" + echo "" + else + if [ `cat $src_file | grep -c arch_compat_alloc_user_space` -gt 0 ] + then + COMPAT_ALLOC_USER_SPACE=arch_compat_alloc_user_space + fi + echo "file $src_file says: COMPAT_ALLOC_USER_SPACE=$COMPAT_ALLOC_USER_SPACE" fi -done -if [ ! -e $src_file ]; -then - echo "Warning: x86 compat.h not found in kernel headers" - echo "neither arch/x86/include/asm/compat.h nor include/asm-x86_64/compat.h" - echo "could be found in $kernelBuild or $linuxsources" - echo "" -else - if [ `cat $src_file | grep -c arch_compat_alloc_user_space` -gt 0 ] - then - COMPAT_ALLOC_USER_SPACE=arch_compat_alloc_user_space - fi - echo "file $src_file says: COMPAT_ALLOC_USER_SPACE=$COMPAT_ALLOC_USER_SPACE" -fi + # make.sh contains some code figuring out whether to use these or not.. + PAGE_ATTR_FIX=0 + setSMP + setModVersions + CC=gcc + MODULE=fglrx + LIBIP_PREFIX=$TMP/arch/$arch/lib/modules/fglrx/build_mod + [ -d $LIBIP_PREFIX ] + GCC_MAJOR="`gcc --version | grep -o -e ") ." | head -1 | cut -d " " -f 2`" -# make.sh contains some code figuring out whether to use these or not.. -PAGE_ATTR_FIX=0 -setSMP -setModVersions -CC=gcc -MODULE=fglrx -case "$system" in - x86_64-linux) - arch=x86_64 - lib_arch=lib64 - ;; - i686-linux) - arch=x86 - lib_arch=lib - ;; - *) exit 1;; -esac -LIBIP_PREFIX=$TMP/arch/$arch/lib/modules/fglrx/build_mod -[ -d $LIBIP_PREFIX ] -GCC_MAJOR="`gcc --version | grep -o -e ") ." | head -1 | cut -d " " -f 2`" + { # build .ko module + cd ./common/lib/modules/fglrx/build_mod/2.6.x + echo .lib${MODULE}_ip.a.GCC${GCC_MAJOR}.cmd + echo 'This is a dummy file created to suppress this warning: could not find /lib/modules/fglrx/build_mod/2.6.x/.libfglrx_ip.a.GCC4.cmd for /lib/modules/fglrx/build_mod/2.6.x/libfglrx_ip.a.GCC4' > lib${MODULE}_ip.a.GCC${GCC_MAJOR}.cmd -{ # build .ko module - cd ./common/lib/modules/fglrx/build_mod/2.6.x - echo .lib${MODULE}_ip.a.GCC${GCC_MAJOR}.cmd - echo 'This is a dummy file created to suppress this warning: could not find /lib/modules/fglrx/build_mod/2.6.x/.libfglrx_ip.a.GCC4.cmd for /lib/modules/fglrx/build_mod/2.6.x/libfglrx_ip.a.GCC4' > lib${MODULE}_ip.a.GCC${GCC_MAJOR}.cmd + sed -i -e "s@COMPAT_ALLOC_USER_SPACE@$COMPAT_ALLOC_USER_SPACE@" ../kcl_ioctl.c - sed -i -e "s@COMPAT_ALLOC_USER_SPACE@$COMPAT_ALLOC_USER_SPACE@" ../kcl_ioctl.c - - make CC=${CC} \ + make CC=${CC} \ LIBIP_PREFIX=$(echo "$LIBIP_PREFIX" | sed -e 's|^\([^/]\)|../\1|') \ MODFLAGS="-DMODULE -DATI -DFGL -DPAGE_ATTR_FIX=$PAGE_ATTR_FIX -DCOMPAT_ALLOC_USER_SPACE=$COMPAT_ALLOC_USER_SPACE $def_smp $def_modversions" \ KVER=$kernelVersion \ @@ -135,8 +138,10 @@ GCC_MAJOR="`gcc --version | grep -o -e ") ." | head -1 | cut -d " " -f 2`" PAGE_ATTR_FIX=$PAGE_ATTR_FIX \ -j4 - cd $TMP -} + cd $TMP + } + +fi { # install @@ -152,13 +157,15 @@ GCC_MAJOR="`gcc --version | grep -o -e ") ." | head -1 | cut -d " " -f 2`" # what are those files used for? cp -r common/etc $out - DIR_DEPENDING_ON_XORG_VERSION=xpic_64a cp -r $DIR_DEPENDING_ON_XORG_VERSION/usr/X11R6/$lib_arch/* $out/lib/xorg - t=$out/lib/modules/${kernelVersion}/kernel/drivers/misc - mkdir -p $t + # install kernel module + if test -z "$libsOnly"; then + t=$out/lib/modules/${kernelVersion}/kernel/drivers/misc + mkdir -p $t - cp ./common/lib/modules/fglrx/build_mod/2.6.x/fglrx.ko $t + cp ./common/lib/modules/fglrx/build_mod/2.6.x/fglrx.ko $t + fi # should this be installed at all? # its used by the example fglrx_gamma only @@ -181,10 +188,46 @@ GCC_MAJOR="`gcc --version | grep -o -e ") ." | head -1 | cut -d " " -f 2`" # make xorg use the ati version ln -s $out/lib/xorg/modules/extensions/{fglrx/fglrx-libglx.so,libglx.so} + # Correct some paths that are hardcoded into binary libs. + if [ "$arch" == "x86_64" ]; then + for lib in \ + lib/xorg/modules/extensions/fglrx/fglrx-libglx.so \ + lib/xorg/modules/glesx.so \ + lib/dri/fglrx_dri.so \ + lib/fglrx_dri.so \ + lib/fglrx-libGL.so.1.2 + do + oldPaths="/usr/X11R6/lib/modules/dri" + newPaths="/run/opengl-driver/lib/dri" + sed -i -e "s|$oldPaths|$newPaths|" $out/$lib + done + else + oldPaths="/usr/X11R6/lib32/modules/dri\x00/usr/lib32/dri" + newPaths="/run/opengl-driver-32/lib/dri\x00/dev/null/dri" + sed -i -e "s|$oldPaths|$newPaths|" \ + $out/lib/xorg/modules/extensions/fglrx/fglrx-libglx.so + + for lib in \ + lib/dri/fglrx_dri.so \ + lib/fglrx_dri.so \ + lib/xorg/modules/glesx.so + do + oldPaths="/usr/X11R6/lib32/modules/dri/" + newPaths="/run/opengl-driver-32/lib/dri" + sed -i -e "s|$oldPaths|$newPaths|" $out/$lib + done + + oldPaths="/usr/X11R6/lib32/modules/dri\x00" + newPaths="/run/opengl-driver-32/lib/dri" + sed -i -e "s|$oldPaths|$newPaths|" $out/lib/fglrx-libGL.so.1.2 + fi + # libstdc++ and gcc are needed by some libs patchelf --set-rpath $gcc/$lib_arch $out/lib/libatiadlxx.so } +if test -z "$libsOnly"; then + { # build samples mkdir -p $out/bin @@ -229,6 +272,8 @@ GCC_MAJOR="`gcc --version | grep -o -e ") ." | head -1 | cut -d " " -f 2`" } +fi + for p in $extraDRIlibs; do for lib in $p/lib/*.so*; do ln -s $lib $out/lib/ diff --git a/pkgs/os-specific/linux/ati-drivers/default.nix b/pkgs/os-specific/linux/ati-drivers/default.nix index 0aa67dba2378..45452c1ea6d2 100644 --- a/pkgs/os-specific/linux/ati-drivers/default.nix +++ b/pkgs/os-specific/linux/ati-drivers/default.nix @@ -1,10 +1,16 @@ -{ stdenv, fetchurl, kernel, xlibs, which, imake +{ stdenv, fetchurl, kernel ? null, xlibs, which, imake , mesa # for fgl_glxgears , libXxf86vm, xf86vidmodeproto # for fglrx_gamma , xorg, makeWrapper, glibc, patchelf , unzip +, # Whether to build the libraries only (i.e. not the kernel module or + # driver utils). Used to support 32-bit binaries on 64-bit + # Linux. + libsOnly ? false }: +assert (!libsOnly) -> kernel != null; + # If you want to use a different Xorg version probably # DIR_DEPENDING_ON_XORG_VERSION in builder.sh has to be adopted (?) # make sure libglx.so of ati is used. xorg.xorgserver does provide it as well @@ -21,12 +27,10 @@ # There is one issue left: # /usr/lib/dri/fglrx_dri.so must point to /run/opengl-driver/lib/fglrx_dri.so -# You eventually have to blacklist radeon module (?) - -assert stdenv.system == "x86_64-linux"; +with stdenv.lib; stdenv.mkDerivation { - name = "ati-drivers-13.12-${kernel.version}"; + name = "ati-drivers-14.4" + (optionalString (!libsOnly) "-${kernel.version}"); builder = ./builder.sh; @@ -34,8 +38,8 @@ stdenv.mkDerivation { gcc = stdenv.gcc.gcc; src = fetchurl { - url = http://www2.ati.com/drivers/linux/amd-catalyst-13.12-linux-x86.x86_64.zip; - sha256 = "1c3fn328340by4qn99dgfj8c2q34fxdb2alcak0vnyc6bw7l5sms"; + url = http://www2.ati.com/drivers/linux/amd-catalyst-14-4-rev2-linux-x86-x86-64-may6.zip; + sha256 = "1xbhn55yifis9b0lzb3s03hc1bcq8jmy7l96m4x8d842n7ji7qlk"; curlOpts = "--referer http://support.amd.com/en-us/download/desktop?os=Linux%20x86_64"; }; @@ -51,7 +55,9 @@ stdenv.mkDerivation { mesa ]; - kernel = kernel.dev; + inherit libsOnly; + + kernel = if libsOnly then null else kernel.dev; inherit glibc /* glibc only used for setting interpreter */; @@ -75,15 +81,7 @@ stdenv.mkDerivation { homepage = http://support.amd.com/us/gpudownload/Pages/index.aspx; license = licenses.unfree; maintainers = with maintainers; [marcweber offline]; - platforms = [ "x86_64-linux" ]; + platforms = platforms.linux; hydraPlatforms = []; }; - - # moved assertions here because the name is evaluated when the NixOS manual is generated - # Don't make that fail - fail lazily when a users tries to build this derivation only - dummy = - # assert xorg.xorgserver.name == "xorg-server-1.7.5"; - assert stdenv.system == "x86_64-linux"; # i686-linux should work as well - however I didn't test it. - null; - } diff --git a/pkgs/os-specific/linux/ati-drivers/gentoo-patches.patch b/pkgs/os-specific/linux/ati-drivers/gentoo-patches.patch index 392c2a8c29e3..fd1d12cccb62 100644 --- a/pkgs/os-specific/linux/ati-drivers/gentoo-patches.patch +++ b/pkgs/os-specific/linux/ati-drivers/gentoo-patches.patch @@ -31,21 +31,3 @@ index d3ad3ce..9362b58 100755 +# endif #endif } - - -diff -urN a/common/lib/modules/fglrx/build_mod/kcl_acpi.c common/lib/modules/fglrx/build_mod/kcl_acpi.c ---- a/common/lib/modules/fglrx/build_mod/kcl_acpi.c 2013-12-27 13:32:34.734832283 +0100 -+++ b/common/lib/modules/fglrx/build_mod/kcl_acpi.c 2013-12-27 13:33:31.849831765 +0100 -@@ -1002,7 +1002,11 @@ - #endif - { - return KCL_ACPI_ERROR; -- } -+ } -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,1) -+ ((acpi_tbl_table_handler)handler)(hdr); -+#else - ((acpi_table_handler)handler)(hdr); -+#endif - return KCL_ACPI_OK; - }