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