ba74bbd5aa
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>
86 lines
3.6 KiB
Markdown
86 lines
3.6 KiB
Markdown
# Ch418 — authentic SH3 display presentation mapping (prefit)
|
|
|
|
## Objective
|
|
|
|
Fix the large presentation mismatch between the accepted Ch417 framebuffer and
|
|
the PCSX2 224139 frame without changing any rasterized framebuffer byte. Ch418
|
|
is scanout-only: it maps the captured GS display source onto the board's
|
|
640x480 HDMI/VGA active raster.
|
|
|
|
## Captured register evidence
|
|
|
|
The vendored PCSX2 `GSPrivRegSet` layout was used to decode the initial and all
|
|
eight per-vsync register snapshots in dump 224139. The active context is
|
|
DISPLAY2 (`PMODE.EN2=1`), stable in every snapshot:
|
|
|
|
- `DISPFB2 = 0x0001000000009000` (FBP rotates later), `FBW=8`, `PSM=1`,
|
|
`DBX=0`, `DBY=32`;
|
|
- `DISPLAY2 = 0x0037f9ff0203228c`, `DX=652`, `DY=50`, `MAGH=4`,
|
|
`MAGV=0`, `DW=2559`, `DH=895`.
|
|
|
|
Therefore the display source is 512 pixels wide (`FBW*64`) and 448 interlaced
|
|
source lines beginning at framebuffer line 32. DISPLAY2 expands each source
|
|
pixel to five VCKs (`MAGH+1`) across 2560 display clocks. Reducing that
|
|
captured display to the board raster gives the exact integer maps:
|
|
|
|
```
|
|
source_x = floor(output_x * 4 / 5) // 0..639 -> 0..511
|
|
source_y = 32 + floor(output_y * 14 / 15) // 0..479 -> 32..479
|
|
```
|
|
|
|
## RTL change
|
|
|
|
`gs_lpddr_scanout_lb` now has opt-in divider-free presentation mapping:
|
|
|
|
- a five-state horizontal phase accumulator implements 512 -> 640;
|
|
- a fifteen-state vertical phase accumulator implements 448 -> 480;
|
|
- vertical prefetch starts at captured `DBY=32`;
|
|
- buffer parity, prefetch throttling, and underflow checks use mapped source y;
|
|
- all default parameters retain the legacy 1:1 behavior.
|
|
|
|
Only `GS_SH3_LPDDR_FB_640` enables the mapping in the DE25 top. The OSD remains
|
|
in the 640x480 output domain and the LPDDR framebuffer/dump remains byte-exact
|
|
to Ch417.
|
|
|
|
The mapper contains no `/` or variable multiply in synthesizable RTL. Its
|
|
datapath is one small phase decrement and one coordinate increment per output
|
|
pixel/line, both in the 25 MHz video domain.
|
|
|
|
## Prefit verification
|
|
|
|
- New two-axis scanout oracle: 600/600 RGB pixels exact, including horizontal
|
|
repeats, vertical repeats, DBY offset, alternating line buffers, zero
|
|
underflow, and zero AXI read errors.
|
|
- Legacy PSMCT16 line-buffer regression: PASS, underflow=0, read errors=0.
|
|
- Legacy PSMCT32 line-buffer/concurrency regression: 49,152 pixels exact,
|
|
underflow=0, read errors=0, 325/325 probes good.
|
|
- The actual QSF profile macros plus `USE_QSYS_TOP` elaborate cleanly under
|
|
Icarus (unavailable vendor IP treated as black boxes); no RTL binding or
|
|
syntax errors.
|
|
- `git diff --check` and the preview utility's Python compile pass.
|
|
|
|
Expected HDMI preview:
|
|
|
|
`sim/data/top_psmct32_raster_demo/sh3_zsrt139f17_ch418_scanout.png`
|
|
|
|
Preview SHA-256:
|
|
|
|
`b710aa7a09db6992faacdaa5a6257d490f1d4fa0112f6c6d20fc388f4b580a63`
|
|
|
|
The preview moves the already-rendered lamppost and character onto the PCSX2
|
|
landmark positions. Full-frame RGB MAE rises from 20.12 to 21.02 because the
|
|
board is still missing large bright/background draws that the transform now
|
|
spreads over more output pixels; that global statistic is a coverage metric at
|
|
this stage, not an alignment metric. The mapping is justified by the captured
|
|
registers and visible landmark alignment, not by claiming a false MAE win.
|
|
|
|
## Owner fit gate
|
|
|
|
Ready for the owner-controlled Quartus 26.1 GUI compile. Required acceptance:
|
|
|
|
- Analysis & Synthesis succeeds with no inferred display divider;
|
|
- setup, hold, recovery, removal, and minimum pulse all close;
|
|
- after deployment, the unchanged 263-epoch board run still passes and the
|
|
framebuffer dump remains byte-identical to Ch417;
|
|
- HDMI shows the 512x448 captured source presented across 640x480.
|