1{
2 lib,
3 bison,
4 buildPackages,
5 directx-headers,
6 elfutils,
7 expat,
8 fetchCrate,
9 fetchFromGitLab,
10 file,
11 flex,
12 glslang,
13 spirv-tools,
14 intltool,
15 jdupes,
16 libdrm,
17 libgbm,
18 libglvnd,
19 libpng,
20 libunwind,
21 libva-minimal,
22 libvdpau,
23 llvmPackages,
24 lm_sensors,
25 meson,
26 ninja,
27 pkg-config,
28 python3Packages,
29 rust-bindgen,
30 rust-cbindgen,
31 rustPlatform,
32 rustc,
33 spirv-llvm-translator,
34 stdenv,
35 udev,
36 valgrind-light,
37 vulkan-loader,
38 wayland,
39 wayland-protocols,
40 wayland-scanner,
41 xcbutilkeysyms,
42 xorg,
43 zstd,
44 enablePatentEncumberedCodecs ? true,
45 withValgrind ? lib.meta.availableOn stdenv.hostPlatform valgrind-light,
46
47 galliumDrivers ?
48 [
49 "asahi" # Apple AGX, built on non-aarch64 for cross tools
50 "d3d12" # WSL emulated GPU (aka Dozen)
51 "iris" # new Intel (Broadwell+)
52 "llvmpipe" # software renderer
53 "nouveau" # Nvidia
54 "panfrost" # ARM Mali Midgard and up (T/G series), built on non-ARM for cross tools
55 "r300" # very old AMD
56 "r600" # less old AMD
57 "radeonsi" # new AMD (GCN+)
58 "softpipe" # older software renderer
59 "svga" # VMWare virtualized GPU
60 "virgl" # QEMU virtualized GPU (aka VirGL)
61 "zink" # generic OpenGL over Vulkan, experimental
62 ]
63 ++ lib.optionals (stdenv.hostPlatform.isAarch64 || stdenv.hostPlatform.isAarch32) [
64 "etnaviv" # Vivante GPU designs (mostly NXP/Marvell SoCs)
65 "freedreno" # Qualcomm Adreno (all Qualcomm SoCs)
66 "lima" # ARM Mali 4xx
67 "vc4" # Broadcom VC4 (Raspberry Pi 0-3)
68 ]
69 ++ lib.optionals stdenv.hostPlatform.isAarch64 [
70 "tegra" # Nvidia Tegra SoCs
71 "v3d" # Broadcom VC5 (Raspberry Pi 4)
72 ]
73 ++ lib.optionals stdenv.hostPlatform.isx86 [
74 "crocus" # Intel legacy, x86 only
75 "i915" # Intel extra legacy, x86 only
76 ],
77 vulkanDrivers ?
78 [
79 "amd" # AMD (aka RADV)
80 "asahi" # Apple AGX, built on non-aarch64 for cross tools
81 "intel" # new Intel (aka ANV)
82 "microsoft-experimental" # WSL virtualized GPU (aka DZN/Dozen)
83 "nouveau" # Nouveau (aka NVK)
84 "swrast" # software renderer (aka Lavapipe)
85 ]
86 ++
87 lib.optionals
88 (stdenv.hostPlatform.isAarch -> lib.versionAtLeast stdenv.hostPlatform.parsed.cpu.version "6")
89 [
90 # QEMU virtualized GPU (aka VirGL)
91 # Requires ATOMIC_INT_LOCK_FREE == 2.
92 "virtio"
93 ]
94 ++ lib.optionals stdenv.hostPlatform.isAarch64 [
95 "broadcom" # Broadcom VC5 (Raspberry Pi 4, aka V3D)
96 "freedreno" # Qualcomm Adreno (all Qualcomm SoCs)
97 "imagination-experimental" # PowerVR Rogue (currently N/A)
98 "panfrost" # ARM Mali Midgard and up (T/G series)
99 ]
100 ++ lib.optionals stdenv.hostPlatform.isx86 [
101 "intel_hasvk" # Intel Haswell/Broadwell, "legacy" Vulkan driver (https://www.phoronix.com/news/Intel-HasVK-Drop-Dead-Code)
102 ],
103 eglPlatforms ? [
104 "x11"
105 "wayland"
106 ],
107 vulkanLayers ? [
108 "device-select"
109 "intel-nullhw"
110 "overlay"
111 "screenshot"
112 "vram-report-limit"
113 ],
114 mesa,
115 mesa-gl-headers,
116 makeSetupHook,
117}:
118
119let
120 rustDeps = [
121 {
122 pname = "paste";
123 version = "1.0.14";
124 hash = "sha256-+J1h7New5MEclUBvwDQtTYJCHKKqAEOeQkuKy+g0vEc=";
125 }
126 {
127 pname = "proc-macro2";
128 version = "1.0.86";
129 hash = "sha256-9fYAlWRGVIwPp8OKX7Id84Kjt8OoN2cANJ/D9ZOUUZE=";
130 }
131 {
132 pname = "quote";
133 version = "1.0.33";
134 hash = "sha256-VWRCZJO0/DJbNu0/V9TLaqlwMot65YjInWT9VWg57DY=";
135 }
136 {
137 pname = "syn";
138 version = "2.0.68";
139 hash = "sha256-nGLBbxR0DFBpsXMngXdegTm/o13FBS6QsM7TwxHXbgQ=";
140 }
141 {
142 pname = "unicode-ident";
143 version = "1.0.12";
144 hash = "sha256-KX8NqYYw6+rGsoR9mdZx8eT1HIPEUUyxErdk2H/Rlj8=";
145 }
146 ];
147
148 copyRustDep = dep: ''
149 cp -R --no-preserve=mode,ownership ${fetchCrate dep} subprojects/${dep.pname}-${dep.version}
150 cp -R subprojects/packagefiles/${dep.pname}/* subprojects/${dep.pname}-${dep.version}/
151 '';
152
153 copyRustDeps = lib.concatStringsSep "\n" (builtins.map copyRustDep rustDeps);
154
155 needNativeCLC = !stdenv.buildPlatform.canExecute stdenv.hostPlatform;
156
157 common = import ./common.nix { inherit lib fetchFromGitLab; };
158in
159stdenv.mkDerivation {
160 inherit (common)
161 pname
162 version
163 src
164 meta
165 ;
166
167 patches = [
168 ./opencl.patch
169 ];
170
171 postPatch = ''
172 patchShebangs .
173
174 for header in ${toString mesa-gl-headers.headers}; do
175 if ! diff -q $header ${mesa-gl-headers}/$header; then
176 echo "File $header does not match between mesa and mesa-gl-headers, please update mesa-gl-headers first!"
177 exit 42
178 fi
179 done
180
181 ${copyRustDeps}
182 '';
183
184 outputs =
185 [
186 "out"
187 # OpenCL drivers pull in ~1G of extra LLVM stuff, so don't install them
188 # if the user didn't explicitly ask for it
189 "opencl"
190 # the Dozen drivers depend on libspirv2dxil, but link it statically, and
191 # libspirv2dxil itself is pretty chonky, so relocate it to its own output in
192 # case anything wants to use it at some point
193 "spirv2dxil"
194 ]
195 ++ lib.optionals (!needNativeCLC) [
196 # tools for the host platform to be used when cross-compiling.
197 # mesa builds these only when not already built. hence:
198 # - for a non-cross build (needNativeCLC = false), we do not provide mesa
199 # with any `*-clc` binaries, so it builds them and installs them.
200 # - for a cross build (needNativeCLC = true), we provide mesa with `*-clc`
201 # binaries, so it skips building & installing any new CLC files.
202 "cross_tools"
203 ];
204
205 # Keep build-ids so drivers can use them for caching, etc.
206 # Also some drivers segfault without this.
207 separateDebugInfo = true;
208
209 # Needed to discover llvm-config for cross
210 preConfigure = ''
211 PATH=${lib.getDev llvmPackages.libllvm}/bin:$PATH
212 '';
213
214 mesonFlags =
215 [
216 "--sysconfdir=/etc"
217
218 # What to build
219 (lib.mesonOption "platforms" (lib.concatStringsSep "," eglPlatforms))
220 (lib.mesonOption "gallium-drivers" (lib.concatStringsSep "," galliumDrivers))
221 (lib.mesonOption "vulkan-drivers" (lib.concatStringsSep "," vulkanDrivers))
222 (lib.mesonOption "vulkan-layers" (lib.concatStringsSep "," vulkanLayers))
223
224 # Enable glvnd for dynamic libGL dispatch
225 (lib.mesonEnable "glvnd" true)
226 (lib.mesonEnable "gbm" true)
227 (lib.mesonBool "libgbm-external" true)
228
229 (lib.mesonBool "gallium-nine" false) # Direct3D9 in Wine, largely supplanted by DXVK
230
231 # Only used by xf86-video-vmware, which has more features than VMWare's KMS driver,
232 # so we're keeping it for now. Should be removed when that's no longer the case.
233 # See: https://github.com/NixOS/nixpkgs/pull/392492
234 (lib.mesonEnable "gallium-xa" true)
235
236 (lib.mesonBool "teflon" true) # TensorFlow frontend
237
238 # Enable all freedreno kernel mode drivers. (For example, virtio can be
239 # used with a virtio-gpu device supporting drm native context.) This option
240 # is ignored when freedreno is not being built.
241 (lib.mesonOption "freedreno-kmds" "msm,kgsl,virtio,wsl")
242
243 # Enable Intel RT stuff when available
244 (lib.mesonEnable "intel-rt" stdenv.hostPlatform.isx86_64)
245
246 # Required for OpenCL
247 (lib.mesonOption "clang-libdir" "${lib.getLib llvmPackages.clang-unwrapped}/lib")
248
249 # Rusticl, new OpenCL frontend
250 (lib.mesonBool "gallium-rusticl" true)
251 (lib.mesonOption "gallium-rusticl-enable-drivers" "auto")
252
253 # meson auto_features enables this, but we do not want it
254 (lib.mesonEnable "android-libbacktrace" false)
255 (lib.mesonEnable "microsoft-clc" false) # Only relevant on Windows (OpenCL 1.2 API on top of D3D12)
256
257 # Enable more sensors in gallium-hud
258 (lib.mesonBool "gallium-extra-hud" true)
259
260 # Disable valgrind on targets where it's not available
261 (lib.mesonEnable "valgrind" withValgrind)
262 ]
263 ++ lib.optionals enablePatentEncumberedCodecs [
264 (lib.mesonOption "video-codecs" "all")
265 ]
266 ++ lib.optionals (!needNativeCLC) [
267 # Build and install extra tools for cross
268 (lib.mesonOption "tools" "asahi,panfrost")
269 (lib.mesonBool "install-mesa-clc" true)
270 (lib.mesonBool "install-precomp-compiler" true)
271 ]
272 ++ lib.optionals needNativeCLC [
273 (lib.mesonOption "mesa-clc" "system")
274 (lib.mesonOption "precomp-compiler" "system")
275 ];
276
277 strictDeps = true;
278
279 buildInputs =
280 with xorg;
281 [
282 directx-headers
283 elfutils
284 expat
285 spirv-tools
286 libdrm
287 libgbm
288 libglvnd
289 libpng
290 libunwind
291 libva-minimal
292 libvdpau
293 libX11
294 libxcb
295 libXext
296 libXfixes
297 libXrandr
298 libxshmfence
299 libXxf86vm
300 llvmPackages.clang
301 llvmPackages.clang-unwrapped
302 llvmPackages.libclc
303 llvmPackages.libllvm
304 lm_sensors
305 python3Packages.python # for shebang
306 spirv-llvm-translator
307 udev
308 vulkan-loader
309 wayland
310 wayland-protocols
311 xcbutilkeysyms
312 xorgproto
313 zstd
314 ]
315 ++ lib.optionals withValgrind [
316 valgrind-light
317 ];
318
319 depsBuildBuild = [
320 pkg-config
321 buildPackages.stdenv.cc
322 ];
323
324 nativeBuildInputs =
325 [
326 meson
327 pkg-config
328 ninja
329 intltool
330 bison
331 flex
332 file
333 python3Packages.python
334 python3Packages.packaging
335 python3Packages.pycparser
336 python3Packages.mako
337 python3Packages.ply
338 python3Packages.pyyaml
339 jdupes
340 # Use bin output from glslang to not propagate the dev output at
341 # the build time with the host glslang.
342 (lib.getBin glslang)
343 rustc
344 rust-bindgen
345 rust-cbindgen
346 rustPlatform.bindgenHook
347 wayland-scanner
348 ]
349 ++ lib.optionals needNativeCLC [
350 # `or null` to not break eval with `attribute missing` on darwin to linux cross
351 (buildPackages.mesa.cross_tools or null)
352 ];
353
354 disallowedRequisites = lib.optionals needNativeCLC [
355 (buildPackages.mesa.cross_tools or null)
356 ];
357
358 doCheck = false;
359
360 postInstall = ''
361 moveToOutput bin/asahi_clc $cross_tools
362 moveToOutput bin/intel_clc $cross_tools
363 moveToOutput bin/mesa_clc $cross_tools
364 moveToOutput bin/panfrost_compile $cross_tools
365 moveToOutput bin/panfrost_texfeatures $cross_tools
366 moveToOutput bin/panfrostdump $cross_tools
367 moveToOutput bin/vtn_bindgen2 $cross_tools
368
369 moveToOutput "lib/lib*OpenCL*" $opencl
370 # Construct our own .icd file that contains an absolute path.
371 mkdir -p $opencl/etc/OpenCL/vendors/
372 echo $opencl/lib/libRusticlOpenCL.so > $opencl/etc/OpenCL/vendors/rusticl.icd
373
374 moveToOutput bin/spirv2dxil $spirv2dxil
375 moveToOutput "lib/libspirv_to_dxil*" $spirv2dxil
376 '';
377
378 postFixup = ''
379 # set full path in EGL driver manifest
380 for js in $out/share/glvnd/egl_vendor.d/*.json; do
381 substituteInPlace "$js" --replace-fail '"libEGL_' '"'"$out/lib/libEGL_"
382 done
383
384 # and in Vulkan layer manifests
385 for js in $out/share/vulkan/{im,ex}plicit_layer.d/*.json; do
386 substituteInPlace "$js" --replace '"libVkLayer_' '"'"$out/lib/libVkLayer_"
387 done
388
389 # remove DRI pkg-config file, provided by dri-pkgconfig-stub
390 rm -f $out/lib/pkgconfig/dri.pc
391
392 # remove headers moved to mesa-gl-headers
393 for header in ${toString mesa-gl-headers.headers}; do
394 rm -f $out/$header
395 done
396
397 # clean up after removing stuff
398 find $out -type d -empty -delete
399
400 # Don't depend on build python
401 patchShebangs --host --update $out/bin/*
402
403 # NAR doesn't support hard links, so convert them to symlinks to save space.
404 jdupes --hard-links --link-soft --recurse "$out"
405
406 # add RPATH here so Zink can find libvulkan.so
407 patchelf --add-rpath ${vulkan-loader}/lib $out/lib/libgallium*.so
408 '';
409
410 passthru = {
411 inherit (libglvnd) driverLink;
412 inherit llvmPackages;
413 inherit
414 eglPlatforms
415 galliumDrivers
416 vulkanDrivers
417 vulkanLayers
418 ;
419
420 # for compatibility
421 drivers = lib.warn "`mesa.drivers` is deprecated, use `mesa` instead" mesa;
422
423 tests.outDoesNotDependOnLLVM = stdenv.mkDerivation {
424 name = "mesa-does-not-depend-on-llvm";
425 buildCommand = ''
426 echo ${mesa} >>$out
427 '';
428 disallowedRequisites = [ llvmPackages.llvm ];
429 };
430
431 llvmpipeHook = makeSetupHook {
432 name = "llvmpipe-hook";
433 substitutions.mesa = mesa;
434 } ./llvmpipe-hook.sh;
435 };
436}