Name Description Size
allocator.rs 2239
bind.rs 19465
bundle.rs ! Render Bundles A render bundle is a prerecorded sequence of commands that can be replayed on a command encoder with a single call. A single bundle can replayed any number of times, on different encoders. Constructing a render bundle lets `wgpu` validate and analyze its commands up front, so that replaying a bundle can be more efficient than simply re-recording its commands each time. Not all commands are available in bundles; for example, a render bundle may not contain a [`RenderCommand::SetViewport`] command. Most of `wgpu`'s backend graphics APIs have something like bundles. For example, Vulkan calls them "secondary command buffers", and Metal calls them "indirect command buffers". Although we plan to take advantage of these platform features at some point in the future, for now `wgpu`'s implementation of render bundles does not use them: at the hal level, `wgpu` render bundles just replay the commands. ## Render Bundle Isolation One important property of render bundles is that the draw calls in a render bundle depend solely on the pipeline and state established within the render bundle itself. A draw call in a bundle will never use a vertex buffer, say, that was set in the `RenderPass` before executing the bundle. We call this property 'isolation', in that a render bundle is somewhat isolated from the passes that use it. Render passes are also isolated from the effects of bundles. After executing a render bundle, a render pass's pipeline, bind groups, and vertex and index buffers are are unset, so the bundle cannot affect later draw calls in the pass. A render pass is not fully isolated from a bundle's effects on push constant values. Draw calls following a bundle's execution will see whatever values the bundle writes to push constant storage. Setting a pipeline initializes any push constant storage it could access to zero, and this initialization may also be visible after bundle execution. ## Render Bundle Lifecycle To create a render bundle: 1) Create a [`RenderBundleEncoder`] by calling [`Global::device_create_render_bundle_encoder`][Gdcrbe]. 2) Record commands in the `RenderBundleEncoder` using functions from the [`bundle_ffi`] module. 3) Call [`Global::render_bundle_encoder_finish`][Grbef], which analyzes and cleans up the command stream and returns a `RenderBundleId`. 4) Then, any number of times, call [`render_pass_execute_bundles`][wrpeb] to execute the bundle as part of some render pass. ## Implementation The most complex part of render bundles is the "finish" step, mostly implemented in [`RenderBundleEncoder::finish`]. This consumes the commands stored in the encoder's [`BasePass`], while validating everything, tracking the state, dropping redundant or unnecessary commands, and presenting the results as a new [`RenderBundle`]. It doesn't actually execute any commands. This step also enforces the 'isolation' property mentioned above: every draw call is checked to ensure that the resources it uses on were established since the last time the pipeline was set. This means the bundle can be executed verbatim without any state tracking. ### Execution When the bundle is used in an actual render pass, `RenderBundle::execute` is called. It goes through the commands and issues them into the native command buffer. Thanks to isolation, it doesn't track any bind group invalidations or index format changes. [Gdcrbe]: crate::global::Global::device_create_render_bundle_encoder [Grbef]: crate::global::Global::render_bundle_encoder_finish [wrpeb]: crate::global::Global::render_pass_execute_bundles ! 60695
clear.rs 19179
compute.rs 44257
compute_command.rs 8481
draw.rs 4566
memory_init.rs 13127
mod.rs 32548
query.rs 15679
render.rs 115680
render_command.rs 18637
timestamp_writes.rs 1165
transfer.rs 41228