Files
retroDE_ps2/tools/report_zsched_issue_uv.py
thejayman77 ba74bbd5aa 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>
2026-07-20 19:56:46 -04:00

105 lines
3.1 KiB
Python

#!/usr/bin/env python3
"""Compact ZSCHED trace-vs-model summary.
Use after tb_top_psmct32_sh3_zsched regenerates sim/traces/rtl/zsched_*.txt.
It compares the current feeder-derived fixed-point model against the RTL issue
and fragment traces, split by epoch.
"""
import contextlib
import io
import os
import sys
HERE = os.path.dirname(os.path.abspath(__file__))
ROOT = os.path.normpath(os.path.join(HERE, ".."))
sys.path.insert(0, HERE)
with contextlib.redirect_stdout(io.StringIO()):
import diagnose_zsched_persp as D
def load_frags(path):
out = []
with open(path) as f:
for ln in f:
p = ln.split()
if len(p) >= 5:
out.append((int(p[0]), int(p[1]), int(p[2]), int(p[3]), int(p[4], 16) & 0xFFFFFF))
return out
def load_issue(path):
out = []
with open(path) as f:
for ln in f:
p = ln.split()
if len(p) >= 7:
out.append((int(p[0]), int(p[1]), int(p[2]), int(p[3]), int(p[4]), int(p[5]), int(p[6])))
return out
def pct(ok, n):
return 100.0 * ok / n if n else 0.0
def main(argv):
trace_dir = os.path.join(ROOT, "sim", "traces", "rtl")
frag_path = argv[1] if len(argv) > 1 else os.path.join(trace_dir, "zsched_frags.txt")
issue_path = argv[2] if len(argv) > 2 else os.path.join(trace_dir, "zsched_issue.txt")
with contextlib.redirect_stdout(io.StringIO()):
_draw_idxs, _tris, _fb, _owner, _emitted, _accepted, model = D.render("zsched")
frags = load_frags(frag_path)
issue = load_issue(issue_path)
n = min(len(model), len(frags), len(issue))
by_ep = {}
coord_miss = z_miss = 0
for i in range(n):
me = model[i]
hwf = frags[i]
hwi = issue[i]
ep = hwf[0]
st = by_ep.setdefault(ep, {
"n": 0, "color": 0, "u": 0, "v": 0, "uv": 0,
"u_ge512": 0, "v_ge512": 0,
})
st["n"] += 1
if me[:3] != hwf[:3]:
coord_miss += 1
if abs(me[3] - hwf[3]) > 256:
z_miss += 1
if (me[4] & 0xFFFFFF) != hwf[4]:
st["color"] += 1
if me[5] != hwi[4]:
st["u"] += 1
if me[6] != hwi[5]:
st["v"] += 1
if me[5] != hwi[4] or me[6] != hwi[5]:
st["uv"] += 1
if hwi[4] >= 512:
st["u_ge512"] += 1
if hwi[5] >= 512:
st["v_ge512"] += 1
print(f"[uv] model={len(model)} frags={len(frags)} issue={len(issue)} compared={n} coord_miss={coord_miss} z_gt256={z_miss}")
for ep in sorted(by_ep):
st = by_ep[ep]
n_ep = st["n"]
u_ok = n_ep - st["u"]
v_ok = n_ep - st["v"]
uv_ok = n_ep - st["uv"]
c_ok = n_ep - st["color"]
print(
f"[uv] e{ep}: n={n_ep} "
f"color_ok={c_ok}/{n_ep} ({pct(c_ok,n_ep):.2f}%) "
f"u_ok={u_ok}/{n_ep} ({pct(u_ok,n_ep):.2f}%) "
f"v_ok={v_ok}/{n_ep} ({pct(v_ok,n_ep):.2f}%) "
f"uv_ok={uv_ok}/{n_ep} ({pct(uv_ok,n_ep):.2f}%) "
f"rtl_u_ge512={st['u_ge512']} rtl_v_ge512={st['v_ge512']}"
)
if __name__ == "__main__":
raise SystemExit(main(sys.argv))