lol
1{ lib
2, OpenGL
3, Xplugin
4, bison
5, buildPackages
6, directx-headers
7, elfutils
8, expat
9, fetchCrate
10, fetchpatch
11, fetchurl
12, file
13, flex
14, glslang
15, intltool
16, jdupes
17, libdrm
18, libffi
19, libglvnd
20, libomxil-bellagio
21, libunwind
22, libva-minimal
23, libvdpau
24, llvmPackages
25, lm_sensors
26, meson
27, ninja
28, openssl
29, pkg-config
30, python3Packages
31, rust-bindgen
32, rustPlatform
33, rustc
34, spirv-llvm-translator
35, stdenv
36, udev
37, valgrind-light
38, vulkan-loader
39, wayland
40, wayland-protocols
41, wayland-scanner
42, xorg
43, zstd
44, withValgrind ?
45 lib.meta.availableOn stdenv.hostPlatform valgrind-light
46 && !valgrind-light.meta.broken
47, withLibunwind ? lib.meta.availableOn stdenv.hostPlatform libunwind
48, enableGalliumNine ? stdenv.isLinux
49, enableOSMesa ? stdenv.isLinux
50, enableOpenCL ? stdenv.isLinux && stdenv.isx86_64
51, enablePatentEncumberedCodecs ? true
52
53, galliumDrivers ?
54 if stdenv.isLinux
55 then [
56 "d3d12" # WSL emulated GPU (aka Dozen)
57 "kmsro" # special "render only" driver for GPUs without a display controller
58 "nouveau" # Nvidia
59 "radeonsi" # new AMD (GCN+)
60 "r300" # very old AMD
61 "r600" # less old AMD
62 "swrast" # software renderer (aka LLVMPipe)
63 "svga" # VMWare virtualized GPU
64 "virgl" # QEMU virtualized GPU (aka VirGL)
65 "zink" # generic OpenGL over Vulkan, experimental
66 ] ++ lib.optionals (stdenv.isAarch64 || stdenv.isAarch32) [
67 "etnaviv" # Vivante GPU designs (mostly NXP/Marvell SoCs)
68 "freedreno" # Qualcomm Adreno (all Qualcomm SoCs)
69 "lima" # ARM Mali 4xx
70 "panfrost" # ARM Mali Midgard and up (T/G series)
71 "vc4" # Broadcom VC4 (Raspberry Pi 0-3)
72 ] ++ lib.optionals stdenv.isAarch64 [
73 "tegra" # Nvidia Tegra SoCs
74 "v3d" # Broadcom VC5 (Raspberry Pi 4)
75 ] ++ lib.optionals stdenv.hostPlatform.isx86 [
76 "iris" # new Intel, could work on non-x86 with PCIe cards, but doesn't build as of 22.3.4
77 "crocus" # Intel legacy, x86 only
78 "i915" # Intel extra legacy, x86 only
79 ]
80 else [ "auto" ]
81, vulkanDrivers ?
82 if stdenv.isLinux
83 then [
84 "amd" # AMD (aka RADV)
85 "microsoft-experimental" # WSL virtualized GPU (aka DZN/Dozen)
86 "nouveau-experimental" # Nouveau (aka NVK)
87 "swrast" # software renderer (aka Lavapipe)
88 ] ++ lib.optionals (stdenv.hostPlatform.isAarch -> lib.versionAtLeast stdenv.hostPlatform.parsed.cpu.version "6") [
89 # QEMU virtualized GPU (aka VirGL)
90 # Requires ATOMIC_INT_LOCK_FREE == 2.
91 "virtio"
92 ] ++ lib.optionals stdenv.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 ] ++ lib.optionals stdenv.hostPlatform.isx86 [
98 "intel" # Intel (aka ANV), could work on non-x86 with PCIe cards, but doesn't build
99 "intel_hasvk" # Intel Haswell/Broadwell, "legacy" Vulkan driver (https://www.phoronix.com/news/Intel-HasVK-Drop-Dead-Code)
100 ]
101 else [ "auto" ]
102, eglPlatforms ? [ "x11" ] ++ lib.optionals stdenv.isLinux [ "wayland" ]
103, vulkanLayers ? lib.optionals (!stdenv.isDarwin) [ # No Vulkan support on Darwin
104 "device-select"
105 "overlay"
106 "intel-nullhw"
107]
108}:
109
110# When updating this package, please verify at least these build (assuming x86_64-linux):
111# nix build .#mesa .#pkgsi686Linux.mesa .#pkgsCross.aarch64-multiplatform.mesa .#pkgsMusl.mesa
112
113let
114 version = "24.0.7";
115 hash = "sha256-dFRCXx7UpvG1sQfhZyswyIsi6g7+oACuLH2W25P2wmo=";
116
117 # Release calendar: https://www.mesa3d.org/release-calendar.html
118 # Release frequency: https://www.mesa3d.org/releasing.html#schedule
119 branch = lib.versions.major version;
120
121 withLibdrm = lib.meta.availableOn stdenv.hostPlatform libdrm;
122
123 haveWayland = lib.elem "wayland" eglPlatforms;
124 haveZink = lib.elem "zink" galliumDrivers;
125 haveDozen = (lib.elem "d3d12" galliumDrivers) || (lib.elem "microsoft-experimental" vulkanDrivers);
126
127 rustDeps = [
128 {
129 pname = "proc-macro2";
130 version = "1.0.70";
131 hash = "sha256-e4ZgyZUTu5nAtaH5QVkLelqJQX/XPj/rWkzf/g2c+1g=";
132 }
133 {
134 pname = "quote";
135 version = "1.0.33";
136 hash = "sha256-VWRCZJO0/DJbNu0/V9TLaqlwMot65YjInWT9VWg57DY=";
137 }
138 {
139 pname = "syn";
140 version = "2.0.39";
141 hash = "sha256-Mjen2L/omhVbhU/+Ao65mogs3BP3fY+Bodab3uU63EI=";
142 }
143 {
144 pname = "unicode-ident";
145 version = "1.0.12";
146 hash = "sha256-KX8NqYYw6+rGsoR9mdZx8eT1HIPEUUyxErdk2H/Rlj8=";
147 }
148 ];
149
150 copyRustDep = dep: ''
151 cp -R --no-preserve=mode,ownership ${fetchCrate dep} subprojects/${dep.pname}-${dep.version}
152 cp -R subprojects/packagefiles/${dep.pname}/* subprojects/${dep.pname}-${dep.version}/
153 '';
154
155 copyRustDeps = lib.concatStringsSep "\n" (builtins.map copyRustDep rustDeps);
156
157self = stdenv.mkDerivation {
158 pname = "mesa";
159 inherit version;
160
161 src = fetchurl {
162 urls = [
163 "https://archive.mesa3d.org/mesa-${version}.tar.xz"
164 "https://mesa.freedesktop.org/archive/mesa-${version}.tar.xz"
165 "ftp://ftp.freedesktop.org/pub/mesa/mesa-${version}.tar.xz"
166 "ftp://ftp.freedesktop.org/pub/mesa/${version}/mesa-${version}.tar.xz"
167 "ftp://ftp.freedesktop.org/pub/mesa/older-versions/${branch}.x/${version}/mesa-${version}.tar.xz"
168 ];
169 inherit hash;
170 };
171
172 patches = [
173 ./opencl.patch
174 ];
175
176 postPatch = ''
177 patchShebangs .
178
179 # The drirc.d directory cannot be installed to $drivers as that would cause a cyclic dependency:
180 substituteInPlace src/util/xmlconfig.c --replace \
181 'DATADIR "/drirc.d"' '"${placeholder "out"}/share/drirc.d"'
182 substituteInPlace src/util/meson.build --replace \
183 "get_option('datadir')" "'${placeholder "out"}/share'"
184 substituteInPlace src/amd/vulkan/meson.build --replace \
185 "get_option('datadir')" "'${placeholder "out"}/share'"
186
187 ${copyRustDeps}
188 '';
189
190 outputs = [
191 "out" "dev" "drivers"
192 ] ++ lib.optionals enableOSMesa [
193 "osmesa"
194 ] ++ lib.optionals stdenv.isLinux [
195 "driversdev"
196 ] ++ lib.optionals enableOpenCL [
197 "opencl"
198 ] ++ lib.optionals haveDozen [
199 # the Dozen drivers depend on libspirv2dxil, but link it statically, and
200 # libspirv2dxil itself is pretty chonky, so relocate it to its own output in
201 # case anything wants to use it at some point
202 "spirv2dxil"
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=${llvmPackages.libllvm.dev}/bin:$PATH
212 '';
213
214 mesonFlags = [
215 "--sysconfdir=/etc"
216 "--datadir=${placeholder "drivers"}/share" # Vendor files
217
218 # Don't build in debug mode
219 # https://gitlab.freedesktop.org/mesa/mesa/blob/master/docs/meson.html#L327
220 (lib.mesonBool "b_ndebug" true)
221
222 (lib.mesonOption "dri-search-path" "${libglvnd.driverLink}/lib/dri")
223
224 (lib.mesonOption "platforms" (lib.concatStringsSep "," eglPlatforms))
225 (lib.mesonOption "gallium-drivers" (lib.concatStringsSep "," galliumDrivers))
226 (lib.mesonOption "vulkan-drivers" (lib.concatStringsSep "," vulkanDrivers))
227
228 (lib.mesonOption "dri-drivers-path" "${placeholder "drivers"}/lib/dri")
229 (lib.mesonOption "vdpau-libs-path" "${placeholder "drivers"}/lib/vdpau")
230 (lib.mesonOption "omx-libs-path" "${placeholder "drivers"}/lib/bellagio")
231 (lib.mesonOption "va-libs-path" "${placeholder "drivers"}/lib/dri")
232 (lib.mesonOption "d3d-drivers-path" "${placeholder "drivers"}/lib/d3d")
233
234 (lib.mesonBool "gallium-nine" enableGalliumNine) # Direct3D in Wine
235 (lib.mesonBool "osmesa" enableOSMesa) # used by wine
236 (lib.mesonEnable "microsoft-clc" false) # Only relevant on Windows (OpenCL 1.2 API on top of D3D12)
237
238 # To enable non-mesa gbm backends to be found (e.g. Nvidia)
239 (lib.mesonOption "gbm-backends-path" "${libglvnd.driverLink}/lib/gbm:${placeholder "out"}/lib/gbm")
240
241 # meson auto_features enables these features, but we do not want them
242 (lib.mesonEnable "android-libbacktrace" false)
243 ] ++ lib.optionals stdenv.isLinux [
244 (lib.mesonBool "glvnd" true)
245
246 # Enable RT for Intel hardware
247 # https://gitlab.freedesktop.org/mesa/mesa/-/issues/9080
248 (lib.mesonEnable "intel-clc" (stdenv.buildPlatform == stdenv.hostPlatform))
249 ] ++ lib.optionals stdenv.isDarwin [
250 # Disable features that are explicitly unsupported on the platform
251 (lib.mesonEnable "gbm" false)
252 (lib.mesonEnable "xlib-lease" false)
253 (lib.mesonEnable "egl" false)
254 (lib.mesonEnable "gallium-vdpau" false)
255 (lib.mesonEnable "gallium-va" false)
256 (lib.mesonEnable "gallium-xa" false)
257 (lib.mesonEnable "lmsensors" false)
258 ] ++ lib.optionals enableOpenCL [
259 # Clover, old OpenCL frontend
260 (lib.mesonOption "gallium-opencl" "icd")
261 (lib.mesonBool "opencl-spirv" true)
262
263 # Rusticl, new OpenCL frontend
264 (lib.mesonBool "gallium-rusticl" true)
265 (lib.mesonOption "clang-libdir" "${llvmPackages.clang-unwrapped.lib}/lib")
266 ] ++ lib.optionals (!withValgrind) [
267 (lib.mesonEnable "valgrind" false)
268 ] ++ lib.optionals (!withLibunwind) [
269 (lib.mesonEnable "libunwind" false)
270 ]
271 ++ lib.optionals enablePatentEncumberedCodecs [
272 (lib.mesonOption "video-codecs" "all")
273 ] ++ lib.optionals (vulkanLayers != []) [
274 (lib.mesonOption "vulkan-layers" (builtins.concatStringsSep "," vulkanLayers))
275 ];
276
277 strictDeps = true;
278
279 buildInputs = with xorg; [
280 expat
281 glslang
282 libffi
283 libglvnd
284 libvdpau
285 llvmPackages.libllvm
286 openssl
287 zstd
288 ] ++ (with xorg; [
289 libX11
290 libXext
291 libXfixes
292 libXrandr
293 libXt
294 libXvMC
295 libpthreadstubs
296 libxcb
297 libxshmfence
298 xorgproto
299 ]) ++ lib.optionals withLibunwind [
300 libunwind
301 ] ++ [
302 python3Packages.python # for shebang
303 ] ++ lib.optionals haveWayland [
304 wayland
305 wayland-protocols
306 ] ++ lib.optionals stdenv.isLinux [
307 libomxil-bellagio
308 libva-minimal
309 lm_sensors
310 udev
311 ] ++ lib.optionals (lib.meta.availableOn stdenv.hostPlatform elfutils) [
312 elfutils
313 ] ++ lib.optionals enableOpenCL [
314 llvmPackages.libclc
315 llvmPackages.clang
316 llvmPackages.clang-unwrapped
317 spirv-llvm-translator
318 ] ++ lib.optionals withValgrind [
319 valgrind-light
320 ] ++ lib.optionals haveZink [
321 vulkan-loader
322 ] ++ lib.optionals haveDozen [
323 directx-headers
324 ];
325
326 depsBuildBuild = [
327 pkg-config
328 ] ++ lib.optionals (!stdenv.isDarwin) [
329 # Adding this unconditionally makes x86_64-darwin pick up an older
330 # toolchain, as we explicitly call Mesa with 11.0 stdenv, but buildPackages
331 # is still 10.something, and Mesa can't build with that.
332 # FIXME: figure this out, or figure out how to get rid of Mesa on Darwin,
333 # whichever is easier.
334 buildPackages.stdenv.cc
335 ];
336
337 nativeBuildInputs = [
338 meson
339 pkg-config
340 ninja
341 intltool
342 bison
343 flex
344 file
345 python3Packages.python
346 python3Packages.mako
347 python3Packages.ply
348 jdupes
349 glslang
350 rustc
351 rust-bindgen
352 rustPlatform.bindgenHook
353 ] ++ lib.optionals haveWayland [
354 wayland-scanner
355 ];
356
357 propagatedBuildInputs = (with xorg; [
358 libXdamage
359 libXxf86vm
360 ]) ++ lib.optionals withLibdrm [
361 libdrm
362 ] ++ lib.optionals stdenv.isDarwin [
363 OpenGL
364 Xplugin
365 ];
366
367 doCheck = false;
368
369 postInstall = ''
370 # Some installs don't have any drivers so this directory is never created.
371 mkdir -p $drivers $osmesa
372 '' + lib.optionalString stdenv.isLinux ''
373 mkdir -p $drivers/lib
374
375 if [ -n "$(shopt -s nullglob; echo "$out/lib/libxatracker"*)" -o -n "$(shopt -s nullglob; echo "$out/lib/libvulkan_"*)" ]; then
376 # move gallium-related stuff to $drivers, so $out doesn't depend on LLVM
377 mv -t $drivers/lib \
378 $out/lib/libpowervr_rogue* \
379 $out/lib/libxatracker* \
380 $out/lib/libvulkan_*
381 fi
382
383 if [ -n "$(shopt -s nullglob; echo "$out"/lib/lib*_mesa*)" ]; then
384 # Move other drivers to a separate output
385 mv -t $drivers/lib $out/lib/lib*_mesa*
386 fi
387
388 # Update search path used by glvnd
389 for js in $drivers/share/glvnd/egl_vendor.d/*.json; do
390 substituteInPlace "$js" --replace '"libEGL_' '"'"$drivers/lib/libEGL_"
391 done
392
393 # Update search path used by Vulkan (it's pointing to $out but
394 # drivers are in $drivers)
395 for js in $drivers/share/vulkan/icd.d/*.json; do
396 substituteInPlace "$js" --replace "$out" "$drivers"
397 done
398 '' + lib.optionalString enableOpenCL ''
399 # Move OpenCL stuff
400 mkdir -p $opencl/lib
401 mv -t "$opencl/lib/" \
402 $out/lib/gallium-pipe \
403 $out/lib/lib*OpenCL*
404
405 # We construct our own .icd files that contain absolute paths.
406 mkdir -p $opencl/etc/OpenCL/vendors/
407 echo $opencl/lib/libMesaOpenCL.so > $opencl/etc/OpenCL/vendors/mesa.icd
408 echo $opencl/lib/libRusticlOpenCL.so > $opencl/etc/OpenCL/vendors/rusticl.icd
409 '' + lib.optionalString enableOSMesa ''
410 # move libOSMesa to $osmesa, as it's relatively big
411 mkdir -p $osmesa/lib
412 mv -t $osmesa/lib/ $out/lib/libOSMesa*
413 '' + lib.optionalString (vulkanLayers != []) ''
414 mv -t $drivers/lib $out/lib/libVkLayer*
415 for js in $drivers/share/vulkan/{im,ex}plicit_layer.d/*.json; do
416 substituteInPlace "$js" --replace '"libVkLayer_' '"'"$drivers/lib/libVkLayer_"
417 done
418 '' + lib.optionalString haveDozen ''
419 mkdir -p $spirv2dxil/{bin,lib}
420 mv -t $spirv2dxil/lib $out/lib/libspirv_to_dxil*
421 mv -t $spirv2dxil/bin $out/bin/spirv2dxil
422 '';
423
424 postFixup = lib.optionalString stdenv.isLinux ''
425 # set the default search path for DRI drivers; used e.g. by X server
426 for pc in lib/pkgconfig/{dri,d3d}.pc; do
427 [ -f "$dev/$pc" ] && substituteInPlace "$dev/$pc" --replace "$drivers" "${libglvnd.driverLink}"
428 done
429
430 # remove pkgconfig files for GL/EGL; they are provided by libGL.
431 rm -f $dev/lib/pkgconfig/{gl,egl}.pc
432
433 # Move development files for libraries in $drivers to $driversdev
434 mkdir -p $driversdev/include
435 mv $dev/include/xa_* $dev/include/d3d* -t $driversdev/include || true
436 mkdir -p $driversdev/lib/pkgconfig
437 for pc in lib/pkgconfig/{xatracker,d3d}.pc; do
438 if [ -f "$dev/$pc" ]; then
439 substituteInPlace "$dev/$pc" --replace $out $drivers
440 mv $dev/$pc $driversdev/$pc
441 fi
442 done
443
444 # Don't depend on build python
445 patchShebangs --host --update $out/bin/*
446
447 # NAR doesn't support hard links, so convert them to symlinks to save space.
448 jdupes --hard-links --link-soft --recurse "$drivers"
449
450 # add RPATH so the drivers can find the moved libgallium and libdricore9
451 # moved here to avoid problems with stripping patchelfed files
452 for lib in $drivers/lib/*.so* $drivers/lib/*/*.so*; do
453 if [[ ! -L "$lib" ]]; then
454 patchelf --set-rpath "$(patchelf --print-rpath $lib):$drivers/lib" "$lib"
455 fi
456 done
457 # add RPATH here so Zink can find libvulkan.so
458 ${lib.optionalString haveZink ''
459 patchelf --add-rpath ${vulkan-loader}/lib $drivers/lib/dri/zink_dri.so
460 ''}
461 '';
462
463 env.NIX_CFLAGS_COMPILE = toString (
464 lib.optionals stdenv.isDarwin [
465 "-fno-common"
466 ] ++ lib.optionals enableOpenCL [
467 "-UPIPE_SEARCH_DIR"
468 "-DPIPE_SEARCH_DIR=\"${placeholder "opencl"}/lib/gallium-pipe\""
469 ]);
470
471 passthru = {
472 inherit (libglvnd) driverLink;
473 inherit llvmPackages;
474
475 libdrm = if withLibdrm then libdrm else null;
476
477 tests = lib.optionalAttrs stdenv.isLinux {
478 devDoesNotDependOnLLVM = stdenv.mkDerivation {
479 name = "mesa-dev-does-not-depend-on-llvm";
480 buildCommand = ''
481 echo ${self.dev} >>$out
482 '';
483 disallowedRequisites = [ llvmPackages.llvm self.drivers ];
484 };
485 };
486 };
487
488 meta = {
489 description = "An open source 3D graphics library";
490 longDescription = ''
491 The Mesa project began as an open-source implementation of the OpenGL
492 specification - a system for rendering interactive 3D graphics. Over the
493 years the project has grown to implement more graphics APIs, including
494 OpenGL ES (versions 1, 2, 3), OpenCL, OpenMAX, VDPAU, VA API, XvMC, and
495 Vulkan. A variety of device drivers allows the Mesa libraries to be used
496 in many different environments ranging from software emulation to
497 complete hardware acceleration for modern GPUs.
498 '';
499 homepage = "https://www.mesa3d.org/";
500 changelog = "https://www.mesa3d.org/relnotes/${version}.html";
501 license = with lib.licenses; [ mit ]; # X11 variant, in most files
502 platforms = lib.platforms.mesaPlatforms;
503 badPlatforms = []; # Load bearing for libGL meta on Darwin.
504 maintainers = with lib.maintainers; [ primeos vcunat ]; # Help is welcome :)
505 };
506};
507
508in self