wgpu/api/render_pass.rs
1use core::ops::Range;
2
3use crate::{
4 api::{impl_deferred_command_buffer_actions, SharedDeferredCommandBufferActions},
5 *,
6};
7pub use wgt::{LoadOp, Operations, StoreOp};
8
9/// In-progress recording of a render pass: a list of render commands in a [`CommandEncoder`].
10///
11/// It can be created with [`CommandEncoder::begin_render_pass()`], whose [`RenderPassDescriptor`]
12/// specifies the attachments (textures) that will be rendered to.
13///
14/// Most of the methods on `RenderPass` serve one of two purposes, identifiable by their names:
15///
16/// * `draw_*()`: Drawing (that is, encoding a render command, which, when executed by the GPU, will
17/// rasterize something and execute shaders).
18/// * `set_*()`: Setting part of the [render state](https://gpuweb.github.io/gpuweb/#renderstate)
19/// for future drawing commands.
20///
21/// A render pass may contain any number of drawing commands, and before/between each command the
22/// render state may be updated however you wish; each drawing command will be executed using the
23/// render state that has been set when the `draw_*()` function is called.
24///
25/// Corresponds to [WebGPU `GPURenderPassEncoder`](
26/// https://gpuweb.github.io/gpuweb/#render-pass-encoder).
27#[derive(Debug)]
28pub struct RenderPass<'encoder> {
29 pub(crate) inner: dispatch::DispatchRenderPass,
30 pub(crate) actions: SharedDeferredCommandBufferActions,
31
32 /// This lifetime is used to protect the [`CommandEncoder`] from being used
33 /// while the pass is alive. This needs to be PhantomDrop to prevent the lifetime
34 /// from being shortened.
35 pub(crate) _encoder_guard: PhantomDrop<&'encoder ()>,
36}
37
38#[cfg(send_sync)]
39static_assertions::assert_impl_all!(RenderPass<'_>: Send, Sync);
40
41crate::cmp::impl_eq_ord_hash_proxy!(RenderPass<'_> => .inner);
42
43impl RenderPass<'_> {
44 /// Drops the lifetime relationship to the parent command encoder, making usage of
45 /// the encoder while this pass is recorded a run-time error instead.
46 ///
47 /// Attention: As long as the render pass has not been ended, any mutating operation on the parent
48 /// command encoder will cause a run-time error and invalidate it!
49 /// By default, the lifetime constraint prevents this, but it can be useful
50 /// to handle this at run time, such as when storing the pass and encoder in the same
51 /// data structure.
52 ///
53 /// This operation has no effect on pass recording.
54 /// It's a safe operation, since [`CommandEncoder`] is in a locked state as long as the pass is active
55 /// regardless of the lifetime constraint or its absence.
56 pub fn forget_lifetime(self) -> RenderPass<'static> {
57 RenderPass {
58 inner: self.inner,
59 actions: self.actions,
60 _encoder_guard: crate::api::PhantomDrop::default(),
61 }
62 }
63
64 /// Sets the active bind group for a given bind group index. The bind group layout
65 /// in the active pipeline when any `draw_*()` method is called must match the layout of
66 /// this bind group.
67 ///
68 /// If the bind group have dynamic offsets, provide them in binding order.
69 /// These offsets have to be aligned to [`Limits::min_uniform_buffer_offset_alignment`]
70 /// or [`Limits::min_storage_buffer_offset_alignment`] appropriately.
71 ///
72 /// Subsequent draw calls’ shader executions will be able to access data in these bind groups.
73 pub fn set_bind_group<'a, BG>(&mut self, index: u32, bind_group: BG, offsets: &[DynamicOffset])
74 where
75 Option<&'a BindGroup>: From<BG>,
76 {
77 let bg: Option<&'a BindGroup> = bind_group.into();
78 let bg = bg.map(|bg| &bg.inner);
79
80 self.inner.set_bind_group(index, bg, offsets);
81 }
82
83 /// Sets the active render pipeline.
84 ///
85 /// Subsequent draw calls will exhibit the behavior defined by `pipeline`.
86 pub fn set_pipeline(&mut self, pipeline: &RenderPipeline) {
87 self.inner.set_pipeline(&pipeline.inner);
88 }
89
90 /// Sets the blend color as used by some of the blending modes.
91 ///
92 /// Subsequent blending tests will test against this value.
93 /// If this method has not been called, the blend constant defaults to [`Color::TRANSPARENT`]
94 /// (all components zero).
95 pub fn set_blend_constant(&mut self, color: Color) {
96 self.inner.set_blend_constant(color);
97 }
98
99 /// Sets the active index buffer.
100 ///
101 /// Subsequent calls to [`draw_indexed`](RenderPass::draw_indexed) on this [`RenderPass`] will
102 /// use `buffer` as the source index buffer.
103 pub fn set_index_buffer(&mut self, buffer_slice: BufferSlice<'_>, index_format: IndexFormat) {
104 self.inner.set_index_buffer(
105 &buffer_slice.buffer.inner,
106 index_format,
107 buffer_slice.offset,
108 Some(buffer_slice.size),
109 );
110 }
111
112 /// Assign a vertex buffer to a slot.
113 ///
114 /// Subsequent calls to [`draw`] and [`draw_indexed`] on this
115 /// [`RenderPass`] will use `buffer` as one of the source vertex buffers.
116 /// The format of the data in the buffer is specified by the [`VertexBufferLayout`] in the
117 /// pipeline's [`VertexState`].
118 ///
119 /// The `slot` refers to the index of the matching descriptor in
120 /// [`VertexState::buffers`].
121 ///
122 /// [`draw`]: RenderPass::draw
123 /// [`draw_indexed`]: RenderPass::draw_indexed
124 pub fn set_vertex_buffer(&mut self, slot: u32, buffer_slice: BufferSlice<'_>) {
125 self.inner.set_vertex_buffer(
126 slot,
127 &buffer_slice.buffer.inner,
128 buffer_slice.offset,
129 Some(buffer_slice.size),
130 );
131 }
132
133 /// Sets the scissor rectangle used during the rasterization stage.
134 /// After transformation into [viewport coordinates](https://www.w3.org/TR/webgpu/#viewport-coordinates).
135 ///
136 /// Subsequent draw calls will discard any fragments which fall outside the scissor rectangle.
137 /// If this method has not been called, the scissor rectangle defaults to the entire bounds of
138 /// the render targets.
139 ///
140 /// The function of the scissor rectangle resembles [`set_viewport()`](Self::set_viewport),
141 /// but it does not affect the coordinate system, only which fragments are discarded.
142 pub fn set_scissor_rect(&mut self, x: u32, y: u32, width: u32, height: u32) {
143 self.inner.set_scissor_rect(x, y, width, height);
144 }
145
146 /// Sets the viewport used during the rasterization stage to linearly map
147 /// from [normalized device coordinates](https://www.w3.org/TR/webgpu/#ndc) to [viewport coordinates](https://www.w3.org/TR/webgpu/#viewport-coordinates).
148 ///
149 /// Subsequent draw calls will only draw within this region.
150 /// If this method has not been called, the viewport defaults to the entire bounds of the render
151 /// targets.
152 pub fn set_viewport(&mut self, x: f32, y: f32, w: f32, h: f32, min_depth: f32, max_depth: f32) {
153 self.inner.set_viewport(x, y, w, h, min_depth, max_depth);
154 }
155
156 /// Sets the stencil reference.
157 ///
158 /// Subsequent stencil tests will test against this value.
159 /// If this method has not been called, the stencil reference value defaults to `0`.
160 pub fn set_stencil_reference(&mut self, reference: u32) {
161 self.inner.set_stencil_reference(reference);
162 }
163
164 /// Inserts debug marker.
165 pub fn insert_debug_marker(&mut self, label: &str) {
166 self.inner.insert_debug_marker(label);
167 }
168
169 /// Start record commands and group it into debug marker group.
170 pub fn push_debug_group(&mut self, label: &str) {
171 self.inner.push_debug_group(label);
172 }
173
174 /// Stops command recording and creates debug group.
175 pub fn pop_debug_group(&mut self) {
176 self.inner.pop_debug_group();
177 }
178
179 /// Draws primitives from the active vertex buffer(s).
180 ///
181 /// The active vertex buffer(s) can be set with [`RenderPass::set_vertex_buffer`].
182 /// This does not use an index buffer. If you need indexed drawing, see [`RenderPass::draw_indexed`]
183 ///
184 /// Panics if `vertices` range is outside of the range of the vertices range of any set vertex buffer.
185 ///
186 /// - `vertices`: The range of vertices to draw.
187 /// - `instances`: Range of instances to draw. Use `0..1` if instance buffers are not used.
188 ///
189 /// E.g.of how its used internally
190 /// ```rust ignore
191 /// for instance_id in instance_range {
192 /// for vertex_id in vertex_range {
193 /// let vertex = vertex[vertex_id];
194 /// vertex_shader(vertex, vertex_id, instance_id);
195 /// }
196 /// }
197 /// ```
198 ///
199 /// This drawing command uses the current render state, as set by preceding `set_*()` methods.
200 /// It is not affected by changes to the state that are performed after it is called.
201 pub fn draw(&mut self, vertices: Range<u32>, instances: Range<u32>) {
202 self.inner.draw(vertices, instances);
203 }
204
205 /// Draws indexed primitives using the active index buffer and the active vertex buffers.
206 ///
207 /// The active index buffer can be set with [`RenderPass::set_index_buffer`]
208 /// The active vertex buffers can be set with [`RenderPass::set_vertex_buffer`].
209 ///
210 /// Panics if `indices` range is outside of the range of the indices range of the set index buffer.
211 ///
212 /// - `indices`: The range of indices to draw.
213 /// - `base_vertex`: value added to each index value before indexing into the vertex buffers.
214 /// - `instances`: Range of instances to draw. Use `0..1` if instance buffers are not used.
215 ///
216 /// E.g.of how its used internally
217 /// ```rust ignore
218 /// for instance_id in instance_range {
219 /// for index_index in index_range {
220 /// let vertex_id = index_buffer[index_index];
221 /// let adjusted_vertex_id = vertex_id + base_vertex;
222 /// let vertex = vertex[adjusted_vertex_id];
223 /// vertex_shader(vertex, adjusted_vertex_id, instance_id);
224 /// }
225 /// }
226 /// ```
227 ///
228 /// This drawing command uses the current render state, as set by preceding `set_*()` methods.
229 /// It is not affected by changes to the state that are performed after it is called.
230 pub fn draw_indexed(&mut self, indices: Range<u32>, base_vertex: i32, instances: Range<u32>) {
231 self.inner.draw_indexed(indices, base_vertex, instances);
232 }
233
234 /// Draws using a mesh shader pipeline
235 pub fn draw_mesh_tasks(&mut self, group_count_x: u32, group_count_y: u32, group_count_z: u32) {
236 self.inner
237 .draw_mesh_tasks(group_count_x, group_count_y, group_count_z);
238 }
239
240 /// Draws primitives from the active vertex buffer(s) based on the contents of the `indirect_buffer`.
241 ///
242 /// This is like calling [`RenderPass::draw`] but the contents of the call are specified in the `indirect_buffer`.
243 /// The structure expected in `indirect_buffer` must conform to [`DrawIndirectArgs`](crate::util::DrawIndirectArgs).
244 ///
245 /// Calling this requires the device support [`DownlevelFlags::INDIRECT_EXECUTION`].
246 pub fn draw_indirect(&mut self, indirect_buffer: &Buffer, indirect_offset: BufferAddress) {
247 self.inner
248 .draw_indirect(&indirect_buffer.inner, indirect_offset);
249 }
250
251 /// Draws indexed primitives using the active index buffer and the active vertex buffers,
252 /// based on the contents of the `indirect_buffer`.
253 ///
254 /// This is like calling [`RenderPass::draw_indexed`] but the contents of the call are specified in the `indirect_buffer`.
255 /// The structure expected in `indirect_buffer` must conform to [`DrawIndexedIndirectArgs`](crate::util::DrawIndexedIndirectArgs).
256 ///
257 /// Calling this requires the device support [`DownlevelFlags::INDIRECT_EXECUTION`].
258 pub fn draw_indexed_indirect(
259 &mut self,
260 indirect_buffer: &Buffer,
261 indirect_offset: BufferAddress,
262 ) {
263 self.inner
264 .draw_indexed_indirect(&indirect_buffer.inner, indirect_offset);
265 }
266
267 /// Draws using a mesh shader pipeline,
268 /// based on the contents of the `indirect_buffer`
269 ///
270 /// This is like calling [`RenderPass::draw_mesh_tasks`] but the contents of the call are specified in the `indirect_buffer`.
271 /// The structure expected in the `indirect_buffer` must conform to [`DispatchIndirectArgs`](crate::util::DispatchIndirectArgs).
272 ///
273 /// Indirect drawing has some caveats depending on the features available. We are not currently able to validate
274 /// these and issue an error.
275 ///
276 /// See details on the individual flags for more information.
277 pub fn draw_mesh_tasks_indirect(
278 &mut self,
279 indirect_buffer: &Buffer,
280 indirect_offset: BufferAddress,
281 ) {
282 self.inner
283 .draw_mesh_tasks_indirect(&indirect_buffer.inner, indirect_offset);
284 }
285
286 impl_deferred_command_buffer_actions!();
287
288 /// Execute a [render bundle][RenderBundle], which is a set of pre-recorded commands
289 /// that can be run together.
290 ///
291 /// Commands in the bundle do not inherit this render pass's current render state, and after the
292 /// bundle has executed, the state is **cleared** (reset to defaults, not the previous state).
293 pub fn execute_bundles<'a, I: IntoIterator<Item = &'a RenderBundle>>(
294 &mut self,
295 render_bundles: I,
296 ) {
297 let mut render_bundles = render_bundles.into_iter().map(|rb| &rb.inner);
298
299 self.inner.execute_bundles(&mut render_bundles);
300 }
301
302 /// Dispatches multiple draw calls from the active vertex buffer(s) based on the contents of the `indirect_buffer`.
303 /// `count` draw calls are issued.
304 ///
305 /// The active vertex buffers can be set with [`RenderPass::set_vertex_buffer`].
306 ///
307 /// The structure expected in `indirect_buffer` must conform to [`DrawIndirectArgs`](crate::util::DrawIndirectArgs).
308 /// These draw structures are expected to be tightly packed.
309 ///
310 /// Calling this requires the device support [`DownlevelFlags::INDIRECT_EXECUTION`].
311 ///
312 /// This drawing command uses the current render state, as set by preceding `set_*()` methods.
313 /// It is not affected by changes to the state that are performed after it is called.
314 pub fn multi_draw_indirect(
315 &mut self,
316 indirect_buffer: &Buffer,
317 indirect_offset: BufferAddress,
318 count: u32,
319 ) {
320 self.inner
321 .multi_draw_indirect(&indirect_buffer.inner, indirect_offset, count);
322 }
323
324 /// Dispatches multiple draw calls from the active index buffer and the active vertex buffers,
325 /// based on the contents of the `indirect_buffer`. `count` draw calls are issued.
326 ///
327 /// The active index buffer can be set with [`RenderPass::set_index_buffer`], while the active
328 /// vertex buffers can be set with [`RenderPass::set_vertex_buffer`].
329 ///
330 /// The structure expected in `indirect_buffer` must conform to [`DrawIndexedIndirectArgs`](crate::util::DrawIndexedIndirectArgs).
331 /// These draw structures are expected to be tightly packed.
332 ///
333 /// Calling this requires the device support [`DownlevelFlags::INDIRECT_EXECUTION`].
334 ///
335 /// This drawing command uses the current render state, as set by preceding `set_*()` methods.
336 /// It is not affected by changes to the state that are performed after it is called.
337 pub fn multi_draw_indexed_indirect(
338 &mut self,
339 indirect_buffer: &Buffer,
340 indirect_offset: BufferAddress,
341 count: u32,
342 ) {
343 self.inner
344 .multi_draw_indexed_indirect(&indirect_buffer.inner, indirect_offset, count);
345 }
346
347 /// Dispatches multiple draw calls based on the contents of the `indirect_buffer`.
348 /// `count` draw calls are issued.
349 ///
350 /// The structure expected in the `indirect_buffer` must conform to [`DispatchIndirectArgs`](crate::util::DispatchIndirectArgs).
351 ///
352 /// This drawing command uses the current render state, as set by preceding `set_*()` methods.
353 /// It is not affected by changes to the state that are performed after it is called.
354 pub fn multi_draw_mesh_tasks_indirect(
355 &mut self,
356 indirect_buffer: &Buffer,
357 indirect_offset: BufferAddress,
358 count: u32,
359 ) {
360 self.inner
361 .multi_draw_mesh_tasks_indirect(&indirect_buffer.inner, indirect_offset, count);
362 }
363
364 #[cfg(custom)]
365 /// Returns custom implementation of RenderPass (if custom backend and is internally T)
366 pub fn as_custom<T: custom::RenderPassInterface>(&self) -> Option<&T> {
367 self.inner.as_custom()
368 }
369}
370
371/// [`Features::MULTI_DRAW_INDIRECT_COUNT`] must be enabled on the device in order to call these functions.
372impl RenderPass<'_> {
373 /// Dispatches multiple draw calls from the active vertex buffer(s) based on the contents of the `indirect_buffer`.
374 /// The count buffer is read to determine how many draws to issue.
375 ///
376 /// The indirect buffer must be long enough to account for `max_count` draws, however only `count`
377 /// draws will be read. If `count` is greater than `max_count`, `max_count` will be used.
378 ///
379 /// The active vertex buffers can be set with [`RenderPass::set_vertex_buffer`].
380 ///
381 /// The structure expected in `indirect_buffer` must conform to [`DrawIndirectArgs`](crate::util::DrawIndirectArgs).
382 /// These draw structures are expected to be tightly packed.
383 ///
384 /// The structure expected in `count_buffer` is the following:
385 ///
386 /// ```rust
387 /// #[repr(C)]
388 /// struct DrawIndirectCount {
389 /// count: u32, // Number of draw calls to issue.
390 /// }
391 /// ```
392 ///
393 /// This drawing command uses the current render state, as set by preceding `set_*()` methods.
394 /// It is not affected by changes to the state that are performed after it is called.
395 pub fn multi_draw_indirect_count(
396 &mut self,
397 indirect_buffer: &Buffer,
398 indirect_offset: BufferAddress,
399 count_buffer: &Buffer,
400 count_offset: BufferAddress,
401 max_count: u32,
402 ) {
403 self.inner.multi_draw_indirect_count(
404 &indirect_buffer.inner,
405 indirect_offset,
406 &count_buffer.inner,
407 count_offset,
408 max_count,
409 );
410 }
411
412 /// Dispatches multiple draw calls from the active index buffer and the active vertex buffers,
413 /// based on the contents of the `indirect_buffer`. The count buffer is read to determine how many draws to issue.
414 ///
415 /// The indirect buffer must be long enough to account for `max_count` draws, however only `count`
416 /// draws will be read. If `count` is greater than `max_count`, `max_count` will be used.
417 ///
418 /// The active index buffer can be set with [`RenderPass::set_index_buffer`], while the active
419 /// vertex buffers can be set with [`RenderPass::set_vertex_buffer`].
420 ///
421 /// The structure expected in `indirect_buffer` must conform to [`DrawIndexedIndirectArgs`](crate::util::DrawIndexedIndirectArgs).
422 ///
423 /// These draw structures are expected to be tightly packed.
424 ///
425 /// The structure expected in `count_buffer` is the following:
426 ///
427 /// ```rust
428 /// #[repr(C)]
429 /// struct DrawIndexedIndirectCount {
430 /// count: u32, // Number of draw calls to issue.
431 /// }
432 /// ```
433 ///
434 /// This drawing command uses the current render state, as set by preceding `set_*()` methods.
435 /// It is not affected by changes to the state that are performed after it is called.
436 pub fn multi_draw_indexed_indirect_count(
437 &mut self,
438 indirect_buffer: &Buffer,
439 indirect_offset: BufferAddress,
440 count_buffer: &Buffer,
441 count_offset: BufferAddress,
442 max_count: u32,
443 ) {
444 self.inner.multi_draw_indexed_indirect_count(
445 &indirect_buffer.inner,
446 indirect_offset,
447 &count_buffer.inner,
448 count_offset,
449 max_count,
450 );
451 }
452
453 /// Dispatches multiple draw calls based on the contents of the `indirect_buffer`. The count buffer is read to determine how many draws to issue.
454 ///
455 /// The indirect buffer must be long enough to account for `max_count` draws, however only `count`
456 /// draws will be read. If `count` is greater than `max_count`, `max_count` will be used.
457 ///
458 /// The structure expected in the `indirect_buffer` must conform to [`DispatchIndirectArgs`](crate::util::DispatchIndirectArgs).
459 ///
460 /// These draw structures are expected to be tightly packed.
461 ///
462 /// This drawing command uses the current render state, as set by preceding `set_*()` methods.
463 /// It is not affected by changes to the state that are performed after it is called.
464 pub fn multi_draw_mesh_tasks_indirect_count(
465 &mut self,
466 indirect_buffer: &Buffer,
467 indirect_offset: BufferAddress,
468 count_buffer: &Buffer,
469 count_offset: BufferAddress,
470 max_count: u32,
471 ) {
472 self.inner.multi_draw_mesh_tasks_indirect_count(
473 &indirect_buffer.inner,
474 indirect_offset,
475 &count_buffer.inner,
476 count_offset,
477 max_count,
478 );
479 }
480}
481
482/// [`Features::PUSH_CONSTANTS`] must be enabled on the device in order to call these functions.
483impl RenderPass<'_> {
484 /// Set push constant data for subsequent draw calls.
485 ///
486 /// Write the bytes in `data` at offset `offset` within push constant
487 /// storage, all of which are accessible by all the pipeline stages in
488 /// `stages`, and no others. Both `offset` and the length of `data` must be
489 /// multiples of [`PUSH_CONSTANT_ALIGNMENT`], which is always 4.
490 ///
491 /// For example, if `offset` is `4` and `data` is eight bytes long, this
492 /// call will write `data` to bytes `4..12` of push constant storage.
493 ///
494 /// # Stage matching
495 ///
496 /// Every byte in the affected range of push constant storage must be
497 /// accessible to exactly the same set of pipeline stages, which must match
498 /// `stages`. If there are two bytes of storage that are accessible by
499 /// different sets of pipeline stages - say, one is accessible by fragment
500 /// shaders, and the other is accessible by both fragment shaders and vertex
501 /// shaders - then no single `set_push_constants` call may affect both of
502 /// them; to write both, you must make multiple calls, each with the
503 /// appropriate `stages` value.
504 ///
505 /// Which pipeline stages may access a given byte is determined by the
506 /// pipeline's [`PushConstant`] global variable and (if it is a struct) its
507 /// members' offsets.
508 ///
509 /// For example, suppose you have twelve bytes of push constant storage,
510 /// where bytes `0..8` are accessed by the vertex shader, and bytes `4..12`
511 /// are accessed by the fragment shader. This means there are three byte
512 /// ranges each accessed by a different set of stages:
513 ///
514 /// - Bytes `0..4` are accessed only by the fragment shader.
515 ///
516 /// - Bytes `4..8` are accessed by both the fragment shader and the vertex shader.
517 ///
518 /// - Bytes `8..12` are accessed only by the vertex shader.
519 ///
520 /// To write all twelve bytes requires three `set_push_constants` calls, one
521 /// for each range, each passing the matching `stages` mask.
522 ///
523 /// [`PushConstant`]: https://docs.rs/naga/latest/naga/enum.StorageClass.html#variant.PushConstant
524 pub fn set_push_constants(&mut self, stages: ShaderStages, offset: u32, data: &[u8]) {
525 self.inner.set_push_constants(stages, offset, data);
526 }
527}
528
529/// [`Features::TIMESTAMP_QUERY_INSIDE_PASSES`] must be enabled on the device in order to call these functions.
530impl RenderPass<'_> {
531 /// Issue a timestamp command at this point in the queue. The
532 /// timestamp will be written to the specified query set, at the specified index.
533 ///
534 /// Must be multiplied by [`Queue::get_timestamp_period`] to get
535 /// the value in nanoseconds. Absolute values have no meaning,
536 /// but timestamps can be subtracted to get the time it takes
537 /// for a string of operations to complete.
538 pub fn write_timestamp(&mut self, query_set: &QuerySet, query_index: u32) {
539 self.inner.write_timestamp(&query_set.inner, query_index);
540 }
541}
542
543impl RenderPass<'_> {
544 /// Start a occlusion query on this render pass. It can be ended with
545 /// [`end_occlusion_query`](Self::end_occlusion_query).
546 /// Occlusion queries may not be nested.
547 pub fn begin_occlusion_query(&mut self, query_index: u32) {
548 self.inner.begin_occlusion_query(query_index);
549 }
550
551 /// End the occlusion query on this render pass. It can be started with
552 /// [`begin_occlusion_query`](Self::begin_occlusion_query).
553 /// Occlusion queries may not be nested.
554 pub fn end_occlusion_query(&mut self) {
555 self.inner.end_occlusion_query();
556 }
557}
558
559/// [`Features::PIPELINE_STATISTICS_QUERY`] must be enabled on the device in order to call these functions.
560impl RenderPass<'_> {
561 /// Start a pipeline statistics query on this render pass. It can be ended with
562 /// [`end_pipeline_statistics_query`](Self::end_pipeline_statistics_query).
563 /// Pipeline statistics queries may not be nested.
564 pub fn begin_pipeline_statistics_query(&mut self, query_set: &QuerySet, query_index: u32) {
565 self.inner
566 .begin_pipeline_statistics_query(&query_set.inner, query_index);
567 }
568
569 /// End the pipeline statistics query on this render pass. It can be started with
570 /// [`begin_pipeline_statistics_query`](Self::begin_pipeline_statistics_query).
571 /// Pipeline statistics queries may not be nested.
572 pub fn end_pipeline_statistics_query(&mut self) {
573 self.inner.end_pipeline_statistics_query();
574 }
575}
576
577/// Describes the timestamp writes of a render pass.
578///
579/// For use with [`RenderPassDescriptor`].
580/// At least one of [`Self::beginning_of_pass_write_index`] and [`Self::end_of_pass_write_index`]
581/// must be `Some`.
582///
583/// Corresponds to [WebGPU `GPURenderPassTimestampWrite`](
584/// https://gpuweb.github.io/gpuweb/#dictdef-gpurenderpasstimestampwrites).
585#[derive(Clone, Debug)]
586pub struct RenderPassTimestampWrites<'a> {
587 /// The query set to write to.
588 pub query_set: &'a QuerySet,
589 /// The index of the query set at which a start timestamp of this pass is written, if any.
590 pub beginning_of_pass_write_index: Option<u32>,
591 /// The index of the query set at which an end timestamp of this pass is written, if any.
592 pub end_of_pass_write_index: Option<u32>,
593}
594#[cfg(send_sync)]
595static_assertions::assert_impl_all!(RenderPassTimestampWrites<'_>: Send, Sync);
596
597/// Describes a color attachment to a [`RenderPass`].
598///
599/// For use with [`RenderPassDescriptor`].
600///
601/// Corresponds to [WebGPU `GPURenderPassColorAttachment`](
602/// https://gpuweb.github.io/gpuweb/#color-attachments).
603#[derive(Clone, Debug)]
604pub struct RenderPassColorAttachment<'tex> {
605 /// The view to use as an attachment.
606 pub view: &'tex TextureView,
607 /// The depth slice index of a 3D view. It must not be provided if the view is not 3D.
608 pub depth_slice: Option<u32>,
609 /// The view that will receive the resolved output if multisampling is used.
610 ///
611 /// If set, it is always written to, regardless of how [`Self::ops`] is configured.
612 pub resolve_target: Option<&'tex TextureView>,
613 /// What operations will be performed on this color attachment.
614 pub ops: Operations<Color>,
615}
616#[cfg(send_sync)]
617static_assertions::assert_impl_all!(RenderPassColorAttachment<'_>: Send, Sync);
618
619/// Describes a depth/stencil attachment to a [`RenderPass`].
620///
621/// For use with [`RenderPassDescriptor`].
622///
623/// Corresponds to [WebGPU `GPURenderPassDepthStencilAttachment`](
624/// https://gpuweb.github.io/gpuweb/#depth-stencil-attachments).
625#[derive(Clone, Debug)]
626pub struct RenderPassDepthStencilAttachment<'tex> {
627 /// The view to use as an attachment.
628 pub view: &'tex TextureView,
629 /// What operations will be performed on the depth part of the attachment.
630 pub depth_ops: Option<Operations<f32>>,
631 /// What operations will be performed on the stencil part of the attachment.
632 pub stencil_ops: Option<Operations<u32>>,
633}
634#[cfg(send_sync)]
635static_assertions::assert_impl_all!(RenderPassDepthStencilAttachment<'_>: Send, Sync);
636
637/// Describes the attachments of a render pass.
638///
639/// For use with [`CommandEncoder::begin_render_pass`].
640///
641/// Corresponds to [WebGPU `GPURenderPassDescriptor`](
642/// https://gpuweb.github.io/gpuweb/#dictdef-gpurenderpassdescriptor).
643#[derive(Clone, Debug, Default)]
644pub struct RenderPassDescriptor<'a> {
645 /// Debug label of the render pass. This will show up in graphics debuggers for easy identification.
646 pub label: Label<'a>,
647 /// The color attachments of the render pass.
648 pub color_attachments: &'a [Option<RenderPassColorAttachment<'a>>],
649 /// The depth and stencil attachment of the render pass, if any.
650 pub depth_stencil_attachment: Option<RenderPassDepthStencilAttachment<'a>>,
651 /// Defines which timestamp values will be written for this pass, and where to write them to.
652 ///
653 /// Requires [`Features::TIMESTAMP_QUERY`] to be enabled.
654 pub timestamp_writes: Option<RenderPassTimestampWrites<'a>>,
655 /// Defines where the occlusion query results will be stored for this pass.
656 pub occlusion_query_set: Option<&'a QuerySet>,
657}
658#[cfg(send_sync)]
659static_assertions::assert_impl_all!(RenderPassDescriptor<'_>: Send, Sync);