Private-buffer source-format comparison
The diagnostic cross-build passed with nix build .#k230-vglite-color-probe --max-jobs 1 --cores 2 --no-link --print-out-paths. On the unchanged board,
timeout 15s /run/card-tools/vglite-color-probe completed all 18 cases and
returned 3 (completed comparison with mismatches). rgba-rgbx.json retains its
structured output, exact artifact and source hash. No process held the GPU
device before the run; normal shell and seatd remained active afterwards.
Each case uses private 256x8 allocations, point sampling, blend NONE, and an actual Pixman SRC conversion to RGB565 as reference. Rows include all 256 values of each channel, grayscale, mixed colors, the scene fixture’s two problem colors, and black/white. Three rounds rotate the gradients. Both RGBA and RGBX upload formats produce 660 differing pixels out of 2,048 for every round and each alpha byte (255, 128, 0). The first differing red input is 136: Pixman yields red code 17, GPU code 16. Merely switching to RGBX does not fix the mismatch, and changing the alpha byte does not change it.
The initial preflight refused to execute because fuser is not installed.
The successful run instead checked /proc/*/fd using the already-installed
Python. The executable transfer was verified on the board before running it.
This diagnoses private-buffer conversion only. It proves neither compositor pixels nor general cache, scale, clip, service-access or performance acceptance. No DRM node is opened by this probe, the shell stays on Pixman, and all existing physical acceptance tasks remain open.
Exact RGB565 upload result
The extended diagnostic adds VG_LITE_BGR565 sources prepared by the same
Pixman SRC conversion. rgb565.json retains all 27 cases. Every RGB565-source
case matches exactly (nine cases, 18,432 pixels); the RGBA/RGBX negative controls
still produce their original 660 mismatches each. The process therefore still
returns 3, preserving those known failures rather than reporting an overall
pass. Shell and seatd remain active on the same boot.
This supports testing RGB565 preconversion in the opt-in renderer. It is not yet proof of scaled/cropped compositor output or a rendering speedup.
Opt-in renderer correction
The renderer now prequantizes its immutable RGBA snapshot to RGB565 when uploading an already-eligible texture. Existing blend eligibility is unchanged: NONE ignores source alpha at the RGB target; SRC_OVER is admitted only for opaque content. Unsupported blending still replays the whole pass in Pixman. The host test device now consumes actual 16-bit uploads, and the production renderer is compared against pinned wlroots/Pixman across channel gradients, source crops, scales, padded rows, metadata rejection and failure/quarantine.
TMPDIR=/mnt/MediaVolume/home/jadams WLROOTS_SOURCE=/nix/store/r2zcb3d3dgmz09qjaqsy945inal2h41r-source VGLITE_SOURCE=/nix/store/pvpqrg3diyi9mcgmqjc0f80hpdmk699p-source/buildroot-overlay/package/vg_lite tools/test-vglite-renderer.sh
passes with ASan/UBSan. nix build .#shell-compositor-vglite --max-jobs 1 --cores 8 --no-link --print-out-paths passes, producing
/nix/store/rfqwba7pf9mcbwrkx2ypdaidy7bmwp0m-sway-1.12.
Actual compositor results are recorded below. Conversion adds CPU work; a
speedup is not assumed.
Corrected compositor captures
On 2026-09-23 at 19:01:46 UTC (GPU) and 19:03:03 UTC (forced Pixman), the
bounded root scene harness ran renderer source
d46333f2b838a3440c9ee87ac05dd940cf153284 on the unchanged board. Both trials
completed successfully and restored the normal shell and seatd. Each observed
one Sway process and DRM RGB565 scanout with the same padded allocator.
scene/scene-check.py records the actual executable/client paths and invocation;
the two scene/*/result.json files retain artifacts, timestamps and recovery.
| Mode | GPU frames | Pixman replays | Recovery |
|---|---|---|---|
| RGB565 upload | 182 | 0 | Normal shell active |
| Forced Pixman, same allocator | 0 | 573 | Normal shell active |
python3 docs/evidence/vglite-scene-board/color-upload/scene/analyze-palette.py
passes without a tolerance: both captures per mode have exactly matching
parent and child palettes. The formerly differing bright colors now read
(33, 113, 181) and (231, 146, 33) in both modes. Root and independent child
counters advance in both. The coordinator visually inspected the two later
captures: both show the expected blue parent and orange child bands.
This resolves the observed palette discrepancy for this scene. Different animation frames prevent a full-image equality claim. This is native capture and synthetic-client evidence, not a camera or finger interaction test. Frame totals still show fewer completions under GPU; startup/capture/animation sequences differ, so this is not the matched performance benchmark. Scaling, bounds, broader cache proof, normal-service access and all control routes still need their named board evidence. No GPU task is marked complete by this sample.