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>
This commit is contained in:
@@ -0,0 +1,153 @@
|
||||
# Ch417 — native 12.4 attribute gradients
|
||||
|
||||
## Objective
|
||||
|
||||
Close the main fidelity debt left by Ch416: coverage already samples native
|
||||
12.4 GS screen coordinates at pixel centers, but color, Z, UV, and STQ planes
|
||||
were still solved from integer vertex coordinates. This chapter makes the
|
||||
attribute setup and evaluation use the same native geometry as coverage while
|
||||
leaving draw population, texture state, blending, fog, and ordering unchanged.
|
||||
|
||||
## RTL cut
|
||||
|
||||
- Triangle orientation and the post-swap gradient determinant now use the full
|
||||
12.4 vertex coordinates. Coordinate deltas are signed 17-bit values and the
|
||||
determinant is signed 35-bit.
|
||||
- The shared gradient numerators are signed 64-bit. Because the determinant is
|
||||
in sixteenths-of-a-pixel squared, the numerator is shifted by 20 rather than
|
||||
16 to produce the existing Q16.16 per-pixel gradient.
|
||||
- The gradient FIFO sideband retains the full 35-bit determinant through the
|
||||
time-shared setup engine and its single sequential divider.
|
||||
- Color, Z, affine UV, and perspective STQ evaluation now use the native
|
||||
pixel-center offset `((pixel << 4) + 8) - vertex12.4`. Products are shifted
|
||||
by 20 to return to the existing attribute domains.
|
||||
- Affine UV filtering consumes the resulting Q16.16 fractional texel bits.
|
||||
This keeps bilinear sampling aligned with the corrected attribute plane.
|
||||
|
||||
Two correctness defects exposed by the new directed tests were repaired in
|
||||
the same path:
|
||||
|
||||
- The packed attribute-prefetch word was missing the LPDDR ABE bit in its
|
||||
unpack destination. Every following field was consequently displaced by
|
||||
one bit, including the vertex-coordinate context. The unpack now includes
|
||||
`gw_d_lpddr_abe` and exactly matches the stored word width.
|
||||
- The opaque affine fragment-Z output retained the reset value instead of the
|
||||
interpolated triangle Z. The emit sideband now selects `s2_interp_z` for an
|
||||
active affine triangle and retains the flat sprite value otherwise.
|
||||
|
||||
## Directed evidence
|
||||
|
||||
- Legacy raster regression: 16/16 pixels PASS.
|
||||
- New native-gradient triangle at `(0.75,0.75)`, `(3.75,0.75)`, and
|
||||
`(0.75,3.75)`: exact R values 72/104/136 and exact Z values
|
||||
1225/1325/1425 at the three covered pixel centers.
|
||||
- Triangle interpolation regression: 31 interior color samples within the
|
||||
established tolerance and 62 exact Z checks, PASS.
|
||||
- Shared gradient divider regression: PASS.
|
||||
- Affine textured triangle: 31/31 UV texels exact, PASS.
|
||||
- Perspective PSMCT32 demo: 96/96 samples exact, PASS.
|
||||
- Combined texture/alpha/Z demo: PASS.
|
||||
- PSMT8 runtime-CLUT triangle: affine, perspective, ABE, and MODULATE paths
|
||||
PASS.
|
||||
- Authentic three-epoch integration: 5,909 fragments fed, 5,909 Z-passing,
|
||||
zero drops, 0/307,200 final Z mismatches, and 0/5,858 color mismatches. The
|
||||
corrected affine Z sideband admits two fragments that Ch416 rejected.
|
||||
|
||||
## Full-scene simulation gate
|
||||
|
||||
The 263-epoch scene uses the same bit-exact divide arithmetic as production.
|
||||
`SH3_FAST_GRAD` selects a one-cycle setup path for quick framebuffer iteration;
|
||||
the final pre-fit gate uses `SH3_BOARD_GRAD`, the production combinational
|
||||
divider and its five-cycle registered settle window. The widened 64/35-bit
|
||||
divide therefore has a 200 ns functional and STA contract at 25 MHz. The
|
||||
sequential-divider implementation also passes its focused regression.
|
||||
|
||||
The full chronological gate passes:
|
||||
|
||||
- 1,145,412 fragments fed and 971,347 Z-passing;
|
||||
- zero fragment drops, request-FIFO high-water mark 1, no color overflow, and
|
||||
no AXI response errors;
|
||||
- 263 markers and 263 ordered read drains (the first drain begins from the
|
||||
reset frame, hence 262 frame-count advances);
|
||||
- 0/307,200 final Z mismatches and 0/235,951 written-color mismatches.
|
||||
|
||||
The dedicated production-control rerun also passes all 263 epochs with
|
||||
`GRAD_SEQ_DIVIDER=0` and `GRAD_DIV_CYCLES=5`: the same 1,145,412 fed /
|
||||
971,347 passing fragments, zero drops, request-FIFO high-water 1, all 263
|
||||
ordered drains, and exact final Z/color. Its framebuffer is byte-identical to
|
||||
the fast arithmetic run (`3d22b442...`), proving that the five-cycle settle FSM
|
||||
changes latency only.
|
||||
|
||||
The focused production board-path regression was corrected in Ch417: its old
|
||||
`GRAD_BOARDPATH` branch accidentally selected the sequential divider. It now
|
||||
selects the actual board combinational divider at five cycles and passes all
|
||||
252/252 interior perspective samples with zero errors. The directed subpixel
|
||||
gradient test also runs at five cycles and passes exact R/Z checks; its timeout
|
||||
is derived from the 14-step gradient setup latency rather than a fixed delay.
|
||||
|
||||
The first owner Analysis & Synthesis attempt exposed a Quartus-specific width
|
||||
limit before fitting: signed `64/64` inference prepended a sign-magnitude bit
|
||||
and requested unsupported `LPM_WIDTHN=65` (Error 272006). Ch417b now divides
|
||||
an explicitly unsigned 64-bit numerator magnitude by the native unsigned
|
||||
35-bit determinant magnitude and restores the quotient sign afterward. This
|
||||
retains signed truncation-toward-zero exactly while fixing the inferred LPM at
|
||||
64/35. All focused gates and the complete 263-epoch production-control gate
|
||||
were rerun after this change; the framebuffer remains byte-identical at
|
||||
`3d22b442...`.
|
||||
|
||||
The compiled Verilator run completed the full gate. The original Icarus run
|
||||
independently matched every count through epoch 59 before it was retired after
|
||||
the faster run passed, including the first Z-rejecting epochs. The two engines
|
||||
therefore agree across both the all-pass prefix and mixed pass/reject behavior.
|
||||
|
||||
The Ch417 framebuffer improves against the bilinearly resized PCSX2 reference
|
||||
from Ch416 MAE 20.4941 / RMSE 30.0163 to MAE 20.1177 / RMSE 29.4268. Lit RGB
|
||||
pixels rise from 199,104 to 199,827. Ch417 versus Ch416 measures MAE 2.9100 /
|
||||
RMSE 9.4742, with 135,574 pixels unchanged exactly.
|
||||
|
||||
Artifact SHA-256 identities:
|
||||
|
||||
- Ch417 RTL framebuffer MEM:
|
||||
`3d22b4421194d444677f3bc9f938e43fd856c6615b92585a10209093d982a625`;
|
||||
- Ch417 RTL framebuffer PNG:
|
||||
`b55b411cc5f6679e6a1ed708ef21ad5eaf5750abb233c6e433ab03594ec9c01e`.
|
||||
|
||||
## Owner fit gate
|
||||
|
||||
The owner-controlled Quartus 26.1 GUI flow completed successfully at
|
||||
2026-07-18 07:21 EDT. Synthesis confirms that the repaired divider is exactly
|
||||
the intended unsigned `LPM_WIDTHN=64`, `LPM_WIDTHD=35`, with no pipeline
|
||||
inserted. Final STA attached the Ch417 setup=5/hold=4 destination constraint
|
||||
to 49 routed `grad_result_q` registers (including retimed internal divider
|
||||
launches), giving the widened cone its 200 ns functional contract.
|
||||
|
||||
Final signoff is clean:
|
||||
|
||||
- setup +0.140 ns;
|
||||
- hold 0.000 ns;
|
||||
- recovery +0.998 ns;
|
||||
- removal +0.143 ns;
|
||||
- minimum pulse width +0.200 ns.
|
||||
|
||||
The fit uses 38,461 / 46,800 ALMs (82%), 5,261,744 / 7,331,840 memory bits
|
||||
(72%), 336 / 358 RAM blocks (94%), and 160 / 376 DSP blocks (43%). The split
|
||||
RBF SHA-256 is
|
||||
`ef0ecc585b6e0506f30f56bbea44ba56023a305e9d22052877b0e51b1b65e643`.
|
||||
|
||||
## Board acceptance
|
||||
|
||||
The timing-clean RBF was installed and loaded on the Terasic board; the FPGA
|
||||
manager reported `operating` before and after the run. The previous installed
|
||||
image was preserved remotely as `retroDE_ps2.pre_ch417b.core.rbf`.
|
||||
|
||||
The live 263-epoch scheduler completed with `rc=0`. Every texture CRC,
|
||||
runtime-palette sum, staging-record count, ordered drain, AXI response, and
|
||||
fragment-drop gate passed. The final capture contains 307,200 words, sum32
|
||||
`0xc552c256`, xor32 `0x90a0ec16`, 235,280 nonzero words, and bounds
|
||||
`(0,0)..(511,479)`.
|
||||
|
||||
Most importantly, the board framebuffer, fast RTL framebuffer, and complete
|
||||
five-cycle production-control framebuffer are byte-for-byte identical. All
|
||||
three have SHA-256
|
||||
`3d22b4421194d444677f3bc9f938e43fd856c6615b92585a10209093d982a625`.
|
||||
Ch417 is therefore accepted in hardware.
|
||||
Reference in New Issue
Block a user