Files
retroDE_ps2/docs/ch402_character_clamp_closeout.md
thejayman77 ba74bbd5aa Snapshot: fog implementation + fidelity tooling baseline (pre bilinear-clamp fix)
Per-vertex GS fog end-to-end (gs_stub emit incl. persp_emit5, gs_prim_list_feeder
XYZ2->XYZF2 on PRIM.FGE, gs_make_sh3_scheduler_fixture.py F/FGE packing), new fog
TBs, fidelity attribution tooling. Functional baseline before removing the dead
bilinear lerp8 clamps (Codex: 161-node comb loop -> -0.042ns setup fail).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-20 19:56:46 -04:00

3.3 KiB

Ch402 — character draws through runtime CLAMP state

Ch402 extends the accepted Ch401 56-draw scene with twelve authentic draws from the character family, each in its own epoch. These draws use GS region clamp mode 2 with exact full-texture bounds (MINU/MINV=0, MAXU/MAXV=511). For a 512x512 texture that state is mathematically identical to ordinary clamp, so the fixture generator proves those bounds and normalizes only the mode bits. Any other region-clamp bounds continue to fail closed.

The feeder format is backward-compatible. Legacy lists retain the seven-word header. Extended lists advertise word 8 with count-word bit 34 and emit CLAMP_1 between TEX0_1 and PRIM. A focused feeder regression proves both formats and the new vertex base.

An initial four-epoch grouping required 2,294 to 3,410 staging words and doubled the allocated RAM. Although functionally exact in simulation, that placement pressure moved the previously marginal color-address FIFO family to -0.233 ns. Ch402 therefore uses twelve single-draw character epochs, retains the accepted 2,048-word staging allocation, and raises only the software epoch-table ceiling from 32 to 64.

Simulation

  • 68 authentic draws in 40 ordered epochs
  • 649,189 fragments fed
  • 332,984 fragments passed Z
  • 40 fresh ordered drains
  • zero request drops, color FIFO overflows, or AXI BRESP errors
  • Z mismatches: 0 / 307,200
  • color mismatches: 0 / 131,618
  • reference coverage: 131,830 pixels
  • largest staging list: 1,844 / 2,048 words
  • maximum measured request FIFO high-water: 1,753 / 4,096
  • simulated framebuffer MEM SHA-256: d3a211671a444991e8032c97d3ba16c66621de1e9d3ad1432442bdb8be585010
  • simulated framebuffer PNG SHA-256: ae1b8fbdf1748723eede478d4ca349245920c32836df94cdf076cc6b983047b6

The simulated image now includes the central character silhouette and reaches the bottom of the 640x480 frame. It remains visibly short of the PCSX2 image in lighting, fog/compositing, and precision; Ch402 closes the missing-character state/capacity blocker, not the remaining fidelity debt.

Timing gate

The first owner GUI fit used a 4,096-word staging allocation. It fit at 291 RAM blocks but failed setup at -0.233 ns / -1.287 ns TNS on the known u_zc_emit|ca_tail/ca_head -> ca_mem family; hold remained clean. The failure was a placement regression rather than a new logical path through the feeder. The 40-epoch repartition removes the seven added RAM blocks and restores the accepted 2,048-word allocation. The follow-up owner GUI fit recovered timing at +0.041 ns setup / 0.000 TNS; hold remained clean. It used 37,279 / 46,800 ALMs and restored RAM usage to 284 / 358 blocks.

Silicon

The timing-clean RBF (SHA-256 a7691ff9203bc1a9097da88f0a341f6c14ed96910bb2d6f3fb46349e02b0fcce) was hash-verified on the board and loaded through core_loader.sh; fpga0 reported operating.

All 40 epochs passed texture/CLUT CRC, staging count, record count, ordered drain, and zero-drop gates with rc=0.

  • nonzero pixels: 131,618
  • bounds: (36,10)..(599,463)
  • board/simulation MEM SHA-256: d3a211671a444991e8032c97d3ba16c66621de1e9d3ad1432442bdb8be585010
  • board/simulation PNG SHA-256: ae1b8fbdf1748723eede478d4ca349245920c32836df94cdf076cc6b983047b6

Board and simulation are byte-exact over all 307,200 framebuffer words. Ch402 is accepted on silicon and remains displayed through the LPDDR HDMI scanout.