lol
at 23.11-beta 388 lines 16 kB view raw
1{ stdenv, lib, fetchurl, fetchpatch, buildPackages 2, meson, pkg-config, ninja 3, intltool, bison, flex, file, python3Packages, wayland-scanner 4, expat, libdrm, xorg, wayland, wayland-protocols, openssl 5, llvmPackages_16, libffi, libomxil-bellagio, libva-minimal 6, libelf, libvdpau 7, libglvnd, libunwind, lm_sensors 8, vulkan-loader, glslang 9, galliumDrivers ? 10 if stdenv.isLinux then 11 [ 12 "d3d12" # WSL emulated GPU (aka Dozen) 13 "nouveau" # Nvidia 14 "radeonsi" # new AMD (GCN+) 15 "r300" # very old AMD 16 "r600" # less old AMD 17 "swrast" # software renderer (aka LLVMPipe) 18 "svga" # VMWare virtualized GPU 19 "virgl" # QEMU virtualized GPU (aka VirGL) 20 "zink" # generic OpenGL over Vulkan, experimental 21 ] ++ lib.optionals (stdenv.isAarch64 || stdenv.isAarch32) [ 22 "etnaviv" # Vivante GPU designs (mostly NXP/Marvell SoCs) 23 "freedreno" # Qualcomm Adreno (all Qualcomm SoCs) 24 "lima" # ARM Mali 4xx 25 "panfrost" # ARM Mali Midgard and up (T/G series) 26 "vc4" # Broadcom VC4 (Raspberry Pi 0-3) 27 ] ++ lib.optionals stdenv.isAarch64 [ 28 "tegra" # Nvidia Tegra SoCs 29 "v3d" # Broadcom VC5 (Raspberry Pi 4) 30 ] ++ lib.optionals stdenv.hostPlatform.isx86 [ 31 "iris" # new Intel, could work on non-x86 with PCIe cards, but doesn't build as of 22.3.4 32 "crocus" # Intel legacy, x86 only 33 "i915" # Intel extra legacy, x86 only 34 ] 35 else [ "auto" ] 36, vulkanDrivers ? 37 if stdenv.isLinux then 38 [ 39 "amd" # AMD (aka RADV) 40 "microsoft-experimental" # WSL virtualized GPU (aka DZN/Dozen) 41 "swrast" # software renderer (aka Lavapipe) 42 ] 43 ++ lib.optionals (stdenv.hostPlatform.isAarch -> lib.versionAtLeast stdenv.hostPlatform.parsed.cpu.version "6") [ 44 # QEMU virtualized GPU (aka VirGL) 45 # Requires ATOMIC_INT_LOCK_FREE == 2. 46 "virtio-experimental" 47 ] 48 ++ lib.optionals stdenv.isAarch64 [ 49 "broadcom" # Broadcom VC5 (Raspberry Pi 4, aka V3D) 50 "freedreno" # Qualcomm Adreno (all Qualcomm SoCs) 51 "imagination-experimental" # PowerVR Rogue (currently N/A) 52 "panfrost" # ARM Mali Midgard and up (T/G series) 53 ] 54 ++ lib.optionals stdenv.hostPlatform.isx86 [ 55 "intel" # Intel (aka ANV), could work on non-x86 with PCIe cards, but doesn't build 56 "intel_hasvk" # Intel Haswell/Broadwell, "legacy" Vulkan driver (https://www.phoronix.com/news/Intel-HasVK-Drop-Dead-Code) 57 ] 58 else [ "auto" ] 59, eglPlatforms ? [ "x11" ] ++ lib.optionals stdenv.isLinux [ "wayland" ] 60, vulkanLayers ? lib.optionals (!stdenv.isDarwin) [ "device-select" "overlay" "intel-nullhw" ] # No Vulkan support on Darwin 61, OpenGL, Xplugin 62, withValgrind ? lib.meta.availableOn stdenv.hostPlatform valgrind-light && !valgrind-light.meta.broken, valgrind-light 63, enableGalliumNine ? stdenv.isLinux 64, enableOSMesa ? stdenv.isLinux 65, enableOpenCL ? stdenv.isLinux && stdenv.isx86_64 66, enablePatentEncumberedCodecs ? true 67, jdupes 68, rustc 69, spirv-llvm-translator 70, zstd 71, directx-headers 72, udev 73}: 74 75/** Packaging design: 76 - The basic mesa ($out) contains headers and libraries (GLU is in libGLU now). 77 This or the mesa attribute (which also contains GLU) are small (~ 2 MB, mostly headers) 78 and are designed to be the buildInput of other packages. 79 - DRI drivers are compiled into $drivers output, which is much bigger and 80 depends on LLVM. These should be searched at runtime in 81 "/run/opengl-driver{,-32}/lib/*" and so are kind-of impure (given by NixOS). 82 (I suppose on non-NixOS one would create the appropriate symlinks from there.) 83 - libOSMesa is in $osmesa (~4 MB) 84*/ 85 86let 87 version = "23.1.9"; 88 hash = "sha256-KVuifCgUbtCSFOjOea+hZZ7fnRQt7MPJH4BFUtZPdRA="; 89 90 # Release calendar: https://www.mesa3d.org/release-calendar.html 91 # Release frequency: https://www.mesa3d.org/releasing.html#schedule 92 branch = lib.versions.major version; 93 94 withLibdrm = lib.meta.availableOn stdenv.hostPlatform libdrm; 95 96 llvmPackages = llvmPackages_16; 97 # Align all the Mesa versions used. Required to prevent explosions when 98 # two different LLVMs are loaded in the same process. 99 # FIXME: these should really go into some sort of versioned LLVM package set 100 rust-bindgen' = buildPackages.rust-bindgen.override { 101 rust-bindgen-unwrapped = buildPackages.rust-bindgen.unwrapped.override { 102 clang = buildPackages.llvmPackages_15.clang; 103 }; 104 }; 105 spirv-llvm-translator' = spirv-llvm-translator.override { 106 inherit (llvmPackages) llvm; 107 }; 108 109 haveWayland = lib.elem "wayland" eglPlatforms; 110 haveZink = lib.elem "zink" galliumDrivers; 111 haveDozen = (lib.elem "d3d12" galliumDrivers) || (lib.elem "microsoft-experimental" vulkanDrivers); 112self = stdenv.mkDerivation { 113 pname = "mesa"; 114 inherit version; 115 116 src = fetchurl { 117 urls = [ 118 "https://archive.mesa3d.org/mesa-${version}.tar.xz" 119 "https://mesa.freedesktop.org/archive/mesa-${version}.tar.xz" 120 "ftp://ftp.freedesktop.org/pub/mesa/mesa-${version}.tar.xz" 121 "ftp://ftp.freedesktop.org/pub/mesa/${version}/mesa-${version}.tar.xz" 122 "ftp://ftp.freedesktop.org/pub/mesa/older-versions/${branch}.x/${version}/mesa-${version}.tar.xz" 123 ]; 124 inherit hash; 125 }; 126 127 # TODO: 128 # revive ./dricore-gallium.patch when it gets ported (from Ubuntu), as it saved 129 # ~35 MB in $drivers; watch https://launchpad.net/ubuntu/+source/mesa/+changelog 130 patches = [ 131 # fixes pkgsMusl.mesa build 132 ./musl.patch 133 134 ./opencl.patch 135 ./disk_cache-include-dri-driver-path-in-cache-key.patch 136 ]; 137 138 postPatch = '' 139 patchShebangs . 140 141 # The drirc.d directory cannot be installed to $drivers as that would cause a cyclic dependency: 142 substituteInPlace src/util/xmlconfig.c --replace \ 143 'DATADIR "/drirc.d"' '"${placeholder "out"}/share/drirc.d"' 144 substituteInPlace src/util/meson.build --replace \ 145 "get_option('datadir')" "'${placeholder "out"}/share'" 146 substituteInPlace src/amd/vulkan/meson.build --replace \ 147 "get_option('datadir')" "'${placeholder "out"}/share'" 148 ''; 149 150 outputs = [ "out" "dev" "drivers" ] 151 ++ lib.optional enableOSMesa "osmesa" 152 ++ lib.optional stdenv.isLinux "driversdev" 153 ++ lib.optional enableOpenCL "opencl" 154 # the Dozen drivers depend on libspirv2dxil, but link it statically, and 155 # libspirv2dxil itself is pretty chonky, so relocate it to its own output 156 # in case anything wants to use it at some point 157 ++ lib.optional haveDozen "spirv2dxil"; 158 159 # FIXME: this fixes rusticl/iris segfaulting on startup, _somehow_. 160 # Needs more investigating. 161 separateDebugInfo = true; 162 163 preConfigure = '' 164 PATH=${llvmPackages.libllvm.dev}/bin:$PATH 165 ''; 166 167 # TODO: Figure out how to enable opencl without having a runtime dependency on clang 168 mesonFlags = [ 169 "--sysconfdir=/etc" 170 "--datadir=${placeholder "drivers"}/share" # Vendor files 171 172 # Don't build in debug mode 173 # https://gitlab.freedesktop.org/mesa/mesa/blob/master/docs/meson.html#L327 174 "-Db_ndebug=true" 175 176 "-Ddisk-cache-key=${placeholder "drivers"}" 177 "-Ddri-search-path=${libglvnd.driverLink}/lib/dri" 178 179 "-Dplatforms=${lib.concatStringsSep "," eglPlatforms}" 180 "-Dgallium-drivers=${lib.concatStringsSep "," galliumDrivers}" 181 "-Dvulkan-drivers=${lib.concatStringsSep "," vulkanDrivers}" 182 183 "-Ddri-drivers-path=${placeholder "drivers"}/lib/dri" 184 "-Dvdpau-libs-path=${placeholder "drivers"}/lib/vdpau" 185 "-Domx-libs-path=${placeholder "drivers"}/lib/bellagio" 186 "-Dva-libs-path=${placeholder "drivers"}/lib/dri" 187 "-Dd3d-drivers-path=${placeholder "drivers"}/lib/d3d" 188 189 "-Dgallium-nine=${lib.boolToString enableGalliumNine}" # Direct3D in Wine 190 "-Dosmesa=${lib.boolToString enableOSMesa}" # used by wine 191 "-Dmicrosoft-clc=disabled" # Only relevant on Windows (OpenCL 1.2 API on top of D3D12) 192 193 # To enable non-mesa gbm backends to be found (e.g. Nvidia) 194 "-Dgbm-backends-path=${libglvnd.driverLink}/lib/gbm:${placeholder "out"}/lib/gbm" 195 196 # meson auto_features enables these features, but we do not want them 197 "-Dandroid-libbacktrace=disabled" 198 199 ] ++ lib.optionals stdenv.isLinux [ 200 "-Dglvnd=true" 201 202 # Enable RT for Intel hardware 203 # https://gitlab.freedesktop.org/mesa/mesa/-/issues/9080 204 (lib.mesonEnable "intel-clc" (stdenv.buildPlatform == stdenv.hostPlatform)) 205 ] ++ lib.optionals enableOpenCL [ 206 # Clover, old OpenCL frontend 207 "-Dgallium-opencl=icd" 208 "-Dopencl-spirv=true" 209 210 # Rusticl, new OpenCL frontend 211 "-Dgallium-rusticl=true" "-Drust_std=2021" 212 "-Dclang-libdir=${llvmPackages.clang-unwrapped.lib}/lib" 213 ] ++ lib.optionals (!withValgrind) [ 214 "-Dvalgrind=disabled" 215 ] ++ lib.optional enablePatentEncumberedCodecs 216 "-Dvideo-codecs=h264dec,h264enc,h265dec,h265enc,vc1dec" 217 ++ lib.optional (vulkanLayers != []) "-D vulkan-layers=${builtins.concatStringsSep "," vulkanLayers}"; 218 219 buildInputs = with xorg; [ 220 expat glslang llvmPackages.libllvm libglvnd xorgproto 221 libX11 libXext libxcb libXt libXfixes libxshmfence libXrandr 222 libffi libvdpau libelf libXvMC 223 libpthreadstubs openssl /*or another sha1 provider*/ 224 zstd libunwind 225 python3Packages.python # for shebang 226 ] ++ lib.optionals haveWayland [ wayland wayland-protocols ] 227 ++ lib.optionals stdenv.isLinux [ libomxil-bellagio libva-minimal udev lm_sensors ] 228 ++ lib.optionals enableOpenCL [ llvmPackages.libclc llvmPackages.clang llvmPackages.clang-unwrapped spirv-llvm-translator' ] 229 ++ lib.optional withValgrind valgrind-light 230 ++ lib.optional haveZink vulkan-loader 231 ++ lib.optional haveDozen directx-headers; 232 233 depsBuildBuild = [ pkg-config ] 234 ++ lib.optional enableOpenCL buildPackages.stdenv.cc; 235 236 nativeBuildInputs = [ 237 meson pkg-config ninja 238 intltool bison flex file 239 python3Packages.python python3Packages.mako python3Packages.ply 240 jdupes glslang 241 ] ++ lib.optionals enableOpenCL [ rust-bindgen' rustc ] 242 ++ lib.optional haveWayland wayland-scanner; 243 244 propagatedBuildInputs = with xorg; [ 245 libXdamage libXxf86vm 246 ] ++ lib.optional withLibdrm libdrm 247 ++ lib.optionals stdenv.isDarwin [ OpenGL Xplugin ]; 248 249 doCheck = false; 250 251 postInstall = '' 252 # Some installs don't have any drivers so this directory is never created. 253 mkdir -p $drivers $osmesa 254 '' + lib.optionalString stdenv.isLinux '' 255 mkdir -p $drivers/lib 256 257 if [ -n "$(shopt -s nullglob; echo "$out/lib/libxatracker"*)" -o -n "$(shopt -s nullglob; echo "$out/lib/libvulkan_"*)" ]; then 258 # move gallium-related stuff to $drivers, so $out doesn't depend on LLVM 259 mv -t $drivers/lib \ 260 $out/lib/libpowervr_rogue* \ 261 $out/lib/libxatracker* \ 262 $out/lib/libvulkan_* 263 fi 264 265 if [ -n "$(shopt -s nullglob; echo "$out"/lib/lib*_mesa*)" ]; then 266 # Move other drivers to a separate output 267 mv -t $drivers/lib $out/lib/lib*_mesa* 268 fi 269 270 # Update search path used by glvnd 271 for js in $drivers/share/glvnd/egl_vendor.d/*.json; do 272 substituteInPlace "$js" --replace '"libEGL_' '"'"$drivers/lib/libEGL_" 273 done 274 275 # Update search path used by Vulkan (it's pointing to $out but 276 # drivers are in $drivers) 277 for js in $drivers/share/vulkan/icd.d/*.json; do 278 substituteInPlace "$js" --replace "$out" "$drivers" 279 done 280 '' + lib.optionalString enableOpenCL '' 281 # Move OpenCL stuff 282 mkdir -p $opencl/lib 283 mv -t "$opencl/lib/" \ 284 $out/lib/gallium-pipe \ 285 $out/lib/lib*OpenCL* 286 287 # We construct our own .icd files that contain absolute paths. 288 mkdir -p $opencl/etc/OpenCL/vendors/ 289 echo $opencl/lib/libMesaOpenCL.so > $opencl/etc/OpenCL/vendors/mesa.icd 290 echo $opencl/lib/libRusticlOpenCL.so > $opencl/etc/OpenCL/vendors/rusticl.icd 291 '' + lib.optionalString enableOSMesa '' 292 # move libOSMesa to $osmesa, as it's relatively big 293 mkdir -p $osmesa/lib 294 mv -t $osmesa/lib/ $out/lib/libOSMesa* 295 '' + lib.optionalString (vulkanLayers != []) '' 296 mv -t $drivers/lib $out/lib/libVkLayer* 297 for js in $drivers/share/vulkan/{im,ex}plicit_layer.d/*.json; do 298 substituteInPlace "$js" --replace '"libVkLayer_' '"'"$drivers/lib/libVkLayer_" 299 done 300 '' + lib.optionalString haveDozen '' 301 mkdir -p $spirv2dxil/{bin,lib} 302 mv -t $spirv2dxil/lib $out/lib/libspirv_to_dxil* 303 mv -t $spirv2dxil/bin $out/bin/spirv2dxil 304 ''; 305 306 postFixup = lib.optionalString stdenv.isLinux '' 307 # set the default search path for DRI drivers; used e.g. by X server 308 substituteInPlace "$dev/lib/pkgconfig/dri.pc" --replace "$drivers" "${libglvnd.driverLink}" 309 [ -f "$dev/lib/pkgconfig/d3d.pc" ] && substituteInPlace "$dev/lib/pkgconfig/d3d.pc" --replace "$drivers" "${libglvnd.driverLink}" 310 311 # remove pkgconfig files for GL/EGL; they are provided by libGL. 312 rm -f $dev/lib/pkgconfig/{gl,egl}.pc 313 314 # Move development files for libraries in $drivers to $driversdev 315 mkdir -p $driversdev/include 316 mv $dev/include/xa_* $dev/include/d3d* -t $driversdev/include || true 317 mkdir -p $driversdev/lib/pkgconfig 318 for pc in lib/pkgconfig/{xatracker,d3d}.pc; do 319 if [ -f "$dev/$pc" ]; then 320 substituteInPlace "$dev/$pc" --replace $out $drivers 321 mv $dev/$pc $driversdev/$pc 322 fi 323 done 324 325 # Don't depend on build python 326 patchShebangs --host --update $out/bin/* 327 328 # NAR doesn't support hard links, so convert them to symlinks to save space. 329 jdupes --hard-links --link-soft --recurse "$drivers" 330 331 # add RPATH so the drivers can find the moved libgallium and libdricore9 332 # moved here to avoid problems with stripping patchelfed files 333 for lib in $drivers/lib/*.so* $drivers/lib/*/*.so*; do 334 if [[ ! -L "$lib" ]]; then 335 patchelf --set-rpath "$(patchelf --print-rpath $lib):$drivers/lib" "$lib" 336 fi 337 done 338 # add RPATH here so Zink can find libvulkan.so 339 ${lib.optionalString haveZink '' 340 patchelf --add-rpath ${vulkan-loader}/lib $drivers/lib/dri/zink_dri.so 341 ''} 342 ''; 343 344 env.NIX_CFLAGS_COMPILE = toString (lib.optionals stdenv.isDarwin [ "-fno-common" ] ++ lib.optionals enableOpenCL [ 345 "-UPIPE_SEARCH_DIR" 346 "-DPIPE_SEARCH_DIR=\"${placeholder "opencl"}/lib/gallium-pipe\"" 347 ]); 348 349 passthru = { 350 inherit (libglvnd) driverLink; 351 inherit llvmPackages; 352 353 libdrm = if withLibdrm then libdrm else null; 354 355 tests = lib.optionalAttrs stdenv.isLinux { 356 devDoesNotDependOnLLVM = stdenv.mkDerivation { 357 name = "mesa-dev-does-not-depend-on-llvm"; 358 buildCommand = '' 359 echo ${self.dev} >>$out 360 ''; 361 disallowedRequisites = [ llvmPackages.llvm self.drivers ]; 362 }; 363 }; 364 }; 365 366 meta = with lib; { 367 description = "An open source 3D graphics library"; 368 longDescription = '' 369 The Mesa project began as an open-source implementation of the OpenGL 370 specification - a system for rendering interactive 3D graphics. Over the 371 years the project has grown to implement more graphics APIs, including 372 OpenGL ES (versions 1, 2, 3), OpenCL, OpenMAX, VDPAU, VA API, XvMC, and 373 Vulkan. A variety of device drivers allows the Mesa libraries to be used 374 in many different environments ranging from software emulation to 375 complete hardware acceleration for modern GPUs. 376 ''; 377 homepage = "https://www.mesa3d.org/"; 378 changelog = "https://www.mesa3d.org/relnotes/${version}.html"; 379 license = licenses.mit; # X11 variant, in most files 380 platforms = platforms.mesaPlatforms; 381 maintainers = with maintainers; [ primeos vcunat ]; # Help is welcome :) 382 383 # https://gitlab.freedesktop.org/mesa/mesa/-/issues/8634 384 broken = stdenv.isDarwin; 385 }; 386}; 387 388in self