Phase 4: play-through checked, final profile, dead code removed, next-step recommendation (t88)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-28 06:50:54 -04:00
co-authored by Claude Opus 5.5
parent 7468d00efb
commit fbc3b07be2
11 changed files with 49604 additions and 56 deletions
+29 -31
View File
@@ -134,10 +134,8 @@ python3 tools/shot.py shots/silo.png --setup tools/scenes/clear-sky.js \
`tools/scenes/clear-sky.js` clears a flat work area and sets `FLOOR`, `BX`, `BY` and `CAM`. Set
`CAM = [x, y]` to frame the shot.
- The HUD and the cursor previews are hidden unless you pass `--hud` or `--previews`.
- `--renderer webgpu|legacy` selects the renderer for either look (default WebGPU). WebGPU screenshots
fail clearly when no device is available; Legacy smooth uses WebGL2; WebGPU smooth uses WGSL.
- `test/t_gpu.py` compares the rendered composite against Legacy for ordinary cells, built pieces,
ghosts, fog and all thermal palettes, and checks world replacement, resize, timing and device loss.
- Both looks require WebGPU; there is no renderer switch or legacy fallback.
- `test/t_gpu.py` checks GPU uploads, dirty/full equality, contours, resize, timing and device loss.
World-pixel tests use `worldPixelContext()` to read both stacked canvases. The helper
presents the retained GPU result again before copying, because canvas textures expire after
presentation ([WebGPU specification](https://gpuweb.github.io/gpuweb/#abstract-opdef-expire-the-current-texture),
@@ -202,13 +200,11 @@ python3 tools/shot.py shots/silo.png --setup tools/scenes/clear-sky.js \
another 60 ticks. Each rebuild resets the power-rebuild scheduler, weather random stream and all statistics to
fresh-page values; fixture hashes are checked by `test/t_perf.js`. No save/load snapshot is used: it would quantize heat and land flyers.
**World** is the whole `drawWorld` CPU call. **Light** is the lighting work inside that call;
**Prep** sets up the view/masks/joins; **Colour** fills CPU grain buffers (including ghosts and
flyers); **Upload** submits the pixel buffer or smooth textures; **Blit** submits drawing,
including pixel light/glow composition or the smooth shader and Canvas2D copy. These are CPU
wall times, including driver stalls; they are not GPU timestamp measurements. In pixel look,
the glow upload is part of Blit. The separate `computeLight_ms` times an unconditional light
call even when the row has lighting off. World includes Light: do not add them together.
**World** is the whole `drawWorld` CPU call. **Prep** sets up the view/masks/joins;
**Colour** fills CPU rare-cell overrides (including ghosts and flyers); **Upload** writes
dirty world chunks and override textures; **Blit** submits GPU drawing and composition.
These are CPU wall times, including driver stalls; they are not GPU timestamp measurements.
Bloom is computed on the GPU. GPU light timestamps are recorded separately as `gpuLight`.
Overlay totals and each individual draw call are in JSON, with ms/frame and invocation counts; conditional
overlays absent from the fixture have zero calls, not a measured zero execution cost.
@@ -225,7 +221,7 @@ python3 tools/shot.py shots/silo.png --setup tools/scenes/clear-sky.js \
retain frame interval (rAF timestamps, including waiting/scheduling), CPU frame work, total
simulation work per frame and number of ticks. p50/p95/p99 use interpolated sorted samples;
five warm-up frames are excluded. Zero-tick frames correctly have zero simulation time.
JSON also records the smooth renderer's adaptive resolution scale: compare it as well as time.
JSON records a fixed render scale of 1 for both looks.
Comparisons accept subsets of the baseline scenes, looks and zooms, with identical world/viewport dimensions and run duration, print all timing changes, and mark >10% regressions;
tiny timings and tails can be noisy, and a zero baseline has no meaningful percent change.
@@ -246,30 +242,32 @@ python3 tools/shot.py shots/silo.png --setup tools/scenes/clear-sky.js \
- `tools/experiments/flow.js`: belt and screw conveyor throughput in grains a second.
- `tools/experiments/worldgen.js`: material counts and timings of world generation.
WebGPU Phase 2a: Colour measures the CPU override fill (including loose objects and ghosts).
`frame_ms` is the complete paused-frame CPU call (including overlays and UI).
Upload measures strided visible-array writes and the override/light uploads, and Blit measures
GPU command submission. `override_cells` records the selected CPU cells; GPU timing is a
completed timestamp sample for that configuration across colour, bloom and drawing when `timestamp-query` is
available. The timestamp excludes uploads and the CPU lighting pass. Lighting remains on the
CPU. The GPU canvas draws the world; the transparent game canvas holds the existing overlays.
Both looks use WebGPU. Colour measures the CPU rare-cell override fill, including loose
objects and ghosts. `frame_ms` is the complete paused-frame CPU call, with overlays and UI.
Upload measures dirty world chunks, override buffers and small lighting tables; Blit measures
GPU command submission. `override_cells` counts CPU cells. GPU timestamp samples include
colour, lighting, bloom and drawing, excluding uploads. CPU lighting is gone. The GPU canvas
draws the world; the transparent game canvas holds overlays. Override colours and glow live in
plain typed arrays, without offscreen Canvas2D backing stores.
The comparison fixture is `tools/scenes/t88-renderer.js`. Capture with `--freeze --zoom 12`
(and 6 or 2), `--viewport 1920x1080`, and each `--renderer`. It includes terrain, water, fire,
magma, fog, a tree, flat/slope belts, screws, pipe, mold, bar and blueprint ghost.
Use `tools/scenes/t88-renderer.js` with `--freeze --zoom 12` (or 6/2),
`--viewport 1920x1080` and `--look pixel|smooth`. It includes terrain, water, fire, magma,
fog, a tree, flat/slope belts, screws, pipe, mold, bar and blueprint ghost. Frozen legacy
comparisons are in `test/t_gpu_golden.py`; no legacy renderer remains in the game.
WebGPU Phase 2c: both looks use WebGPU. `test/t_gpu.py` also reads all four smooth input
textures back and compares them against the legacy CPU buffers at zoom 12/6/2 with fog on/off:
classes, sky flags, field bits and geometry tags must match exactly; RGB can differ by one.
The smooth shader retains the legacy nine-tap glow filter and samples field AO at mip level 2.2;
The smooth shader retains the nine-tap glow filter and samples field AO at mip level 2.2;
three render passes generate field levels 1-3, including non-power-of-two view sizes.
Only smooth allocates/uploads the back/tree/field overrides and a separate presence mask.
`tools/perf.py` refuses a WebGPU fallback in either look and records WebGPU scale as 1.
The screenshot tool invalidates the shared parallax horizon after scene setup changes `surfY`,
so renderer startup timing cannot change the hills in a comparison. Mip pass references:
[Chrome's porting guide](https://developer.chrome.com/docs/web-platform/webgpu/from-webgl-to-webgpu#mipmap_generation)
Only smooth uploads back/tree/field overrides and a separate presence mask. Profiler scale is
always 1. The screenshot tool invalidates the parallax horizon after setup changes `surfY`.
Mip pass references: [Chrome's porting guide](https://developer.chrome.com/docs/web-platform/webgpu/from-webgl-to-webgpu#mipmap_generation)
and [WebGPU Fundamentals](https://webgpufundamentals.org/webgpu/lessons/webgpu-importing-textures.html#generating-mips-on-the-gpu).
`perfSim` reports synchronous tick wall time (also occupied main-thread time), polling in
`threadWait`, and main compute excluding polling. The latter includes serial simulation,
dispatch/merge and the main thread's own chunk batch; it is not pure scheduling overhead.
Final t88 full-matrix results are saved in `tools/perf-after-t88.json`; keep
`tools/perf-baseline.json` unchanged as the original comparison.
The required pipeline limits are checked in `gpuLimitsOK` before requesting the device: four
storage textures, sixteen sampled textures and eight storage buffers per stage, plus 8192 for
2D textures; no non-default limit is requested. References: [WebGPU limits](https://www.w3.org/TR/2026/CRD-webgpu-20260109/#limits)