diff --git a/deploy/nixos/configuration.nix b/deploy/nixos/configuration.nix index fe00d43..eeabe5a 100644 --- a/deploy/nixos/configuration.nix +++ b/deploy/nixos/configuration.nix @@ -164,6 +164,95 @@ in # passes and the full one fails the build with a readable error. system.forbiddenDependenciesRegexes = [ "linux-firmware-[0-9]" ]; + # Mesa without an LLVM-backed rasterizer. + # + # nixpkgs builds Mesa with 21 gallium drivers. Two of them, llvmpipe and + # radeonsi, link LLVM, and that RPATH pulls llvm-21-lib into the system + # closure: 540MB, a ninth of the image, on a kiosk with a soldered Intel GPU. + # + # The driver list has to span three Intel generations: + # crocus EVERY machine in the fleet. Surveyed, not assumed: sintra + # and tejo are Braswell [8086:22b0], batm3 is Haswell GT2 + # [8086:0412], douro is Bay Trail. sintra and batm3 were read + # straight off their running X logs; both say crocus. + # i915 pre-Gen4, insurance against an older board turning up. + # softpipe the software rasterizer that does NOT use LLVM. Kept so a + # board whose KMS driver fails still brings up X, slowly, + # rather than dying headless in the field. + # + # ── IRIS IS DELIBERATELY ABSENT AND RE-ADDING IT COSTS 540MB ──────── + # iris covers Gen8+ big-core Intel, which nothing here has. Its absence is + # what lets -Dllvm=disabled below work: mesa's meson puts + # with_gallium_iris in with_driver_using_cl and then + # with_llvm.enable_if(with_clc, 'CLC requires LLVM') + # so asking for iris drags in the OpenCL frontend and the whole of + # llvm-lib. Mesa's closure is 88MB without iris, 633MB with. + # + # A newer x86 board — a modern NUC, the "build it from these parts" kiosk + # — WILL need iris. Until one exists, such a board falls back to softpipe + # and renders in software: it boots, it displays, it looks fine, and it is + # very slow. Check `DRI driver:` in /var/log/X.0.log on any new hardware + # rather than assuming this list still covers it. + # i915 pre-Gen4, insurance against an older board turning up + # softpipe the software rasterizer that does NOT use LLVM. Kept so a + # board whose KMS driver fails still brings up X, slowly, + # rather than dying headless in the field. This is the role + # llvmpipe was playing, for 540MB. + # + # Vulkan is emptied because nothing here uses it, and its software ICD + # (lavapipe) is the other LLVM consumer. The VDPAU and VA state trackers + # have to go with it: meson refuses to build them unless one of the AMD or + # NVIDIA gallium drivers is present. Intel VA-API is unaffected, it comes + # from intel-media-driver in hardware/*.nix. + hardware.graphics.package = + (pkgs.mesa.override { + galliumDrivers = [ "crocus" "i915" "softpipe" ]; + vulkanDrivers = [ ]; + vulkanLayers = [ ]; + }).overrideAttrs + (old: { + mesonFlags = old.mesonFlags ++ [ + # Severs LLVM outright. Only possible because iris is out of the + # driver list above; with iris present meson refuses this flag. + # Verified with patchelf: libgallium.so ends up with no libLLVM in + # its DT_NEEDED, not merely absent from the closure listing. + # Dropping llvmpipe alone never achieved this. + (lib.mesonEnable "llvm" false) + (lib.mesonBool "gallium-rusticl" false) + # nixpkgs builds the asahi/panfrost cross tools and installs + # mesa-clc on native builds. Both reference prog_mesa_clc, which + # exists only when CLC is on, so they go with LLVM. An x86 kiosk + # has no use for either. + (lib.mesonOption "tools" "") + (lib.mesonBool "install-mesa-clc" false) + (lib.mesonBool "install-precomp-compiler" false) + (lib.mesonEnable "gallium-vdpau" false) + (lib.mesonEnable "gallium-va" false) + (lib.mesonEnable "intel-rt" false) + ]; + # Mesa declares spirv2dxil and cross_tools as outputs unconditionally, + # but they only receive files when the d3d12, asahi or panfrost gallium + # drivers are built, and none of those are in the list above. Nix fails + # a build that leaves a declared output unproduced, so create them + # empty. (Mesa sets __structuredAttrs, so $outputs is a bash array and + # a plain `for o in $outputs` loop silently does nothing here.) + postInstall = (old.postInstall or "") + '' + mkdir -p "$spirv2dxil" "$cross_tools" "$opencl" + ''; + + # With rusticl off there is no libRusticlOpenCL.so, and Mesa's + # postFixup patchelfs it unconditionally. Drop just that argument. + # The assert makes a nixpkgs bump that reshapes this line fail loudly + # here rather than silently stop removing LLVM. + postFixup = + let + marker = " $opencl/lib/libRusticlOpenCL.so"; + in + assert lib.assertMsg (lib.hasInfix marker old.postFixup) + "mesa postFixup no longer patchelfs libRusticlOpenCL.so; revisit this override"; + lib.replaceStrings [ marker ] [ "" ] old.postFixup; + }); + # Networking networking = { hostName = "bitspire";