Frame Performance Analysis and Bottleneck Identification

Goal

Now that GPU-driven frustum culling and indirect rendering are implemented (#143 (closed)), establish where frame time is actually being spent before introducing additional architectural optimizations.

Context

#143 (closed) landed three successive architecture changes — CPU per-object frustum culling, CPU per-submesh frustum culling, and finally GPU-driven compute culling with indirect multi-draw and material-sorted batching — each motivated by understanding the real Bistro scene rather than assumptions. Despite all three, reported real-world FPS on the Bistro project is still near-zero. Rather than implement a fourth optimization (occlusion culling, Hi-Z, meshlets, LODs are all real candidates) on a hypothesis, this issue exists to get real numbers first and let the next architectural decision be driven by measurements.

Full history/rationale: docs/decisions/frustum-culling-143.md and docs/ADR/ADR-0013-gpu-driven-culling.md.

Scope

  • Add CPU timing for the major renderer stages (already partially covered by engine/Profiler.zig's zone system — extend as needed for the new cull compute phase).
  • Add GPU timestamp queries for each render pass (shadow, cull compute, main, transparent) — not currently implemented (engine/Profiler.zig's gpu_time_ms is a CPU-time proxy today, not a real GPU timer).
  • Display per-pass timings in the Studio profiler panel.
  • Report, from a real interactive Bistro session:
    • total frame time, CPU vs GPU;
    • shadow pass cost;
    • compute culling cost;
    • main render pass cost;
    • transparent pass cost;
    • visible vs. culled submesh counts;
    • draw calls;
    • material switches (before/after batching, if comparable).
  • Validate the renderer on the Bistro project while navigating interactively (not headless — this repo's dev sandbox can't produce real frame-timing data without live camera movement).
  • Produce a short document summarizing the dominant bottleneck and recommending the next optimization.

Explicitly out of scope

No new rendering optimizations should be implemented as part of this issue. Its purpose is to produce trustworthy profiling data that drives the next round of work, not to speed anything up directly.