[iterate-4A] docs: handoff for intro-video-done milestone + speed frontier
HANDOFF-intro-video-done.md: what to push/copy, the 6 branch commits, build/run, root-cause summary, and the profiled emulator-speed frontier with ranked levers. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
109
HANDOFF-intro-video-done.md
Normal file
109
HANDOFF-intro-video-done.md
Normal file
@@ -0,0 +1,109 @@
|
||||
# Handoff — Intro video SOLVED (`iterate-4A/apu-xma-stage1`, tag `intro-video-done`)
|
||||
|
||||
The original frontier — **why `dat/movie/ADV.wmv` never played** vs Xenia Canary — is **solved**.
|
||||
The intro renders authentically: white SQUARE ENIX logo + cyan glow + red diamonds on a near-black
|
||||
background, correct color / geometry / luminance, playing reliably. This doc is the handoff for that
|
||||
state and the newly-opened **emulator-speed** frontier.
|
||||
|
||||
> Method (unchanged): first-divergence vs canary · fix causes not symptoms · NO masking · measure the
|
||||
> oracle, never infer. Full setup for this branch is in `HANDOFF-iterate-4A-milestone2.md` (FFmpeg dev
|
||||
> libs, DuckDB tooling, etc.) — read that first on a fresh machine.
|
||||
|
||||
---
|
||||
|
||||
## 0. What to push / copy for handoff
|
||||
|
||||
**Git (the only repo):** `xenia-rs/`. Branch `iterate-4A/apu-xma-stage1`, **6 commits ahead of origin**.
|
||||
```bash
|
||||
cd xenia-rs
|
||||
git push origin iterate-4A/apu-xma-stage1 # the 6 commits below
|
||||
git push origin intro-video-done # the annotated milestone tag (-> 5573ac1)
|
||||
```
|
||||
**Not in git (machine-local — copy manually for a full-context handoff):**
|
||||
- `../CLAUDE.md` — project working instructions (project root is NOT a git repo).
|
||||
- `~/.claude/projects/-home-fabi-RE---Project-Sylpheed/memory/` — the auto-memory (`MEMORY.md`
|
||||
index + topic files). This is where the detailed step-by-step history lives.
|
||||
- Large local artifacts (NOT pushed): the real ISO (`sylpheed.iso` symlink target), `sylpheed.db`
|
||||
(DuckDB static-analysis DB, ~1h35m to regenerate — see CLAUDE.md), canary build.
|
||||
|
||||
---
|
||||
|
||||
## 1. Commits on this branch (ahead of origin)
|
||||
|
||||
| Commit | What |
|
||||
|---|---|
|
||||
| `645feb8` | ROOT #1 decode-timeout clock (IPM 10k→1M), #1b feeder starvation (incumbent-pick), #2 `k_8` texture decoder |
|
||||
| `4344152` | re-baseline boot golden 50M→200M after the clock fix |
|
||||
| `3559c8f` | ROOT #3 host render path — multi-texture YUV, tfetch dest-swizzle, PS const-bank +256 |
|
||||
| `deb9292` | RectangleList quad completion (fix diagonal seam) |
|
||||
| `5573ac1` | MULSC/ADDSC/SUBSC scalar-const operand addressing (fix squared-luma) — **tag `intro-video-done`** |
|
||||
| `2c883e9` | diagnostics snapshot: `XENIA_PROFILE` profiler + probe/tooling (this handoff) |
|
||||
|
||||
Working tree is **clean** — all diagnostics/tooling are now committed in `2c883e9`.
|
||||
|
||||
---
|
||||
|
||||
## 2. Build & run (see CLAUDE.md for the authoritative version)
|
||||
|
||||
```bash
|
||||
cd xenia-rs
|
||||
export CARGO_BUILD_JOBS=4 && cargo build --release # ~8s incremental
|
||||
# Headless oracle run (threaded GPU, single-thread CPU lockstep):
|
||||
RUST_LOG=warn ./target/release/xenia-rs exec sylpheed.iso -n 3000000000
|
||||
# Watch the movie (windowed): add --ui ; the first on-screen frame is at ~81s WALL
|
||||
# (mostly boot). Give it >=150s. Boot is DETERMINISTIC; only wall speed varies.
|
||||
```
|
||||
Movie oracles: `sylph-run.sh [runs] [n] [timeout]` (default 180s). Static analysis: `zq.py` over
|
||||
`sylpheed.db` (DECIMAL bounds, never `0x`). Both are committed at repo root now.
|
||||
|
||||
---
|
||||
|
||||
## 3. Root-cause summary (the fixes)
|
||||
|
||||
- **#1 clock deadline** — movie handler `sub_821B4968` has a 2000 ms decode-ready timeout;
|
||||
`INSTRUCTIONS_PER_MS` 10k ran ~320× too fast so a legit 720p decode looked timed-out → abort.
|
||||
Fixed to 1_000_000 (`state.rs`; `XENIA_INSTR_PER_MS` overrides).
|
||||
- **#1b feeder starvation** — co-located feeder tid24 lost the equal-priority rotation;
|
||||
`pick_runnable` now has an incumbent-preference tiebreak (`scheduler.rs`; `XENIA_INCUMBENT_PICK`).
|
||||
- **#2 `k_8` decoder** — the movie uploads YUV planes as linear `k_8`; added `decode_k8`.
|
||||
- **#3 host render path** — multi-texture (8 YUV slots), tfetch 12-bit dest-swizzle, PS constant
|
||||
bank +256 (Xenos splits VS 0..255 / PS 256..511), RectangleList quad synthesis (v3=v0+v2−v1),
|
||||
and MULSC operand addressing (src3, not src_a/src_b). Details: memory topic file STEPs 88→97.
|
||||
|
||||
---
|
||||
|
||||
## 4. Open frontier — emulator SPEED (profiled, not yet worked)
|
||||
|
||||
Playback is slow (~14–19 fps). First quantified profile (`XENIA_PROFILE=1`, headless):
|
||||
|
||||
- Effective **~35 MIPS** overall (3 B guest instr / 86 s clean).
|
||||
- **Interpreter body ~40% @ ~95–102 MIPS**; kernel HLE ~4%; block-cache lookup ~5–6%;
|
||||
**texture decode 0.3% (cache works — not a bottleneck); present ~0%; no default IPS throttle.**
|
||||
- The rest is **per-block dispatch + scheduler plumbing** — ~13 instr/block over ~229 M blocks,
|
||||
each paying fixed prologue/epilogue/lookup/borrow costs. **Overhead-bound, not interpreter-body
|
||||
bound.** (Note: default run is single-thread lockstep `run_superblock`, confirming the
|
||||
"serialized single-core" architecture; the console's 6 HW threads are time-sliced onto one host
|
||||
thread. `--parallel` exists but is not validated for the movie.)
|
||||
|
||||
**Ranked levers:**
|
||||
1. **Coarsen the execution unit — longer superblock chains** (raise `superblock_budget`). Cheap,
|
||||
reversible, targets the dominant overhead. ⚠️ chaining is also the scheduling lever (can starve
|
||||
the movie subsystem — validate against the oracles). *Start here.*
|
||||
2. **JIT / block-recompiler** — collapses both the interpreter body and per-block dispatch; the real
|
||||
ceiling (~5–10×), but a multi-week subsystem.
|
||||
3. **True multi-core** (guest threads on separate host threads) — huge for a 6-thread workload but
|
||||
riskiest: would invalidate the IPM=1M + incumbent-pick timing fixes that made the video work.
|
||||
|
||||
**Caveat for the next session:** precise remainder attribution needs a sampling profiler
|
||||
(`perf_event_paranoid=4` blocks perf without sudo here; gdb `ptrace_scope=1` blocks non-descendant
|
||||
attach). The `XENIA_PROFILE` coarse timers are the current best tool and are now gated zero-cost
|
||||
when off.
|
||||
|
||||
---
|
||||
|
||||
## 5. `XENIA_PROFILE` quick reference
|
||||
|
||||
`XENIA_PROFILE=1 <run>` → periodic snapshots (every 500 M guest instr, or every 500 presents) +
|
||||
a clean-exit report on stderr. Buckets: interp `step_block`, kernel HLE `call_export`, block
|
||||
decode/cache `lookup_or_build`, texture decode, host draw, present, and the unaccounted remainder.
|
||||
Zero-cost when unset (cached `is_on()` gate). Source: `crates/xenia-gpu/src/prof.rs`.
|
||||
Reference in New Issue
Block a user