Deferred perf ticket — see docs/perf/012-remaining-bind-group-caches.md.
Summary
Cache the five remaining per-frame create_bind_group calls in end_frame_with_scene that commit 95da6af didn't cover: scene_compose_bg, dof_bg, motion_blur_bg, sss_bg, composite_bg. Expected gain: ~15-30 µs CPU.
Why deferred — V1 prototype regressed
The V1 prototype landed all five caches as Option<(u32, wgpu::BindGroup)> fields keyed on state enums (SSR enabled × ssr_history_idx, TAA × taa_dst_idx, DoF / motion-blur / SSS toggles, exposure ping-pong). Invalidated alongside the existing ssao / ssr caches in resize().
Compiled and ran --quality 3 --ssgi 1 --fps-only 300 at 60 fps vsync — same as pre-change. But on interactive launch, the window rendered entirely black. Most likely cause: one of the cached bind groups bound a view (probably in the composite chain) whose contents had not yet been written by the current frame's pass on the first frame the key appeared — i.e. the state key covered input selection but missed an implicit frame-order dependency.
Reverted.
Why not worth re-attempting right now
- Ticket's own best-case gain is 15-30 µs CPU.
- Perf README's rule of thumb: "Sponza is GPU-bound, not CPU-bound. Don't chase CPU micro-optimizations expecting FPS improvement."
- Render-total CPU is ~4 ms against a 16.7 ms vsync budget — no CPU pressure to relieve.
How to do it safely when reopened
- Per-pass screenshot diff after each cache is wired, so a regression is caught at the first broken cache rather than the composite chain.
- Either include a "was this view written this frame?" bit in the key, OR use a pure
[Option<BindGroup>; N] array so the prior frame's BG stays resident rather than getting evicted when the state flips and back on the next frame.
Reopen criteria
- A scene becomes CPU-bound on bind-group rebuilds (unlikely on current workloads).
- A per-pass screenshot-diff harness becomes available so the V2 rollout can catch regressions incrementally.
Full V1 prototype shape documented in the ticket's "Deferred — prototype notes" section.
Deferred perf ticket — see docs/perf/012-remaining-bind-group-caches.md.
Summary
Cache the five remaining per-frame
create_bind_groupcalls inend_frame_with_scenethat commit 95da6af didn't cover:scene_compose_bg,dof_bg,motion_blur_bg,sss_bg,composite_bg. Expected gain: ~15-30 µs CPU.Why deferred — V1 prototype regressed
The V1 prototype landed all five caches as
Option<(u32, wgpu::BindGroup)>fields keyed on state enums (SSR enabled ×ssr_history_idx, TAA ×taa_dst_idx, DoF / motion-blur / SSS toggles, exposure ping-pong). Invalidated alongside the existing ssao / ssr caches inresize().Compiled and ran
--quality 3 --ssgi 1 --fps-only 300at 60 fps vsync — same as pre-change. But on interactive launch, the window rendered entirely black. Most likely cause: one of the cached bind groups bound a view (probably in the composite chain) whose contents had not yet been written by the current frame's pass on the first frame the key appeared — i.e. the state key covered input selection but missed an implicit frame-order dependency.Reverted.
Why not worth re-attempting right now
How to do it safely when reopened
[Option<BindGroup>; N]array so the prior frame's BG stays resident rather than getting evicted when the state flips and back on the next frame.Reopen criteria
Full V1 prototype shape documented in the ticket's "Deferred — prototype notes" section.