Skip to content

ENG2-P0-01: Add GPU timestamp queries (wgpu QuerySet) for shadow/render/submit phases #741

Description

@aram-devdocs

Parent

  • Program: ENG2 — GoudEngine v2 Rebuild (see the pinned master tracking issue)
  • Phase / Milestone: Phase 0 — Instrumentation & Truth (eng2-p0-truth)
  • Batch / Group: Batch 0.1 — Instrumentation core, Group A
  • Runbook spec: docs/src/runbook/phases/phase-0.md (committed with the roadmap)

Summary

Add wgpu QuerySet-based GPU timestamp queries around the shadow pass, main render pass, and submit call so GPU-side phase costs (gpu_shadow, gpu_render, gpu_submit) are measured directly instead of inferred from CPU record time.

Architecture Context

Layer: Libs (Layer 2) — libs/graphics/backend/wgpu_backend/.
Modules/types touched:

  • goud_engine/src/libs/graphics/backend/wgpu_backend/frame.rstimestamp_writes: None at line 148; CPU-only phase timers at lines 18-127
  • goud_engine/src/libs/graphics/backend/wgpu_backend/shadow_pass.rstimestamp_writes: None at lines 76 and 382

Boundary constraints (only those that apply):

  • Raw GPU calls stay in libs/graphics/backend/ — this work already lives there; do not leak wgpu:: types out of the backend module boundary.

Pattern to follow: Existing CPU phase-timer bracketing pattern in frame.rs (Instant::now() before/after each phase) — mirror the same phase boundaries but back them with QuerySet begin/end.

Scope

  • Add a wgpu::QuerySet (timestamp type) sized for shadow/render/submit phase pairs
  • Wire timestamp_writes: Some(...) into the shadow pass descriptor (shadow_pass.rs:76,382) and main render pass descriptor (frame.rs:148)
  • Resolve query results and expose new gpu_shadow/gpu_render/gpu_submit phase counters distinct from the existing CPU-record phases
  • Tests: spec test asserting the query set is populated and resolved without panicking on the wgpu backend
  • Docs/rules updates if this invalidates .agents/rules/graphics-patterns.md's testing guidance

Acceptance Criteria

  • gpu_shadow, gpu_render, gpu_submit report non-zero timings on a real GPU-backed capture (S1 scene)
  • PERF (area:performance): S1 capture attributes shadow/render/submit cost distinctly instead of the current always-CPU-record-time values; feeds the Phase 0 gate item "S1 capture: gpu_shadow, gpu_render, gpu_submit report non-zero"
  • cargo check && cargo fmt --all -- --check && cargo clippy -- -D warnings clean; cargo test green; ./codegen.sh && git diff --exit-code (drift gate)

Breaking Change & Throne Follow-up

None — additive/internal.

Blocked By

None.

Files Likely Touched

  • Modified: goud_engine/src/libs/graphics/backend/wgpu_backend/frame.rs, .../shadow_pass.rs
  • New: possibly a query-set helper module under backend/wgpu_backend/

Agent Notes

  • timestamp_writes: None at backend/wgpu_backend/frame.rs:148 and shadow_pass.rs:76,382 — no GPU timing exists today; all phases are Instant::now() CPU record-time (frame.rs:18-127).
  • Add QuerySet begin/end around shadow, main pass, submit; new gpu_shadow/gpu_render/gpu_submit phases distinct from CPU-record phases.
  • This is why shadow_pass reports 0 µs while Metal stalls 300–600 ms (perf: BeginFrame + EndFrame stall 300-600ms when shadows enabled with 1.4k+ scene instances (macOS Metal) #677 evidence) — the counter, not the GPU, is silent.
  • This issue blocks ENG2-P0-02 (surfacing the counters via FFI/MCP), ENG2-P0-07 (scene harness capture), and ENG2-P2-10 (root-causing the Metal shadow stall).

Verification

cargo check && cargo fmt --all -- --check && cargo clippy -- -D warnings
cargo test
./codegen.sh && git diff --exit-code

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions