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:
2026-07-20 19:56:46 -04:00
parent ec82764bef
commit ba74bbd5aa
476 changed files with 696247 additions and 130119 deletions
+17 -10
View File
@@ -80,10 +80,15 @@ def tex0_real(tbp, cbp):
return v
def main(argv):
global CH # Ch353 — full-frame mode reassigns the FB height
dump = None; draw_idx = 89761
a = argv[1:]
if a and not a[0].startswith("--"): dump = a[0]
if "--draw-idx" in a: draw_idx = int(a[a.index("--draw-idx")+1])
# Ch353 — --full-frame renders the WHOLE 256xfull_h draw bounding box (no crop) for the LPDDR framebuffer.
# Crop-dependent outputs are written with a `full` tag so the Ch352 cropped build (sh3_real_*) is untouched.
full_frame = "--full-frame" in a
tag = "full" if full_frame else "real"
if dump is None:
c = glob.glob(os.path.join(ROOT,"captures","gs","silenthill3","*224139*.gs.zst"))
if not c: sys.exit("no SH3 dump found; pass the .gs.zst path")
@@ -132,6 +137,8 @@ def main(argv):
s = sum(row_cov[cy0:cy0+CH])
if s > best_sum: best_sum, best_cy0 = s, cy0
CY0 = best_cy0; CX0 = 0
if full_frame:
CH = full_h; CY0 = 0; CX0 = 0 # Ch353 full-frame: render the whole 256xfull_h bounding box (no crop)
# apply the viewport crop: shift Y by -CY0 (ST/Q UNCHANGED — only the framebuffer window moves), then
# CLIP each triangle to the crop rect [0,FBPXW]x[0,CH] (Sutherland-Hodgman, interpolating S/T/Q linearly in
# screen space — correct since S,T,Q are already premultiplied by 1/w). This is the VIEWPORT scissor done at
@@ -274,17 +281,17 @@ def main(argv):
covered = sum(1 for w in refmap if w>>31)
print(f"[Ch350] host reference: {covered} covered FB pixels")
# emit the RTL-faithful refmap + PNG for the Ch351 oracle
with open(os.path.join(DATA,"sh3_real_refmap_recip.mem"),"w") as f:
with open(os.path.join(DATA,f"sh3_{tag}_refmap_recip.mem"),"w") as f:
f.write("// Ch351 RTL-faithful (8-bit reciprocal) per-pixel texel map. gitignored.\n")
for x in refmap_rec: f.write(f"{x & 0xFFFFFFFF:08x}\n")
with open(os.path.join(DATA,"sh3_real_refmap_affine.mem"),"w") as f:
with open(os.path.join(DATA,f"sh3_{tag}_refmap_affine.mem"),"w") as f:
f.write("// Ch351 AFFINE (per-vertex texel, linear interp) per-pixel texel map. gitignored.\n")
for x in refmap_aff: f.write(f"{x & 0xFFFFFFFF:08x}\n")
try:
from PIL import Image
Image.new("RGB",(FBPXW,CH)).copy() # noop guard
im2=Image.new("RGB",(FBPXW,CH)); im2.putdata(refpix_rec)
im2.save(os.path.join(ROOT,"captures","gs","silenthill3","extracted","recon","sh3_real_ref_recip.png"))
im2.save(os.path.join(ROOT,"captures","gs","silenthill3","extracted","recon",f"STALE_idx8_sh3_{tag}_ref_recip.png"))
except Exception as e:
print("(PIL skip recip png:", e, ")")
@@ -308,12 +315,12 @@ def main(argv):
pay.append(word)
qwc=len(pay)
disp_hi=((CH-1)<<12)|(FBPXW-1)
with open(os.path.join(DATA,"payload_sh3_real.mem"),"w") as f:
with open(os.path.join(DATA,f"payload_sh3_{tag}.mem"),"w") as f:
f.write(f"// Ch352 LOCAL SH3 real-draw setup payload (CSM1 CLUT 256x1 -> CBP={CBP}, grid bytes verbatim). gitignored. QWC={qwc}.\n")
for _ in range(16): f.write(f"{0:032x}\n")
for x in pay: f.write(f"{x&((1<<128)-1):032x}\n")
for _ in range(RAM_QWORDS-16-qwc): f.write(f"{0:032x}\n")
bake.write_bios_mem("bios_sh3_real.mem",
bake.write_bios_mem(f"bios_sh3_{tag}.mem",
bake.build_textured_demo_bootlet_disp(qwc, disp_hi, FBW),
f"Ch352 LOCAL SH3 real-draw setup bootlet (QWC={qwc}, DISPLAY1={FBPXW}x{CH}). gitignored.")
print(f"[Ch352] setup bootlet: payload {qwc} qw (CSM1 CLUT 256x1 upload to CBP={CBP}).")
@@ -345,12 +352,12 @@ def main(argv):
# de-gridded palette pal[i] (what the HW CSM1 grid-read produces) -> TB reference expected colors
wmem("sh3_real_pal.mem", [p & 0xFFFFFFFF for p in pal], 8,
"Ch350 LOCAL SH3 de-gridded palette pal[i] (grid-read of the CBP bytes) for the TB reference. gitignored.")
bake.write_feeder_stg_mem("feeder_sh3_real.mem", stg,
bake.write_feeder_stg_mem(f"feeder_sh3_{tag}.mem", stg,
"Ch350 LOCAL SH3 REAL draw (idx89761) feeder staging: triangle list + TEX0(PSMT8,CSM1,CLD=1,DECAL). gitignored.",
total=STG_WORDS)
wmem("sh3_real_refmap.mem", refmap, 8, "Ch350 LOCAL per-FB-pixel covered|interior|tu|tv reference map. gitignored.")
wmem(f"sh3_{tag}_refmap.mem", refmap, 8, "Ch350 LOCAL per-FB-pixel covered|interior|tu|tv reference map. gitignored.")
# params include for the TB
with open(os.path.join(DATA,"sh3_real_params.vh"),"w") as f:
with open(os.path.join(DATA,f"sh3_{tag}_params.vh"),"w") as f:
f.write("// Ch350 LOCAL generated params for tb_top_psmct32_sh3_real_draw_demo. gitignored.\n")
f.write(f"localparam int FBW = {FBW};\n")
f.write(f"localparam int FBPXW = {FBPXW};\n")
@@ -371,8 +378,8 @@ def main(argv):
try:
from PIL import Image
im=Image.new("RGB",(FBPXW,CH)); im.putdata(refpix)
im.save(os.path.join(ROOT,"captures","gs","silenthill3","extracted","recon","sh3_real_ref.png"))
print("[Ch350] wrote sh3_real_ref.png")
im.save(os.path.join(ROOT,"captures","gs","silenthill3","extracted","recon",f"sh3_{tag}_ref.png"))
print(f"[Ch350] wrote sh3_{tag}_ref.png")
except Exception as e:
print("(PIL skipped:", e, ")")
print(f"[Ch350] emitted fixtures -> {DATA} (LOCAL). TEX_VRAM_BASE=0x{TEX_VRAM_BASE:x} TBP={NEW_TBP} CBP={CBP} "