forked from godotengine/godot
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathnixGL.nix
204 lines (184 loc) · 6.79 KB
/
nixGL.nix
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
{ ## Nvidia informations.
# Version of the system kernel module. Let it to null to enable auto-detection.
nvidiaVersion ? null,
# Hash of the Nvidia driver .run file. null is fine, but fixing a value here
# will be more reproducible and more efficient.
nvidiaHash ? null,
# Alternatively, you can pass a path that points to a nvidia version file
# 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 ).
nvidiaVersionFile ? null,
# Enable 32 bits driver
# This is one by default, you can switch it to off if you want to reduce a
# bit the size of nixGL closure.
enable32bits ? false,
writeTextFile, shellcheck, pcre, runCommand, linuxPackages, fetchurl, lib,
runtimeShell, bumblebee, libglvnd, vulkan-validation-layers, mesa_drivers,
pkgsi686Linux,zlib, libdrm, xorg, wayland, gcc
}:
let
_nvidiaVersionFile =
if nvidiaVersionFile != null then
nvidiaVersionFile
else
# 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.
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 || touch $out";
# The nvidia version. Either fixed by the `nvidiaVersion` argument, or
# auto-detected. Auto-detection is impure.
_nvidiaVersion =
if nvidiaVersion != null then
nvidiaVersion
else
# Get if from the nvidiaVersionFile
let
data = builtins.readFile _nvidiaVersionFile;
versionMatch = builtins.match ".*Module +([0-9]+(\\.[0-9]+)+).*" data;
in
if versionMatch != null then
builtins.head versionMatch
else
null;
addNvidiaVersion = drv: drv.overrideAttrs(oldAttrs: {
name = oldAttrs.name + "-${_nvidiaVersion}";
});
writeExecutable = { name, text } : 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
'';
};
in
rec {
nvidia = (linuxPackages.nvidia_x11.override {
}).overrideAttrs(oldAttrs: rec {
name = "nvidia-${_nvidiaVersion}";
src = let url ="http://download.nvidia.com/XFree86/Linux-x86_64/${_nvidiaVersion}/NVIDIA-Linux-x86_64-${_nvidiaVersion}.run";
in if nvidiaHash != null
then fetchurl {
inherit url;
sha256 = nvidiaHash;
} else
builtins.fetchurl url;
useGLVND = true;
});
nvidiaLibsOnly = nvidia.override {
libsOnly = true;
kernel = null;
};
getFirstFile = path: path + builtins.head (builtins.attrNames (builtins.readDir path));
json = getFirstFile "${nvidiaLibsOnly}/share/vulkan/icd.d/";
json32 = getFirstFile "${nvidiaLibsOnly.lib32}/share/vulkan/icd.d/";
nixGLNvidiaBumblebee = addNvidiaVersion (writeExecutable {
name = "nixGLNvidiaBumblebee";
text = ''
#!${runtimeShell}
export LD_LIBRARY_PATH=${lib.makeLibraryPath [nvidia]}:$LD_LIBRARY_PATH
${bumblebee.override {nvidia_x11 = nvidia; nvidia_x11_i686 = nvidia.lib32;}}/bin/optirun --ldpath ${lib.makeLibraryPath ([libglvnd nvidia] ++ lib.optionals enable32bits [nvidia.lib32 pkgsi686Linux.libglvnd])} "$@"
'';
});
# TODO: 32bit version? Not tested.
nixNvidiaWrapper = api: addNvidiaVersion (writeExecutable {
name = "nix${api}Nvidia";
text = ''
#!${runtimeShell}
${lib.optionalString (api == "Vulkan") ''export VK_LAYER_PATH=${vulkan-validation-layers}/share/vulkan/explicit_layer.d''}
${lib.optionalString (api == "Vulkan") ''export VK_ICD_FILENAMES=${json}${lib.optionalString enable32bits ":${json32}"}:$VK_ICD_FILENAMES''}
export LD_LIBRARY_PATH=${lib.makeLibraryPath ([
libglvnd
nvidiaLibsOnly
] ++ lib.optional (api == "Vulkan") vulkan-validation-layers
++ lib.optionals enable32bits [nvidiaLibsOnly.lib32 pkgsi686Linux.libglvnd])
}:''${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}
"$@"
'';
});
# TODO: 32bit version? Not tested.
nixGLNvidia = nixNvidiaWrapper "GL";
# TODO: 32bit version? Not tested.
nixVulkanNvidia = nixNvidiaWrapper "Vulkan";
nixGLIntel = writeExecutable {
name = "nixGLIntel";
# add the 32 bits drivers if needed
text = let
drivers = [mesa_drivers] ++ lib.optional enable32bits pkgsi686Linux.mesa_drivers;
in ''
#!${runtimeShell}
export LIBGL_DRIVERS_PATH=${lib.makeSearchPathOutput "lib" "lib/dri" drivers}
export LD_LIBRARY_PATH=${
lib.makeLibraryPath drivers
}:$LD_LIBRARY_PATH
"$@"
'';
};
nixVulkanIntel = writeExecutable {
name = "nixVulkanIntel";
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
export LD_LIBRARY_PATH=${lib.makeLibraryPath [
zlib
libdrm
xorg.libX11
xorg.libxcb
xorg.libxshmfence
wayland
gcc.cc
]}:$LD_LIBRARY_PATH
exec "$@"
'';
};
nixGLCommon = nixGL:
runCommand "nixGLCommon" {
buildInuts = [nixGL];
}
''
mkdir -p "$out/bin"
# star because nixGLNvidia... have version prefixed name
cp ${nixGL}/bin/* "$out/bin/nixGL";
'';
# The output derivation contains nixGL which point either to
# nixGLNvidia or nixGLIntel using an heuristic.
nixGLDefault =
if _nvidiaVersion != null then
nixGLCommon nixGLNvidia
else
nixGLCommon nixGLIntel
;
}