summary refs log blame commit diff
path: root/pkgs/os-specific/linux/amdgpu-pro/default.nix
blob: 241145a24843ca577e9fcfcefe611223ae07133f (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13












              
        

               

  
         


   


                                                  
                                                      
                      
                                                             
                        
                                                  
 

                            
                    
                       
                               

                  


                                                                                                         

    
                 
              

                                                                            
      
                                                
        
        


                                                                             

     



                                                              
 





                                                                                                                                                                                                                                    
 























                                                                                                                         
 


                                                                      
 


                                      
 











                                                         

                                














                                                                          


                   

                      
                 
 

                                     
 






                                                               

        






                                           

        



                                                  
         




                                                                                             

     

































                                                                                                                          


                 
          





                                
                    
                                       
                                                 


                                                 

    
{ lib
, stdenv
, fetchurl
, elfutils
, xorg
, patchelf
, libxcb
, libxshmfence
, perl
, zlib
, expat
, libffi
, libselinux
, libdrm
, udev
, kernel ? null
}:

with lib;

let

  bitness = if stdenv.is64bit then "64" else "32";

  libArch =
    if stdenv.hostPlatform.system == "i686-linux" then
      "i386-linux-gnu"
    else if stdenv.hostPlatform.system == "x86_64-linux" then
      "x86_64-linux-gnu"
    else throw "amdgpu-pro is Linux only. Sorry.";

in stdenv.mkDerivation rec {

  version = "21.30";
  pname = "amdgpu-pro";
  build = "${version}-1290604";

  src = fetchurl {
    url = "https://drivers.amd.com/drivers/linux/amdgpu-pro-${build}-ubuntu-20.04.tar.xz";
    sha256 = "sha256-WECqxjo2WLP3kMWeVyJgYufkvHTzwGaj57yeMGXiQ4I=";
    curlOpts = "--referer https://www.amd.com/en/support/kb/release-notes/rn-amdgpu-unified-linux-21-30";
  };

  postUnpack = ''
    mkdir root
    pushd $sourceRoot
    for deb in *_all.deb *_${if stdenv.is64bit then "amd64" else "i386"}.deb
    do
      ar p $deb data.tar.xz | tar -C ../root -xJ
    done
    popd
    # if we don't use a short sourceRoot, compilation can fail due to command
    # line length
    sourceRoot=root
  '';

  passthru = optionalAttrs (kernel != null) {
    kmod = stdenv.mkDerivation rec {
      inherit version src postUnpack;
      name = "${pname}-${version}-kmod-${kernel.dev.version}";

      postPatch = ''
        pushd usr/src/amdgpu-*
        patchShebangs amd/dkms/*.sh
        substituteInPlace amd/dkms/pre-build.sh --replace "./configure" "./configure --with-linux=${kernel.dev}/lib/modules/${kernel.modDirVersion}/source --with-linux-obj=${kernel.dev}/lib/modules/${kernel.modDirVersion}/build"
        popd
      '';

      preConfigure = ''
        pushd usr/src/amdgpu-*
        makeFlags="$makeFlags M=$(pwd)"
        amd/dkms/pre-build.sh ${kernel.version}
        popd
      '';

      postBuild = ''
        pushd usr/src/amdgpu-*
        find -name \*.ko -exec xz {} \;
        popd
      '';

      makeFlags = optionalString (kernel != null) "-C ${kernel.dev}/lib/modules/${kernel.modDirVersion}/build modules";

      installPhase = ''
        runHook preInstall

        pushd usr/src/amdgpu-*
        find -name \*.ko.xz -exec install -Dm444 {} $out/lib/modules/${kernel.modDirVersion}/kernel/drivers/gpu/drm/{} \;
        popd

        runHook postInstall
      '';

      # without this we get a collision with the ttm module from linux
      meta.priority = 4;
    };

    fw = stdenv.mkDerivation rec {
      inherit version src postUnpack;
      name = "${pname}-${version}-fw";

      installPhase = ''
        runHook preInstall

        mkdir -p $out/lib
        cp -r usr/src/amdgpu-*/firmware $out/lib/firmware

        runHook postInstall
      '';
    };
  };

  outputs = [ "out" "vulkan" ];

  depLibPath = makeLibraryPath [
    stdenv.cc.cc.lib
    zlib
    libxcb
    libxshmfence
    elfutils
    expat
    libffi
    libselinux
    # libudev is not listed in any dependencies, but is loaded dynamically
    udev
    xorg.libXext
    xorg.libX11
    xorg.libXfixes
    xorg.libXdamage
    xorg.libXxf86vm
  ];

  installPhase = ''
    runHook preInstall

    mkdir -p $out

    cp -r usr/lib/${libArch} $out/lib
    cp -r usr/share $out/share

    mkdir -p $out/opt/amdgpu{,-pro}
    cp -r opt/amdgpu-pro/lib/${libArch} $out/opt/amdgpu-pro/lib
    cp -r opt/amdgpu/lib/${libArch} $out/opt/amdgpu/lib

    pushd $out/lib
    ln -s ../opt/amdgpu-pro/lib/libGL.so* .
    ln -s ../opt/amdgpu-pro/lib/libEGL.so* .
    popd

    # short name to allow replacement below
    ln -s lib/dri $out/dri

  '' + optionalString (stdenv.is64bit) ''
    mkdir -p $out/etc
    pushd etc
    cp -r modprobe.d udev amd $out/etc
    popd

    cp -r lib/udev/rules.d/* $out/etc/udev/rules.d
    cp -r opt/amdgpu/lib/xorg $out/lib/xorg
    cp -r opt/amdgpu-pro/lib/xorg/* $out/lib/xorg
    cp -r opt/amdgpu/share $out/opt/amdgpu/share
  '' + ''

    mkdir -p $vulkan/share/vulkan/icd.d
    install opt/amdgpu-pro/etc/vulkan/icd.d/amd_icd${bitness}.json $vulkan/share/vulkan/icd.d

    runHook postInstall
  '';

  preFixup = (if stdenv.is64bit
    # this could also be done with LIBGL_DRIVERS_PATH, but it would need to be
    # set in the user session and for Xorg
    then ''
      expr1='s:/opt/amdgpu/lib/x86_64-linux-gnu/dri\0:/run/opengl-driver/lib/dri\0\0\0\0\0\0\0\0\0\0\0:g'
      expr2='s:/usr/lib/x86_64-linux-gnu/dri[\0\:]:/run/opengl-driver/lib/dri\0\0\0\0:g'
      perl -pi -e "$expr2" $out/lib/xorg/modules/extensions/libglx.so
    ''
    else ''
      expr1='s:/opt/amdgpu/lib/i386-linux-gnu/dri\0:/run/opengl-driver-32/lib/dri\0\0\0\0\0\0:g'
      # we replace a different path on 32-bit because it's the only one long
      # enough to fit the target path :(
      expr2='s:/usr/lib/i386-linux-gnu/dri[\0\:]:/run/opengl-driver-32/dri\0\0\0:g'
    '') + ''
    perl -pi -e "$expr1" \
      $out/opt/amdgpu/lib/libEGL.so.1.0.0 \
      $out/opt/amdgpu/lib/libgbm.so.1.0.0 \
      $out/opt/amdgpu/lib/libGL.so.1.2.0

    perl -pi -e "$expr2" \
      $out/opt/amdgpu-pro/lib/libEGL.so.1 \
      $out/opt/amdgpu-pro/lib/libGL.so.1.2 \
      $out/opt/amdgpu-pro/lib/libGLX_amd.so.0

    find $out -type f -exec perl -pi -e 's:/opt/amdgpu-pro/:/run/amdgpu-pro/:g' {} \;
    find $out -type f -exec perl -pi -e 's:/opt/amdgpu/:/run/amdgpu/:g' {} \;

    substituteInPlace $vulkan/share/vulkan/icd.d/*.json --replace /opt/amdgpu-pro/lib/${libArch} "$out/opt/amdgpu-pro/lib"
  '';

  # doing this in post because shrinking breaks things that dynamically load
  postFixup = ''
    libPath="$out/opt/amdgpu/lib:$out/opt/amdgpu-pro/lib:$depLibPath"
    find "$out" -name '*.so*' -type f -exec patchelf --set-rpath "$libPath" {} \;
  '';

  buildInputs = [
    libdrm
    patchelf
    perl
  ];

  enableParallelBuilding = true;

  meta = with lib; {
    description = "AMDGPU-PRO drivers";
    homepage =  "https://www.amd.com/en/support";
    license = licenses.unfree;
    platforms = platforms.linux;
    maintainers = with maintainers; [ corngood ];
  };
}