Parent
- Program: ENG2 — GoudEngine v2 Rebuild (see the pinned master tracking issue)
- Phase / Milestone: Phase 2 — Render Core v2 (
eng2-p2-render-core)
- Batch / Group: New in design-expansion.md — Metal-gated stretch goal, sequenced after core instancing/culling work
- Runbook spec:
docs/src/runbook/phases/phase-2.md (committed with the roadmap)
Summary
Evaluate GPU-driven culling via multi_draw_indirect/compute-driven submission for the 30k+ visible target on the Metal backend; implement it if wgpu's Metal support is viable, otherwise ship the CPU spatial-index path (ENG2-P2-02) as the answer and document the indirect path as a future capability.
Architecture Context
Layer: Layer 2 (Libs) — libs/graphics/backend/wgpu_backend/ (see tools/lint_layers.rs — downward-only deps).
Modules/types touched:
goud_engine/src/libs/graphics/backend/wgpu_backend/init.rs — currently requests wgpu::Features::empty(); this issue evaluates whether MULTI_DRAW_INDIRECT/INDIRECT_FIRST_INSTANCE can be requested and are actually supported on the Metal adapter.
- If viable: new compute-pass culling shader that writes a draw-indirect buffer, plus the indirect-draw submission path in the render loop.
Boundary constraints (only those that apply):
- Raw GPU calls stay in
libs/graphics/backend/ — no wgpu:: outside it.
Pattern to follow: RFC-0005 (ENG2-P0-09) decision item on CPU spatial index vs GPU compute culling — this issue is the execution of whichever branch the RFC (and this issue's own Metal feasibility check) lands on.
Scope
Acceptance Criteria
Breaking Change & Throne Follow-up
None — additive/optional path. If implemented, it is an alternate submission mode gated by hardware capability detection, not a replacement that removes the CPU path.
Blocked By
ENG2-P2-02 (CPU spatial index — the fallback/comparison baseline), ENG2-P2-04 (uniform v2 dynamic-offset layout — indirect draws need compatible per-object addressing).
Files Likely Touched
- New/Modified/Generated:
goud_engine/src/libs/graphics/backend/wgpu_backend/init.rs, new compute-culling shader + indirect-draw submission path (if shipped), decision-record doc (if not shipped)
Agent Notes
- This is an explicitly Metal-gated stretch goal per design-expansion.md — do not block Phase 2 gate closure (ENG2-P2-12) on this landing; the CPU spatial-index path (ENG2-P2-02) is the guaranteed-shipped answer regardless of this issue's outcome.
backend/wgpu_backend/init.rs currently sets required_features: wgpu::Features::empty() (verified in current source) — no indirect-draw features are requested today, so this issue's first job is determining whether the Metal adapter actually supports them before writing any compute-culling code.
- RFC-0005 (ENG2-P0-09) decision item: "instanced draws vs multi_draw_indirect (Metal feature check)" — this issue is the execution of that RFC decision point, so the RFC's conclusion should already have flagged the direction; verify it hasn't changed before starting.
- Acceptance is explicitly "whichever path achieves it" — this issue's success criterion is the S2 30k-visible/120-FPS/CPU-submit-≤1ms number, not "ship GPU-driven culling" as an end in itself.
Verification
cargo check && cargo fmt --all -- --check && cargo clippy -- -D warnings
cargo test
./codegen.sh && git diff --exit-code
Parent
eng2-p2-render-core)docs/src/runbook/phases/phase-2.md(committed with the roadmap)Summary
Evaluate GPU-driven culling via
multi_draw_indirect/compute-driven submission for the 30k+ visible target on the Metal backend; implement it if wgpu's Metal support is viable, otherwise ship the CPU spatial-index path (ENG2-P2-02) as the answer and document the indirect path as a future capability.Architecture Context
Layer: Layer 2 (Libs) —
libs/graphics/backend/wgpu_backend/(seetools/lint_layers.rs— downward-only deps).Modules/types touched:
goud_engine/src/libs/graphics/backend/wgpu_backend/init.rs— currently requestswgpu::Features::empty(); this issue evaluates whetherMULTI_DRAW_INDIRECT/INDIRECT_FIRST_INSTANCEcan be requested and are actually supported on the Metal adapter.Boundary constraints (only those that apply):
libs/graphics/backend/— nowgpu::outside it.Pattern to follow: RFC-0005 (ENG2-P0-09) decision item on CPU spatial index vs GPU compute culling — this issue is the execution of whichever branch the RFC (and this issue's own Metal feasibility check) lands on.
Scope
wgpu::Features::MULTI_DRAW_INDIRECTandINDIRECT_FIRST_INSTANCEsupport on the Metal backend/adapter actually used (confirm against whatinit.rsrequests today — currentlyFeatures::empty()).goud_engine/tests/spec/+ unit/isolation coverage for the new code paths..agents/rules/graphics-patterns.mdordocs/src/*.Acceptance Criteria
cargo check && cargo fmt --all -- --check && cargo clippy -- -D warningsclean;cargo testgreen;./codegen.sh && git diff --exit-code(drift gate)Breaking Change & Throne Follow-up
None — additive/optional path. If implemented, it is an alternate submission mode gated by hardware capability detection, not a replacement that removes the CPU path.
Blocked By
ENG2-P2-02 (CPU spatial index — the fallback/comparison baseline), ENG2-P2-04 (uniform v2 dynamic-offset layout — indirect draws need compatible per-object addressing).
Files Likely Touched
goud_engine/src/libs/graphics/backend/wgpu_backend/init.rs, new compute-culling shader + indirect-draw submission path (if shipped), decision-record doc (if not shipped)Agent Notes
backend/wgpu_backend/init.rscurrently setsrequired_features: wgpu::Features::empty()(verified in current source) — no indirect-draw features are requested today, so this issue's first job is determining whether the Metal adapter actually supports them before writing any compute-culling code.Verification