Render Bundles
RenderBundleEncoder records a reusable sequence of draw calls once, replayed via RenderPass::execute_bundles — worth it once you have many draws that don’t change pipeline/bind group/buffers from one frame to the next (static scene geometry, say), since replaying a bundle is typically cheaper than re-recording the same commands by hand every frame.
let mut encoder = RenderBundleEncoderBuilder::new()
.color_formats(vec![Some(backend.surface_format())])
.depth_stencil_format(TextureFormat::Depth32Float) // omit if this pass has no depth attachment
.sample_count(backend.sample_count()) // must match the pass(es) it's executed in — see MSAA
.build(&backend);
encoder.set_pipeline(&material.pipeline);
encoder.set_bind_group(0, &instance.bind_group, &[]);
encoder.set_vertex_buffer(0, &mesh.vertex_buffer);
encoder.set_index_buffer(&mesh.index_buffer, IndexFormat::Uint32);
encoder.draw_indexed(0..mesh.index_count, 0, 0..1);
let bundle = encoder.finish(Some("static-geometry"));
// ... later, once per frame, inside an ordinary render pass:
pass.execute_bundles(&[&bundle]);
color_formats/depth_stencil_format/sample_count must match whatever render pass(es) the bundle is later executed against, or wgpu’s validation rejects it — the same requirement as a material’s own targets/depth/sample_count (see Materials and MSAA). The recording methods (set_pipeline/set_bind_group/set_vertex_buffer/set_index_buffer/draw/draw_indexed) are the same shape as RenderPass itself — a bundle is a record-once, replay-many version of the same vocabulary.