perf: cut the image 38% and turn GPU acceleration back on #112

Merged
padreug merged 9 commits from perf/gpu-acceleration into dev 2026-09-25 05:48:15 +00:00
Showing only changes of commit 1691511aea - Show all commits

perf(deploy): drop the gallium drivers this fleet cannot use

nixpkgs builds Mesa with 21 gallium drivers, the full Vulkan stack and the
VDPAU and VA state trackers, so one binary can serve every GPU and
cross-build case. This fleet is four Intel boards and a kiosk that never
asks for Vulkan.

  mesa closure  974.5 -> 88.5 MiB
  sintra 3940 -> 3201 MB    tejo  3940 -> 3201 MB
  batm3  3918 -> 3179 MB    douro 3894 -> 3156 MB

Keep crocus, i915 and softpipe. softpipe earns its place: it is the
software rasterizer that does NOT use LLVM, so a board whose KMS driver
fails still brings up X slowly rather than dying headless somewhere
nobody can reach it.

IRIS IS OUT, and that is what makes the rest of this possible. Mesa's
meson puts with_gallium_iris in with_driver_using_cl and then

  with_llvm.enable_if(with_clc, error_message : 'CLC requires LLVM')

so asking for iris drags in the OpenCL frontend and with it 540MB of
llvm-lib, and -Dllvm=disabled fails at configure. Nothing here needs iris.
The fleet was surveyed rather than assumed: sintra and tejo are Braswell
[8086:22b0], batm3 is Haswell GT2 [8086:0412], douro is Bay Trail. sintra
and batm3 were read off their running X logs and both say crocus.

That survey corrected an assumption an earlier draft of this commit was
built on. It claimed the UP Boards were the iris machines and crocus was
only for douro and batm3. sintra's Braswell is Gen8 and binds crocus
anyway. Had the list been trimmed to iris on that reasoning, which looked
like the tidier option, sintra would have dropped to software rendering or
lost its display outright.

With iris gone, LLVM goes: verified with patchelf, libgallium.so has no
libLLVM in its DT_NEEDED, not merely absent from the closure listing.
Dropping llvmpipe alone never achieved that.

THE COST IS FUTURE HARDWARE. A newer x86 board — a modern NUC, the "build
it from these parts" kiosk — will need iris, and re-adding it re-adds the
540MB. Until then such a board falls back to softpipe and renders in
software: it boots, it displays, it looks fine, and it is very slow. The
driver list carries that warning. Check `DRI driver:` in /var/log/X.0.log
on any new hardware rather than trusting the list still covers it.

Five secondary failures on the way here, each now a comment where it bites.
Two are nixpkgs' meson hook forcing auto_features=enabled, which turns
Mesa's soft driver guards into hard errors, so gallium-vdpau and gallium-va
must be disabled explicitly once the AMD and NVIDIA drivers are gone. One
is that outputs lists spirv2dxil and cross_tools unconditionally while only
d3d12, asahi and panfrost populate them; nix fails a build that leaves a
declared output unproduced, so they are created empty — and mesa sets
__structuredAttrs, so $outputs is a bash array and the obvious
`for o in $outputs` loop silently does nothing. The last two are the
asahi/panfrost cross tools and install-mesa-clc, which reference
prog_mesa_clc and so must go with LLVM.

Tested on sintra at the previous revision (with iris, 3744MB): X restarted
onto the pruned Mesa, glamor reported hardware acceleration on crocus, no
errors. This revision removes iris and LLVM and has NOT been on hardware
yet. douro and batm3 want their own nixos-rebuild test regardless; batm3
runs a different kernel and douro is the only Bay Trail.
Padreug 2026-09-24 22:31:20 +02:00

View file

@ -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";