docs(gpu): #1050 run the GPU tests locally on a software adapter

docs/gpu-pipeline.md says how to run lightcraft-gpu's tests on a machine
without a GPU: LIGHTCRAFT_GPU_ALLOW_SOFTWARE=1 admits Mesa's lavapipe on
Linux and WARP on Windows (Metal on macOS needs nothing), and
LIGHTCRAFT_SKIP_LOG shows whether anything still skipped for want of an
adapter. The comments on the variable and in equivalence.rs no longer
say CI runs them: the platform CI legs of #1148 are not landing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Chad Elliott
2026-10-31 22:26:51 -05:00
co-authored by Claude Opus 5.5
parent fc99d212f6
commit 21a7d64d46
3 changed files with 31 additions and 17 deletions
+26 -11
View File
@@ -50,8 +50,8 @@ Overrides (read once at launch):
- Both `LIGHTCRAFT_GPU=0` and `LIGHTCRAFT_GPU_BACKEND=off` also keep AI Denoise, the face models
and the AI mask model (SAM 3 on Metal) on the CPU.
- `LIGHTCRAFT_GPU_ALLOW_SOFTWARE=1`: accept a software adapter (llvmpipe / lavapipe, WARP), which is
otherwise refused because the CPU pipeline is faster. For tests on machines without a GPU (CI);
the app never sets it.
otherwise refused because the CPU pipeline is faster. For running the GPU tests on a machine
without a GPU (below); the app never sets it.
**DX12 shader compiler (issue #471).** Every instance (window and compute) compiles DX12 shaders with
FXC (`d3dcompiler_47.dll`, part of Windows; `lightcraft_gpu::backend::backend_options`). wgpu's
@@ -275,15 +275,30 @@ bit-identical, and one (the point colour range overlay) has max 2 LSB on 0.0002%
mean 0.0003 LSB. That is the same picture as on Metal, inside the bounds
(`cargo test -p lightcraft-gpu --release --test it equivalence:: -- --nocapture`).
**In CI** (`.github/workflows/ci.yml`, issue #1050) they run on every platform: on Metal on the macOS
runners, and on software adapters on Linux (Mesa lavapipe) and Windows (WARP, DX12 with FXC), which
`LIGHTCRAFT_GPU_ALLOW_SOFTWARE=1` admits (tests only: the app never sets it). The step fails if they
skip. Measured on lavapipe (CI and locally) and WARP: all 134 compared renders within **max 1 LSB,
mean ≤ 0.0003 LSB**, as on the M4 Pro; on the macOS runner's (paravirtual) Metal device one case reaches
2 LSB (point colour range overlay, 0.0002% of pixels over 1), the rest max 1. The suite takes about
50 s on lavapipe, 30 s on the macOS runner and 2–7.5 min on WARP. lavapipe's
storage bindings stop at 128 MiB (the WebGPU default), so the two big-source tests use a 117 MiB
source: above what a view keeps with its stages (96 MiB) and small enough to be uploaded there.
**Running them without a GPU (issue #1050).** `Gpu::new` turns down software adapters, so on a
machine without a hardware GPU (a VM, a container) every GPU test skips.
`LIGHTCRAFT_GPU_ALLOW_SOFTWARE=1` lets them through for one run (tests only: the app never sets it):
```sh
rm -f /tmp/gpu-skips.jsonl # the log is appended to; an absolute path, as tests run in crates/gpu
LIGHTCRAFT_GPU_ALLOW_SOFTWARE=1 LIGHTCRAFT_SKIP_LOG=/tmp/gpu-skips.jsonl cargo test -p lightcraft-gpu --tests
grep '"reason":"no GPU adapter' /tmp/gpu-skips.jsonl # no output: nothing skipped for want of an adapter
```
- **Linux:** Mesa's lavapipe (Vulkan; `mesa-vulkan-drivers` on Debian and Ubuntu). Its storage
bindings stop at 128 MiB (the WebGPU default), so the two big-source tests use a 117 MiB source:
above what a view keeps with its stages (96 MiB) and small enough to be uploaded there.
- **Windows:** WARP, the DX12 software rasterizer that ships with Windows (shaders through FXC, as
above).
- **macOS:** Metal is a hardware adapter, so the tests run without the variable.
A machine with a hardware GPU picks it over the software adapter, variable or not. Each test that
skips prints `skipped (gpu): …` and appends a line to the `LIGHTCRAFT_SKIP_LOG` file; with a software
adapter the only one left should be the device-loss test (`no GPU device, or one that can't be lost on
purpose here`). Measured 2026-10-11 on lavapipe and WARP, and again 2026-10-30 on lavapipe (Mesa's
llvmpipe on LLVM 20, 143 compared renders), every compared render stayed within **max 1 LSB, mean ≤
0.0003 LSB**, as on the M4 Pro. The equivalence binary takes about 20 s on lavapipe and several
minutes on WARP.
Remaining differences come from f32 vs f64 coordinate math, fast-math transcendental functions on
Metal and summation order in the box filters — all far below one 8-bit step.