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