[iterate-4A] diagnostics: XENIA_PROFILE wall-time profiler + probe/tooling snapshot
Handoff snapshot of the env-gated diagnostic scaffolding used across the intro-video RE. Kept out of the milestone commits (645feb8..5573ac1) to keep those clean; committed here so nothing is lost on handoff. New — XENIA_PROFILE wall-time profiler (crates/xenia-gpu/src/prof.rs): Coarse buckets attributing playback wall time to interpreter (step_block), kernel HLE (call_export), block decode/cache (lookup_or_build), texture decode, host draw, and present; prints periodic snapshots (every 500M guest instr, or every 500 presents) + a clean-exit report. Hot path is gated on a cached is_on() (one relaxed load) so it is zero-cost when XENIA_PROFILE is unset. Call sites: main.rs run_superblock / parallel worker (step_block, lookup_or_build, call_export), texture_cache ensure_cached, render.rs present + dispatch_xenos_draws. First profile (movie playback, headless single-thread lockstep): effective ~35 MIPS; interpreter body ~40% @ ~95-102 MIPS; texture decode 0.3% (cache works); present ~0%; the rest is per-block dispatch + scheduler plumbing (~13 instr/block over 229M blocks). Overhead-bound, not interpreter-body bound; the levers are coarser execution units (superblock chaining) and ultimately a JIT. Pre-existing read-only probe knobs (were uncommitted; env-gated, observe-only): XENIA_RET_CAPTURE_PC/_REG/_MEM, LOG_RESUMES, LOG_WAITS, LOG_SIGNAL, FORCE_TID, STARVE_LIMIT, INCUMBENT_PICK, INSTR_PER_MS, DUMP_FRAME, DUMP_WGSL, BIND_LOG, CONST_LOG, DISPATCH_REC, AUDIT_PC_TRACE. Tooling: sylph-run.sh (movie oracle loop, 180s default timeout), zq.py (DuckDB disasm/xref helper). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -652,6 +652,7 @@ impl TextureCache {
|
||||
}
|
||||
self.restale_total += 1;
|
||||
}
|
||||
let _prof_t0 = std::time::Instant::now();
|
||||
let bytes = match key.format {
|
||||
TextureFormat::K8 => decode_k8(&key, mem)?,
|
||||
TextureFormat::K8888 => decode_k8888_tiled(&key, mem)?,
|
||||
@@ -659,9 +660,37 @@ impl TextureCache {
|
||||
TextureFormat::Dxt1 => decode_dxt1_tiled(&key, mem)?,
|
||||
TextureFormat::Dxt2_3 => decode_dxt23_tiled(&key, mem)?,
|
||||
TextureFormat::Dxt4_5 => decode_dxt45_tiled(&key, mem)?,
|
||||
_ => return Err(DecodeError::UnsupportedFormat),
|
||||
_ => {
|
||||
// XENIA_TEX_REJECT_LOG diagnostic (STEP 87, read-only): the
|
||||
// intro video uploads its YUV420 planes as `k_8` linear
|
||||
// textures; if we have no decoder for the requested format we
|
||||
// reject it here and it never reaches the GPU (→ black video).
|
||||
// Rate-limited so a per-frame flood stays grep-able.
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
static N: AtomicUsize = AtomicUsize::new(0);
|
||||
let n = N.fetch_add(1, Ordering::Relaxed);
|
||||
if n < 120 {
|
||||
tracing::warn!(
|
||||
fmt = ?key.format,
|
||||
w = key.width,
|
||||
h = key.height,
|
||||
base = format_args!("0x{:08x}", key.base_address),
|
||||
dim = ?key.dimension,
|
||||
pitch = key.pitch_texels,
|
||||
n,
|
||||
"TEX-REJECT: unsupported texture format (no host decoder)"
|
||||
);
|
||||
}
|
||||
return Err(DecodeError::UnsupportedFormat);
|
||||
}
|
||||
};
|
||||
self.decodes_total += 1;
|
||||
{
|
||||
use crate::prof;
|
||||
prof::add(&prof::TEXDEC_NS, _prof_t0.elapsed().as_nanos() as u64);
|
||||
prof::add(&prof::TEXDEC_CALLS, 1);
|
||||
prof::add(&prof::TEXDEC_BYTES, bytes.len() as u64);
|
||||
}
|
||||
let entry = CachedTexture {
|
||||
key,
|
||||
version_when_uploaded: current_version,
|
||||
|
||||
Reference in New Issue
Block a user