Commit 78f6ee7b authored by ccicnce113424's avatar ccicnce113424
Browse files

nixos/nvidia: utilize ICD libraries built from source

This changes the NVIDIA NixOS module to use ICD libraries built from
source rather than relying on the pre-compiled bundled versions.

Additionally, this adds a necessary workaround for driver versions
below 595 to ensure proper compatibility.

For more context on the workaround, see the discussion at:
https://github.com/NixOS/nixpkgs/pull/497342#issuecomment-4034876793
parent d8f2a8e0
Loading
Loading
Loading
Loading
+46 −4
Original line number Diff line number Diff line
@@ -401,9 +401,51 @@ in
            KERNEL=="nvidia_uvm", RUN+="${pkgs.runtimeShell} -c 'mknod -m 666 /dev/nvidia-uvm c $$(grep nvidia-uvm /proc/devices | cut -d \  -f 1) 0'"
            KERNEL=="nvidia_uvm", RUN+="${pkgs.runtimeShell} -c 'mknod -m 666 /dev/nvidia-uvm-tools c $$(grep nvidia-uvm /proc/devices | cut -d \  -f 1) 1'"
          '';
          hardware.graphics = {
            extraPackages = [ nvidia_x11.out ];
            extraPackages32 = [ nvidia_x11.lib32 ];
          hardware.graphics =
            let
              icd = [
                "egl-wayland"
              ]
              # GBM support was added in 495.
              ++ lib.optionals (lib.versionAtLeast nvidia_x11.version "495") [
                "egl-gbm"
              ]
              # ICDs below use a new driver interface, which is added in the 560 series drivers.
              ++ lib.optionals (lib.versionAtLeast nvidia_x11.version "560") [
                "egl-wayland2"
                "egl-x11"
              ];
              combineIcdPkgs =
                icd: pkgs:
                pkgs.symlinkJoin {
                  name = "nvidia-egl-external-platforms${lib.optionalString pkgs.stdenv.is32bit "-x32"}";
                  paths = lib.attrVals icd pkgs;
                  # Remediate reversed priorities in pre-595 drivers,
                  # https://github.com/NixOS/nixpkgs/pull/497342#issuecomment-4034876793
                  postBuild = lib.optionalString (lib.versionOlder nvidia_x11.version "595") ''
                    pushd $out/share/egl/egl_external_platform.d
                    for f in [0-9][0-9]_*; do
                      num=''${f:0:2}
                      rest=''${f:2}
                      new=$(printf "%02d" $((99 - 10#$num)))
                      mv -- "$f" "tmp-$new$rest"
                    done
                    for f in tmp-*; do
                      mv -- "$f" "''${f#tmp-}"
                    done
                    popd
                  '';
                };
            in
            {
              extraPackages = [
                nvidia_x11.out
                (combineIcdPkgs icd pkgs)
              ];
              extraPackages32 = [
                nvidia_x11.lib32
                (combineIcdPkgs icd pkgs.pkgsi686Linux)
              ];
            };
          environment.systemPackages = [ nvidia_x11.bin ];
        }
+7 −15
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ installPhase() {
        rm -f $i/lib/lib{glx,nvidia-wfb}.so.* # handled separately
        rm -f $i/lib/libnvidia-gtk* # built from source
        rm -f $i/lib/libnvidia-wayland-client* # built from source
        rm -f $i/lib/libnvidia-egl-* # built from source
        if [ "$useGLVND" = "1" ]; then
            # Pre-built libglvnd
            rm $i/lib/lib{GL,GLX,EGL,GLESv1_CM,GLESv2,OpenGL,GLdispatch}.so.*
@@ -79,13 +80,7 @@ installPhase() {
            else
                sed -E "s#(libGLX_nvidia)#$i/lib/\\1#" nvidia_icd.json > nvidia_icd.json.fixed
            fi

            # nvidia currently only supports x86_64 and i686
            if [ "$i" == "$lib32" ]; then
                install -Dm644 nvidia_icd.json.fixed $i/share/vulkan/icd.d/nvidia_icd.i686.json
            else
                install -Dm644 nvidia_icd.json.fixed $i/share/vulkan/icd.d/nvidia_icd.x86_64.json
            fi
            install -Dm644 nvidia_icd.json.fixed $i/share/vulkan/icd.d/nvidia_icd.json
        fi

        if [ -e nvidia_layers.json ]; then
@@ -95,17 +90,14 @@ installPhase() {

        # EGL
        if [ "$useGLVND" = "1" ]; then
            mkdir -p "$i/share/egl/egl_external_platform.d"
            for icdname in $(find . -name '*_nvidia*.json')
            do
                cat "$icdname" | jq ".ICD.library_path |= \"$i/lib/\(.)\"" | tee "$i/share/egl/egl_external_platform.d/$icdname"
            done

            # glvnd icd
            mkdir -p "$i/share/glvnd/egl_vendor.d"
            mv "$i/share/egl/egl_external_platform.d/10_nvidia.json" "$i/share/glvnd/egl_vendor.d/10_nvidia.json"
            for icdname in "10_nvidia.json";
            do
                cat "$icdname" | jq ".ICD.library_path |= \"$i/lib/\(.)\"" | tee "$i/share/glvnd/egl_vendor.d/$icdname"
            done

            if [[ -f "$i/share/egl/egl_external_platform.d/15_nvidia_gbm.json" ]]; then
            if [[ -f "15_nvidia_gbm.json" ]]; then
              mkdir -p $i/lib/gbm
              ln -s $i/lib/libnvidia-allocator.so $i/lib/gbm/nvidia-drm_gbm.so
            fi