# Ch354 audit log — draw-list expansion: multiple SH3 draws composited into one LPDDR framebuffer

Purpose: auditable trail for Codex. Builds directly on Ch353 (the LPDDR-only PSMCT32 framebuffer, silicon-verified).
Brick 1 scope (Codex, conservative): the SAME-TEXTURE trio idx89548/89761/89974 (tbp=9216/cbp=13952, frame f1)
composited into one FB — ONE new variable: multiple authentic draws accumulating into one LPDDR framebuffer. NOT in
Brick 1: multi-texture residency, full 640x480, large Z-buffer.

## Fixture generator (tools/gs_make_sh3_multidraw_fixture.py) — all guardrails fail-CLOSED
- #4 mechanical: the trio is one frame (f1), one texture key (9216,0x13,8,TRI_STRIP,tme=1,abe=0), ascending dump order.
- #2 ALL feeder-visible state identical: TEX0(all fields), PRIM/fst/tme/abe, TEST, ZBUF, CLAMP, ALPHA, TEXA.
- #3 CONTENT (epoch-aware): texture @tbp=9216 (256 KB) + CLUT @cbp=13952 (1 KB) byte-identical across all three
  (per-draw local-memory reconstruction; a same-byte re-upload passes, a changed payload FAILS).
- #1 capacity: 204 clipped tris -> 1843 staging words. Correctly fail-closed at 768; Codex approved FEEDER_STG_WORDS
  =2048 (16-bit tri count + 12-bit staging addr cover it). Feeder .mem padded to 2048.
- #3 union bbox: origin (243,52), 248x338 -> FB 256x338, stride 1024B, size 0x54800 (338 KiB).
- #5 INDEPENDENT oracle from reconstructed GS local memory (not feeder records); #6 overlap scored: 10370 overlap px.

## Integration sim (tb_top_psmct32_sh3_multidraw) — PASS on the accumulation acceptance
Combined list through the SAME Ch353 LPDDR-FB path (FEEDER_AUTOSTART=0 + render-epoch EOF + frame_drained hard gate +
line-buffer scanout). PASS: records_emitted=204, ONE frame_drained after all batches, writer overflow/BRESP=0,
raster_overflow=0, scanout 256x338 = 10816 beats/frame exact, underflow=0, transport exact, clut_bad=0, overlap
exercised (10370 px). Fidelity is REPORTED, not gated (Codex: not part of accumulation acceptance).

## Codex diagnostic branch — RESOLVED (two SEPARATE claims)
Isolation + per-draw + RTL-composition (tool --tag/--only/owner-map; TB +TAG/+FBDUMP; scratch compose_check.py):
- **89761 isolated through the new path: INTERIOR 97.5%** == Ch353's 97.6% -> the multidraw tool/origin translation
  is CORRECT (not the source of the drop).
- Per-draw <=1-texel INTERIOR: 89761=97.5%, 89548=95.6%, 89974=93.2% (draw-dependent).
- **RTL-paint-order composition: combined RTL == overlay of the three isolated single RTL renders, 0/86528 px differ.**

**CLAIM 1 (accumulation/order/coalescing): bit-exact — 0/86528 px different from RTL-composed singles.**
**CLAIM 2 (authentic-reference fidelity): draw-dependent (97.5/95.6/93.2%), the EXISTING perspective-sampling
fidelity limitation — NOT part of the accumulation acceptance, NOT independently attributed to the reciprocal curve.**
The combined interior (94.4%) is the coverage-weighted mix; the overlap region is dominated by the least-accurate
draw (89974 owns the most covered pixels), which is why OVERLAP-INTERIOR looks lowest.

## Board prep (Codex-directed) — verified in sim, owner-gated for the fit
- Board top: `GS_SH3_LPDDR_FB_MULTI` overrides FEEDER_STG_WORDS 768->2048 and SCANOUT_LB_NROWS 334->338; everything
  else shared with GS_SH3_LPDDR_FB. Elaborates clean (exit 0) under GS_SH3_LPDDR_FB+_MULTI+GS_LPDDR4B_FB+GS_LPDDR_TEX.
- Framebuffer 256x338, stride 1024, size 0x54800; scanout 10816 beats/frame.
- Host ps2_sh3_tex_upload.c: `--fb-rows N` -> preclears the exact 256xN range (338 => 0..0x54800). -Wall clean.
- frame_drained diagnostic (0x02C[6], Ch353 follow-up) is BUNDLED into this fit.
- Build profile `sh3_lpddr_fb_multi` (select_de25_profile.sh + QSF): SCENE GS_SH3_LPDDR_FB + GS_SH3_LPDDR_FB_MULTI +
  GS_LPDDR_TEX + feeder_sh3_multi; FIXTURE bios/payload_sh3_multi. Ran profile-select + verified the QSF.
- BOARD RUN: `sudo ./ps2_sh3_tex_upload sh3_real_tex_lpddr.mem --lpddr-fb --fb-rows 338`.
