pub struct RenderPassDescriptorCache { /* private fields */ }Expand description
OPT 34: persistent render-pass descriptor and its inner
attachments, reused across begin_render_pass_full calls.
§Why
begin_render_pass_full historically allocated a fresh descriptor
Object, a colorAttachments Array, and one inner
color_attachment Object (plus an optional clearValue Object)
on every frame, then ran 8-15 Reflect::set calls to populate
them. WebGPU re-validates the descriptor each call, but the JS-side
Object / Array allocations and the per-property Reflect::set
crossings are pure overhead — only the clearValue and (rarely)
view / loadOp / storeOp fields change between frames.
§What we cache
- The top-level descriptor
Object(the one passed tobeginRenderPass). - The
colorAttachmentsArray(always exactly one element — we keep the sameArrayreference and mutate its slot 0 in place). - The inner color attachment
Object(slot 0 ofcolorAttachments). - The
clearValueObject(the{r, g, b, a}dictionary that is the actual per-frame mutating field). - Last-applied
loadOp/storeOpstring slices, to detect when the caller switched ops and the cached descriptor must be rebuilt (rare; WebGPU does not hot-swap ops every frame). - Last-applied depth-stencil shape (present / absent), to detect when the depth-stencil shape changes.
§Invalidation
The cache is invalidated (rebuilt from scratch) when any of:
load_opchanges between calls,store_opchanges between calls,- the depth-stencil shape changes (None → Some / Some → None),
- the resolve-target shape changes (MSAA on/off).
view / resolveTarget / clearValue are refreshed on every call
(the swap-chain view expires after each presented frame, so caching
it across frames silently invalidates every subsequent render pass).
These are all &'static str (they come from WEBGPU_*_OP_*
constants), so invalidation is a pointer-compare.
Clone is derived so the parent WebGpuRenderer’s Data derive
(which adds a Clone bound on every field) keeps compiling;
js_sys::Object and js_sys::Array both derive Clone, so the
derived Clone impl just clones the inner JS-side references
(cheap, no JS allocation).