2023-01-12 20:01:11 +00:00
|
|
|
{
|
|
|
|
# # Nvidia informations.
|
|
|
|
# Version of the system kernel module. Let it to null to enable auto-detection.
|
2023-06-18 00:46:31 +00:00
|
|
|
nvidiaVersion ? null,
|
|
|
|
# Hash of the Nvidia driver .run file. null is fine, but fixing a value here
|
2023-01-12 20:01:11 +00:00
|
|
|
# will be more reproducible and more efficient.
|
2023-06-18 00:46:31 +00:00
|
|
|
nvidiaHash ? null,
|
|
|
|
# Alternatively, you can pass a path that points to a nvidia version file
|
2023-01-12 20:01:11 +00:00
|
|
|
# and let nixGL extract the version from it. That file must be a copy of
|
|
|
|
# /proc/driver/nvidia/version. Nix doesn't like zero-sized files (see
|
|
|
|
# https://github.com/NixOS/nix/issues/3539 ).
|
2023-06-18 00:46:31 +00:00
|
|
|
nvidiaVersionFile ? null,
|
|
|
|
# Enable 32 bits driver
|
2023-01-12 20:01:11 +00:00
|
|
|
# This is one by default, you can switch it to off if you want to reduce a
|
|
|
|
# bit the size of nixGL closure.
|
2023-06-18 00:46:31 +00:00
|
|
|
enable32bits ? true,
|
|
|
|
writeTextFile,
|
|
|
|
shellcheck,
|
|
|
|
pcre,
|
|
|
|
runCommand,
|
|
|
|
linuxPackages,
|
|
|
|
fetchurl,
|
|
|
|
lib,
|
|
|
|
runtimeShell,
|
|
|
|
bumblebee,
|
|
|
|
libglvnd,
|
|
|
|
vulkan-validation-layers,
|
|
|
|
mesa,
|
|
|
|
libvdpau-va-gl,
|
|
|
|
intel-media-driver,
|
|
|
|
vaapiIntel,
|
|
|
|
pkgsi686Linux,
|
|
|
|
driversi686Linux,
|
|
|
|
zlib,
|
|
|
|
libdrm,
|
|
|
|
xorg,
|
|
|
|
wayland,
|
|
|
|
gcc,
|
|
|
|
}: let
|
|
|
|
writeExecutable = {
|
|
|
|
name,
|
|
|
|
text,
|
|
|
|
}:
|
2022-12-30 08:45:15 +00:00
|
|
|
writeTextFile {
|
|
|
|
inherit name text;
|
|
|
|
|
|
|
|
executable = true;
|
|
|
|
destination = "/bin/${name}";
|
|
|
|
|
|
|
|
checkPhase = ''
|
|
|
|
${shellcheck}/bin/shellcheck "$out/bin/${name}"
|
|
|
|
|
|
|
|
# Check that all the files listed in the output binary exists
|
|
|
|
for i in $(${pcre}/bin/pcregrep -o0 '/nix/store/.*?/[^ ":]+' $out/bin/${name})
|
|
|
|
do
|
|
|
|
ls $i > /dev/null || (echo "File $i, referenced in $out/bin/${name} does not exists."; exit -1)
|
|
|
|
done
|
|
|
|
'';
|
|
|
|
};
|
2023-01-13 00:22:56 +00:00
|
|
|
fetch_db = builtins.fromJSON (builtins.readFile ./nvidia_versions.json);
|
2022-12-30 08:45:15 +00:00
|
|
|
top = rec {
|
|
|
|
/*
|
2023-06-18 00:46:31 +00:00
|
|
|
It contains the builder for different nvidia configuration, parametrized by
|
|
|
|
the version of the driver and sha256 sum of the driver installer file.
|
2022-12-30 08:45:15 +00:00
|
|
|
*/
|
2023-06-18 00:46:31 +00:00
|
|
|
nvidiaPackages = {
|
|
|
|
version,
|
|
|
|
sha256 ? fetch_db."${version}".sha256,
|
|
|
|
}: let
|
|
|
|
nvidiaDrivers =
|
|
|
|
(linuxPackages.nvidia_x11.override {}).overrideAttrs
|
|
|
|
(oldAttrs: {
|
|
|
|
pname = "nvidia";
|
|
|
|
name = "nvidia-x11-${version}-nixGL";
|
|
|
|
inherit version;
|
|
|
|
src = let
|
|
|
|
url = "https://download.nvidia.com/XFree86/Linux-x86_64/${version}/NVIDIA-Linux-x86_64-${version}.run";
|
|
|
|
in
|
|
|
|
fetchurl {inherit url sha256;};
|
|
|
|
useGLVND = true;
|
|
|
|
});
|
|
|
|
nvidiaLibsOnly = nvidiaDrivers.override {
|
|
|
|
libsOnly = true;
|
|
|
|
kernel = null;
|
|
|
|
};
|
|
|
|
nixNvidiaWrapper = api:
|
|
|
|
writeExecutable {
|
|
|
|
name = "nix${api}Nvidia-${version}";
|
|
|
|
text = ''
|
|
|
|
#!${runtimeShell}
|
|
|
|
${lib.optionalString (api == "Vulkan")
|
2023-01-12 20:01:11 +00:00
|
|
|
"export VK_LAYER_PATH=${vulkan-validation-layers}/share/vulkan/explicit_layer.d"}
|
2023-06-18 00:46:31 +00:00
|
|
|
NVIDIA_JSON=(${nvidiaLibsOnly}/share/glvnd/egl_vendor.d/*nvidia.json)
|
|
|
|
${lib.optionalString enable32bits "NVIDIA_JSON32=(${nvidiaLibsOnly.lib32}/share/glvnd/egl_vendor.d/*nvidia.json)"}
|
2022-12-30 08:45:15 +00:00
|
|
|
|
2023-06-18 00:46:31 +00:00
|
|
|
${''export __EGL_VENDOR_LIBRARY_FILENAMES=''${NVIDIA_JSON[*]}${
|
2023-01-12 20:01:11 +00:00
|
|
|
lib.optionalString enable32bits
|
|
|
|
'':''${NVIDIA_JSON32[*]}''
|
2023-06-18 00:46:31 +00:00
|
|
|
}"''${__EGL_VENDOR_LIBRARY_FILENAMES:+:$__EGL_VENDOR_LIBRARY_FILENAMES}"''}
|
2023-01-13 00:27:32 +00:00
|
|
|
|
2023-06-18 00:46:31 +00:00
|
|
|
${
|
|
|
|
lib.optionalString (api == "Vulkan")
|
|
|
|
''export VK_ICD_FILENAMES=${nvidiaLibsOnly}/share/vulkan/icd.d/nvidia_icd.json${
|
|
|
|
lib.optionalString enable32bits
|
|
|
|
":${nvidiaLibsOnly.lib32}/share/vulkan/icd.d/nvidia_icd.json"
|
|
|
|
}"''${VK_ICD_FILENAMES:+:$VK_ICD_FILENAMES}"''
|
|
|
|
}
|
|
|
|
export LD_LIBRARY_PATH=${
|
|
|
|
lib.makeLibraryPath ([libglvnd nvidiaLibsOnly]
|
|
|
|
++ lib.optional (api == "Vulkan") vulkan-validation-layers
|
2023-01-13 00:27:32 +00:00
|
|
|
++ lib.optionals enable32bits [
|
2023-06-18 00:46:31 +00:00
|
|
|
nvidiaLibsOnly.lib32
|
2023-01-13 00:27:32 +00:00
|
|
|
pkgsi686Linux.libglvnd
|
|
|
|
])
|
2023-06-18 00:46:31 +00:00
|
|
|
}"''${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
|
|
|
|
exec "$@"
|
2023-01-13 00:27:32 +00:00
|
|
|
'';
|
|
|
|
};
|
2023-06-18 00:46:31 +00:00
|
|
|
in {
|
|
|
|
inherit nvidiaDrivers nvidiaLibsOnly;
|
2023-01-13 00:27:32 +00:00
|
|
|
|
2023-06-18 00:46:31 +00:00
|
|
|
nixGLNvidiaBumblebee = writeExecutable {
|
|
|
|
name = "nixGLNvidiaBumblebee-${version}";
|
|
|
|
text = ''
|
|
|
|
#!${runtimeShell}
|
|
|
|
export LD_LIBRARY_PATH=${
|
|
|
|
lib.makeLibraryPath [nvidiaDrivers]
|
|
|
|
}"''${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
|
|
|
|
${
|
|
|
|
bumblebee.override {
|
|
|
|
nvidia_x11 = nvidiaDrivers;
|
|
|
|
nvidia_x11_i686 = nvidiaDrivers.lib32;
|
|
|
|
}
|
|
|
|
}/bin/optirun --ldpath ${
|
|
|
|
lib.makeLibraryPath ([libglvnd nvidiaDrivers]
|
|
|
|
++ lib.optionals enable32bits [
|
|
|
|
nvidiaDrivers.lib32
|
|
|
|
pkgsi686Linux.libglvnd
|
|
|
|
])
|
|
|
|
} "$@"
|
|
|
|
'';
|
|
|
|
};
|
2023-01-12 20:01:11 +00:00
|
|
|
|
2023-06-18 00:46:31 +00:00
|
|
|
# TODO: 32bit version? Not tested.
|
|
|
|
inherit nixNvidiaWrapper;
|
2023-01-12 20:01:11 +00:00
|
|
|
|
2023-06-18 00:46:31 +00:00
|
|
|
# TODO: 32bit version? Not tested.
|
|
|
|
nixGLNvidia = nixNvidiaWrapper "GL";
|
|
|
|
|
|
|
|
# TODO: 32bit version? Not tested.
|
|
|
|
nixVulkanNvidia = nixNvidiaWrapper "Vulkan";
|
|
|
|
};
|
2022-12-30 08:45:15 +00:00
|
|
|
|
|
|
|
nixGLIntel = writeExecutable {
|
|
|
|
name = "nixGLIntel";
|
|
|
|
# add the 32 bits drivers if needed
|
2023-06-18 00:46:31 +00:00
|
|
|
text = let
|
|
|
|
mesa-drivers =
|
|
|
|
[mesa.drivers]
|
|
|
|
++ lib.optional enable32bits pkgsi686Linux.mesa.drivers;
|
|
|
|
intel-driver =
|
|
|
|
[intel-media-driver vaapiIntel]
|
|
|
|
# Note: intel-media-driver is disabled for i686 until https://github.com/NixOS/nixpkgs/issues/140471 is fixed
|
|
|
|
++ lib.optionals enable32bits [
|
|
|
|
/*
|
|
|
|
pkgsi686Linux.intel-media-driver
|
|
|
|
*/
|
|
|
|
driversi686Linux.vaapiIntel
|
|
|
|
];
|
|
|
|
libvdpau =
|
|
|
|
[libvdpau-va-gl]
|
|
|
|
++ lib.optional enable32bits pkgsi686Linux.libvdpau-va-gl;
|
|
|
|
glxindirect = runCommand "mesa_glxindirect" {} ''
|
|
|
|
mkdir -p $out/lib
|
|
|
|
ln -s ${mesa.drivers}/lib/libGLX_mesa.so.0 $out/lib/libGLX_indirect.so.0
|
|
|
|
'';
|
|
|
|
in ''
|
|
|
|
#!${runtimeShell}
|
|
|
|
export LIBGL_DRIVERS_PATH=${lib.makeSearchPathOutput "lib" "lib/dri" mesa-drivers}
|
|
|
|
export LIBVA_DRIVERS_PATH=${lib.makeSearchPathOutput "out" "lib/dri" intel-driver}
|
|
|
|
${''export __EGL_VENDOR_LIBRARY_FILENAMES=${mesa.drivers}/share/glvnd/egl_vendor.d/50_mesa.json${
|
2023-01-12 20:01:11 +00:00
|
|
|
lib.optionalString enable32bits
|
|
|
|
":${pkgsi686Linux.mesa.drivers}/share/glvnd/egl_vendor.d/50_mesa.json"
|
2023-06-18 00:46:31 +00:00
|
|
|
}"''${__EGL_VENDOR_LIBRARY_FILENAMES:+:$__EGL_VENDOR_LIBRARY_FILENAMES}"''}
|
|
|
|
export LD_LIBRARY_PATH=${lib.makeLibraryPath mesa-drivers}:${lib.makeSearchPathOutput "lib" "lib/vdpau" libvdpau}:${glxindirect}/lib:${lib.makeLibraryPath [libglvnd]}"''${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
|
|
|
|
exec "$@"
|
|
|
|
'';
|
2022-12-30 08:45:15 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
nixVulkanIntel = writeExecutable {
|
|
|
|
name = "nixVulkanIntel";
|
2023-06-18 00:46:31 +00:00
|
|
|
text = let
|
|
|
|
# generate a file with the listing of all the icd files
|
|
|
|
icd = runCommand "mesa_icd" {} (
|
|
|
|
# 64 bits icd
|
|
|
|
''
|
|
|
|
ls ${mesa.drivers}/share/vulkan/icd.d/*.json > f
|
|
|
|
''
|
|
|
|
# 32 bits ones
|
|
|
|
+ lib.optionalString enable32bits ''
|
|
|
|
ls ${pkgsi686Linux.mesa.drivers}/share/vulkan/icd.d/*.json >> f
|
|
|
|
''
|
|
|
|
# concat everything as a one line string with ":" as seperator
|
|
|
|
+ ''cat f | xargs | sed "s/ /:/g" > $out''
|
|
|
|
);
|
|
|
|
in ''
|
|
|
|
#!${runtimeShell}
|
|
|
|
if [ -n "$LD_LIBRARY_PATH" ]; then
|
|
|
|
echo "Warning, nixVulkanIntel overwriting existing LD_LIBRARY_PATH" 1>&2
|
|
|
|
fi
|
|
|
|
export VK_LAYER_PATH=${vulkan-validation-layers}/share/vulkan/explicit_layer.d
|
|
|
|
ICDS=$(cat ${icd})
|
|
|
|
export VK_ICD_FILENAMES=$ICDS"''${VK_ICD_FILENAMES:+:$VK_ICD_FILENAMES}"
|
|
|
|
export LD_LIBRARY_PATH=${
|
|
|
|
lib.makeLibraryPath [
|
|
|
|
zlib
|
|
|
|
libdrm
|
|
|
|
xorg.libX11
|
|
|
|
xorg.libxcb
|
|
|
|
xorg.libxshmfence
|
|
|
|
wayland
|
|
|
|
gcc.cc
|
|
|
|
]
|
|
|
|
}"''${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
|
|
|
|
exec "$@"
|
|
|
|
'';
|
2022-12-30 08:45:15 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
nixGLCommon = nixGL:
|
2023-06-18 00:46:31 +00:00
|
|
|
runCommand "nixGL" {} ''
|
2022-12-30 08:45:15 +00:00
|
|
|
mkdir -p "$out/bin"
|
|
|
|
# star because nixGLNvidia... have version prefixed name
|
|
|
|
cp ${nixGL}/bin/* "$out/bin/nixGL";
|
|
|
|
'';
|
|
|
|
|
2023-06-18 00:46:31 +00:00
|
|
|
auto = let
|
|
|
|
_nvidiaVersionFile =
|
|
|
|
if nvidiaVersionFile != null
|
|
|
|
then nvidiaVersionFile
|
|
|
|
else
|
2023-01-12 20:01:11 +00:00
|
|
|
# HACK: Get the version from /proc. It turns out that /proc is mounted
|
|
|
|
# inside of the build sandbox and varies from machine to machine.
|
|
|
|
#
|
|
|
|
# builtins.readFile is not able to read /proc files. See
|
|
|
|
# https://github.com/NixOS/nix/issues/3539.
|
2023-06-18 00:46:31 +00:00
|
|
|
runCommand "impure-nvidia-version-file"
|
|
|
|
{
|
|
|
|
# To avoid sharing the build result over time or between machine,
|
|
|
|
# Add an impure parameter to force the rebuild on each access.
|
|
|
|
# time = builtins.currentTime;
|
|
|
|
preferLocalBuild = true;
|
|
|
|
allowSubstitutes = false;
|
|
|
|
} "cp /proc/driver/nvidia/version $out 2> /dev/null || touch $out";
|
2023-01-12 20:01:11 +00:00
|
|
|
|
2023-06-18 00:46:31 +00:00
|
|
|
# The nvidia version. Either fixed by the `nvidiaVersion` argument, or
|
|
|
|
# auto-detected. Auto-detection is impure.
|
|
|
|
nvidiaVersionAuto =
|
|
|
|
if nvidiaVersion != null
|
|
|
|
then nvidiaVersion
|
|
|
|
else
|
2023-01-12 20:01:11 +00:00
|
|
|
# Get if from the nvidiaVersionFile
|
2023-06-18 00:46:31 +00:00
|
|
|
let
|
|
|
|
data = builtins.readFile _nvidiaVersionFile;
|
|
|
|
versionMatch = builtins.match ".*Module ([0-9.]+) .*" data;
|
|
|
|
in
|
|
|
|
if versionMatch != null
|
|
|
|
then builtins.head versionMatch
|
|
|
|
else null;
|
2023-01-12 20:01:11 +00:00
|
|
|
|
2023-06-18 00:46:31 +00:00
|
|
|
autoNvidia = nvidiaPackages {version = nvidiaVersionAuto;};
|
|
|
|
in
|
2023-01-12 20:01:11 +00:00
|
|
|
rec {
|
|
|
|
# The output derivation contains nixGL which point either to
|
|
|
|
# nixGLNvidia or nixGLIntel using an heuristic.
|
|
|
|
nixGLDefault =
|
2023-06-18 00:46:31 +00:00
|
|
|
if nvidiaVersionAuto != null
|
|
|
|
then nixGLCommon autoNvidia.nixGLNvidia
|
|
|
|
else nixGLCommon nixGLIntel;
|
|
|
|
}
|
|
|
|
// autoNvidia;
|
2022-12-30 08:45:15 +00:00
|
|
|
};
|
2023-01-12 20:01:11 +00:00
|
|
|
in
|
2023-06-18 00:46:31 +00:00
|
|
|
top
|
|
|
|
// (
|
|
|
|
if nvidiaVersion != null
|
|
|
|
then
|
|
|
|
top.nvidiaPackages
|
|
|
|
{
|
|
|
|
version = nvidiaVersion;
|
|
|
|
sha256 = nvidiaHash;
|
|
|
|
}
|
|
|
|
else {}
|
|
|
|
)
|