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