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
+16 -8
View File
@@ -29,10 +29,10 @@ def f32(bits):
PRIMT = {0:"POINT",1:"LINE",2:"LINE_STRIP",3:"TRIANGLE",4:"TRI_STRIP",5:"TRI_FAN",6:"SPRITE",7:"INVALID"}
VERTS_PER = {0:1,1:2,2:2,3:3,4:3,5:3,6:2,7:0} # min verts to kick a primitive
def census(dump, frame_filter=None, min_prims=1, collected=None):
def census(dump, frame_filter=None, min_prims=1, collected=None, include_untextured=False):
d, h, events, uploads, runs, vram = collected if collected is not None else R.collect(dump, 0)
# live GS state we latch as we walk
prim = dict(type=7, tme=0, fst=0, abe=0, ctxt=0)
prim = dict(type=7, tme=0, fge=0, fst=0, abe=0, ctxt=0)
tex0 = {1:None, 2:None}
ofx = {1:0.0, 2:0.0}; ofy = {1:0.0, 2:0.0}
cur_st = (0.0, 0.0, 1.0) # S, T, Q
@@ -72,7 +72,8 @@ def census(dump, frame_filter=None, min_prims=1, collected=None):
r, v = e.reg, e.value
if r == "PRIM":
close()
prim = dict(type=v&7, tme=(v>>4)&1, fst=(v>>8)&1, abe=(v>>6)&1, ctxt=(v>>9)&1)
prim = dict(type=v&7, tme=(v>>4)&1, fge=(v>>5)&1,
fst=(v>>8)&1, abe=(v>>6)&1, ctxt=(v>>9)&1)
vqueue = []
elif r == "PRMODE": # PRIM-less prim mode (rare); ignore topology change w/o reset
pass
@@ -94,13 +95,14 @@ def census(dump, frame_filter=None, min_prims=1, collected=None):
z = (v>>32) & 0xFFFFFF
else:
z = (v>>32) & 0xFFFFFFFF
if not prim["tme"]: # only textured draws are Ch349 candidates
fogv = ((v>>56) & 0xFF) if r in ("XYZF2","XYZF3") else 255
if not prim["tme"] and not include_untextured:
continue
if newkey() is None:
continue
if cur is None or cur["key"] != newkey():
close(); open_draw()
vtx = dict(x=x, y=y, z=z, s=cur_st[0], t=cur_st[1], q=cur_st[2], rgba=cur_rgba)
vtx = dict(x=x, y=y, z=z, fog=fogv, s=cur_st[0], t=cur_st[1], q=cur_st[2], rgba=cur_rgba)
cur["verts"].append(vtx); cur["nvert"] += 1
cur["nprim"] += 1 # each kick completes one primitive in fan/strip/list
cur["xmin"]=min(cur["xmin"],x); cur["xmax"]=max(cur["xmax"],x)
@@ -119,9 +121,10 @@ def census(dump, frame_filter=None, min_prims=1, collected=None):
if dr["nprim"] < min_prims: continue
if frame_filter is not None and dr["frame"] != frame_filter: continue
t0 = dr["tex0"]
snap = R.snapshot_present(vram, t0["tbp"], nb=512)
snap = (True if not dr["prim"]["tme"] else
R.snapshot_present(vram, t0["tbp"], nb=512))
clut = None
if t0["psm"] in R.INDEXED_PSMS:
if dr["prim"]["tme"] and t0["psm"] in R.INDEXED_PSMS:
csnap = R.snapshot_present(vram, t0["cbp"], nb=1024, min_nz=64)
clut = dict(cbp=t0["cbp"], cpsm=t0["cpsm"], cld=t0["cld"], resident=bool(csnap),
distinct=(csnap["distinct"] if csnap else None))
@@ -156,6 +159,10 @@ def _score(dr):
rectangle in perspective. Reward on-screen containment + sampled-texel span, NOT guard-band area."""
t0 = dr["tex0"]
s = 0.0
if not dr["prim"]["tme"]:
return (100.0 * dr["onscreen_frac"] +
min(dr["onscreen_area"]/200.0,120.0) +
min(dr["nprim"],48))
if not dr["tex_resident"]: return -1.0 # must be reconstructable
if t0["psm"] in R.INDEXED_PSMS:
if dr["clut"] and dr["clut"]["resident"]: s += 40.0 # indexed + resident CLUT == the real SH3 path
@@ -204,7 +211,8 @@ def main(argv):
def opt(n, dv=None): return argv[argv.index(n)+1] if n in argv else dv
top = int(opt("--top","25")); minp = int(opt("--min-prims","1"))
ff = int(opt("--frame")) if "--frame" in argv else None
draws, h, vram = census(dump, frame_filter=ff, min_prims=minp)
draws, h, vram = census(dump, frame_filter=ff, min_prims=minp,
include_untextured="--include-untextured" in argv)
print(f"# Ch349 draw census: {os.path.basename(dump)}")
print(f"# textured draws (>= {minp} prim): {len(draws)} vram_snapshot={'present' if vram is not None else 'ABSENT'}")
cand = [d for d in draws if d["score"] > 0]