wgpu/api/render_pass.rs
1use core::{num::NonZeroU32, 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 pipeline.
235 ///
236 /// The current pipeline must be a mesh pipeline.
237 ///
238 /// If the current pipeline has a task shader, run it with an workgroup for
239 /// every `vec3<u32>(i, j, k)` where `i`, `j`, and `k` are between `0` and
240 /// `group_count_x`, `group_count_y`, and `group_count_z`. The invocation with
241 /// index zero in each group is responsible for determining the mesh shader dispatch.
242 /// Its return value indicates the number of workgroups of mesh shaders to invoke. It also
243 /// passes a payload value for them to consume. Because each task workgroup is essentially
244 /// a mesh shader draw call, mesh workgroups dispatched by different task workgroups
245 /// cannot interact in any way, and `workgroup_id` corresponds to its location in the
246 /// calling specific task shader's dispatch group.
247 ///
248 /// If the current pipeline lacks a task shader, run its mesh shader with a
249 /// workgroup for every `vec3<u32>(i, j, k)` where `i`, `j`, and `k` are
250 /// between `0` and `group_count_x`, `group_count_y`, and `group_count_z`.
251 ///
252 /// Each mesh shader workgroup outputs a set of vertices and indices for primitives.
253 /// The indices outputted correspond to the vertices outputted by that same workgroup;
254 /// there is no global vertex buffer. These primitives are passed to the rasterizer and
255 /// essentially treated like a vertex shader output, except that the mesh shader may
256 /// choose to cull specific primitives or pass per-primitive non-interpolated values
257 /// to the fragment shader. As such, each primitive is then rendered with the current
258 /// pipeline's fragment shader, if present. Otherwise, [No Color Output mode] is used.
259 ///
260 /// [No Color Output mode]: https://www.w3.org/TR/webgpu/#no-color-output
261 pub fn draw_mesh_tasks(&mut self, group_count_x: u32, group_count_y: u32, group_count_z: u32) {
262 self.inner
263 .draw_mesh_tasks(group_count_x, group_count_y, group_count_z);
264 }
265
266 /// Draws primitives from the active vertex buffer(s) based on the contents of the `indirect_buffer`.
267 ///
268 /// This is like calling [`RenderPass::draw`] but the contents of the call are specified in the `indirect_buffer`.
269 /// The structure expected in `indirect_buffer` must conform to [`DrawIndirectArgs`](crate::util::DrawIndirectArgs).
270 ///
271 /// Calling this requires the device support [`DownlevelFlags::INDIRECT_EXECUTION`].
272 pub fn draw_indirect(&mut self, indirect_buffer: &Buffer, indirect_offset: BufferAddress) {
273 self.inner
274 .draw_indirect(&indirect_buffer.inner, indirect_offset);
275 }
276
277 /// Draws indexed primitives using the active index buffer and the active vertex buffers,
278 /// based on the contents of the `indirect_buffer`.
279 ///
280 /// This is like calling [`RenderPass::draw_indexed`] but the contents of the call are specified in the `indirect_buffer`.
281 /// The structure expected in `indirect_buffer` must conform to [`DrawIndexedIndirectArgs`](crate::util::DrawIndexedIndirectArgs).
282 ///
283 /// Calling this requires the device support [`DownlevelFlags::INDIRECT_EXECUTION`].
284 pub fn draw_indexed_indirect(
285 &mut self,
286 indirect_buffer: &Buffer,
287 indirect_offset: BufferAddress,
288 ) {
289 self.inner
290 .draw_indexed_indirect(&indirect_buffer.inner, indirect_offset);
291 }
292
293 /// Draws using a mesh pipeline,
294 /// based on the contents of the `indirect_buffer`
295 ///
296 /// This is like calling [`RenderPass::draw_mesh_tasks`] but the contents of the call are specified in the `indirect_buffer`.
297 /// The structure expected in the `indirect_buffer` must conform to [`DispatchIndirectArgs`](crate::util::DispatchIndirectArgs).
298 ///
299 /// Indirect drawing has some caveats depending on the features available. We are not currently able to validate
300 /// these and issue an error.
301 ///
302 /// See details on the individual flags for more information.
303 pub fn draw_mesh_tasks_indirect(
304 &mut self,
305 indirect_buffer: &Buffer,
306 indirect_offset: BufferAddress,
307 ) {
308 self.inner
309 .draw_mesh_tasks_indirect(&indirect_buffer.inner, indirect_offset);
310 }
311
312 impl_deferred_command_buffer_actions!();
313
314 /// Execute a [render bundle][RenderBundle], which is a set of pre-recorded commands
315 /// that can be run together.
316 ///
317 /// Commands in the bundle do not inherit this render pass's current render state, and after the
318 /// bundle has executed, the state is **cleared** (reset to defaults, not the previous state).
319 pub fn execute_bundles<'a, I: IntoIterator<Item = &'a RenderBundle>>(
320 &mut self,
321 render_bundles: I,
322 ) {
323 let mut render_bundles = render_bundles.into_iter().map(|rb| &rb.inner);
324
325 self.inner.execute_bundles(&mut render_bundles);
326 }
327
328 /// Dispatches multiple draw calls from the active vertex buffer(s) based on the contents of the `indirect_buffer`.
329 /// `count` draw calls are issued.
330 ///
331 /// The active vertex buffers can be set with [`RenderPass::set_vertex_buffer`].
332 ///
333 /// The structure expected in `indirect_buffer` must conform to [`DrawIndirectArgs`](crate::util::DrawIndirectArgs).
334 /// These draw structures are expected to be tightly packed.
335 ///
336 /// Calling this requires the device support [`DownlevelFlags::INDIRECT_EXECUTION`].
337 ///
338 /// This drawing command uses the current render state, as set by preceding `set_*()` methods.
339 /// It is not affected by changes to the state that are performed after it is called.
340 pub fn multi_draw_indirect(
341 &mut self,
342 indirect_buffer: &Buffer,
343 indirect_offset: BufferAddress,
344 count: u32,
345 ) {
346 self.inner
347 .multi_draw_indirect(&indirect_buffer.inner, indirect_offset, count);
348 }
349
350 /// Dispatches multiple draw calls from the active index buffer and the active vertex buffers,
351 /// based on the contents of the `indirect_buffer`. `count` draw calls are issued.
352 ///
353 /// The active index buffer can be set with [`RenderPass::set_index_buffer`], while the active
354 /// vertex buffers can be set with [`RenderPass::set_vertex_buffer`].
355 ///
356 /// The structure expected in `indirect_buffer` must conform to [`DrawIndexedIndirectArgs`](crate::util::DrawIndexedIndirectArgs).
357 /// These draw structures are expected to be tightly packed.
358 ///
359 /// Calling this requires the device support [`DownlevelFlags::INDIRECT_EXECUTION`].
360 ///
361 /// This drawing command uses the current render state, as set by preceding `set_*()` methods.
362 /// It is not affected by changes to the state that are performed after it is called.
363 pub fn multi_draw_indexed_indirect(
364 &mut self,
365 indirect_buffer: &Buffer,
366 indirect_offset: BufferAddress,
367 count: u32,
368 ) {
369 self.inner
370 .multi_draw_indexed_indirect(&indirect_buffer.inner, indirect_offset, count);
371 }
372
373 /// Dispatches multiple draw calls based on the contents of the `indirect_buffer`.
374 /// `count` draw calls are issued.
375 ///
376 /// The structure expected in the `indirect_buffer` must conform to [`DispatchIndirectArgs`](crate::util::DispatchIndirectArgs).
377 ///
378 /// This drawing command uses the current render state, as set by preceding `set_*()` methods.
379 /// It is not affected by changes to the state that are performed after it is called.
380 pub fn multi_draw_mesh_tasks_indirect(
381 &mut self,
382 indirect_buffer: &Buffer,
383 indirect_offset: BufferAddress,
384 count: u32,
385 ) {
386 self.inner
387 .multi_draw_mesh_tasks_indirect(&indirect_buffer.inner, indirect_offset, count);
388 }
389
390 #[cfg(custom)]
391 /// Returns custom implementation of RenderPass (if custom backend and is internally T)
392 pub fn as_custom<T: custom::RenderPassInterface>(&self) -> Option<&T> {
393 self.inner.as_custom()
394 }
395}
396
397/// [`Features::MULTI_DRAW_INDIRECT_COUNT`] must be enabled on the device in order to call these functions.
398impl RenderPass<'_> {
399 /// Dispatches multiple draw calls from the active vertex buffer(s) based on the contents of the `indirect_buffer`.
400 /// The count buffer is read to determine how many draws to issue.
401 ///
402 /// The indirect buffer must be long enough to account for `max_count` draws, however only `count`
403 /// draws will be read. If `count` is greater than `max_count`, `max_count` will be used.
404 ///
405 /// The active vertex buffers can be set with [`RenderPass::set_vertex_buffer`].
406 ///
407 /// The structure expected in `indirect_buffer` must conform to [`DrawIndirectArgs`](crate::util::DrawIndirectArgs).
408 /// These draw structures are expected to be tightly packed.
409 ///
410 /// The structure expected in `count_buffer` is the following:
411 ///
412 /// ```rust
413 /// #[repr(C)]
414 /// struct DrawIndirectCount {
415 /// count: u32, // Number of draw calls to issue.
416 /// }
417 /// ```
418 ///
419 /// This drawing command uses the current render state, as set by preceding `set_*()` methods.
420 /// It is not affected by changes to the state that are performed after it is called.
421 pub fn multi_draw_indirect_count(
422 &mut self,
423 indirect_buffer: &Buffer,
424 indirect_offset: BufferAddress,
425 count_buffer: &Buffer,
426 count_offset: BufferAddress,
427 max_count: u32,
428 ) {
429 self.inner.multi_draw_indirect_count(
430 &indirect_buffer.inner,
431 indirect_offset,
432 &count_buffer.inner,
433 count_offset,
434 max_count,
435 );
436 }
437
438 /// Dispatches multiple draw calls from the active index buffer and the active vertex buffers,
439 /// based on the contents of the `indirect_buffer`. The count buffer is read to determine how many draws to issue.
440 ///
441 /// The indirect buffer must be long enough to account for `max_count` draws, however only `count`
442 /// draws will be read. If `count` is greater than `max_count`, `max_count` will be used.
443 ///
444 /// The active index buffer can be set with [`RenderPass::set_index_buffer`], while the active
445 /// vertex buffers can be set with [`RenderPass::set_vertex_buffer`].
446 ///
447 /// The structure expected in `indirect_buffer` must conform to [`DrawIndexedIndirectArgs`](crate::util::DrawIndexedIndirectArgs).
448 ///
449 /// These draw structures are expected to be tightly packed.
450 ///
451 /// The structure expected in `count_buffer` is the following:
452 ///
453 /// ```rust
454 /// #[repr(C)]
455 /// struct DrawIndexedIndirectCount {
456 /// count: u32, // Number of draw calls to issue.
457 /// }
458 /// ```
459 ///
460 /// This drawing command uses the current render state, as set by preceding `set_*()` methods.
461 /// It is not affected by changes to the state that are performed after it is called.
462 pub fn multi_draw_indexed_indirect_count(
463 &mut self,
464 indirect_buffer: &Buffer,
465 indirect_offset: BufferAddress,
466 count_buffer: &Buffer,
467 count_offset: BufferAddress,
468 max_count: u32,
469 ) {
470 self.inner.multi_draw_indexed_indirect_count(
471 &indirect_buffer.inner,
472 indirect_offset,
473 &count_buffer.inner,
474 count_offset,
475 max_count,
476 );
477 }
478
479 /// Dispatches multiple draw calls based on the contents of the `indirect_buffer`. The count buffer is read to determine how many draws to issue.
480 ///
481 /// The indirect buffer must be long enough to account for `max_count` draws, however only `count`
482 /// draws will be read. If `count` is greater than `max_count`, `max_count` will be used.
483 ///
484 /// The structure expected in the `indirect_buffer` must conform to [`DispatchIndirectArgs`](crate::util::DispatchIndirectArgs).
485 ///
486 /// These draw structures are expected to be tightly packed.
487 ///
488 /// This drawing command uses the current render state, as set by preceding `set_*()` methods.
489 /// It is not affected by changes to the state that are performed after it is called.
490 pub fn multi_draw_mesh_tasks_indirect_count(
491 &mut self,
492 indirect_buffer: &Buffer,
493 indirect_offset: BufferAddress,
494 count_buffer: &Buffer,
495 count_offset: BufferAddress,
496 max_count: u32,
497 ) {
498 self.inner.multi_draw_mesh_tasks_indirect_count(
499 &indirect_buffer.inner,
500 indirect_offset,
501 &count_buffer.inner,
502 count_offset,
503 max_count,
504 );
505 }
506}
507
508/// [`Features::IMMEDIATES`] must be enabled on the device in order to call these functions.
509impl RenderPass<'_> {
510 /// Set immediate data data for subsequent draw calls.
511 ///
512 /// Write the bytes in `data` at offset `offset` within immediate data
513 /// storage, all of which are accessible by all the pipeline stages in
514 /// `stages`, and no others. Both `offset` and the length of `data` must be
515 /// multiples of [`IMMEDIATES_ALIGNMENT`], which is always 4.
516 ///
517 /// For example, if `offset` is `4` and `data` is eight bytes long, this
518 /// call will write `data` to bytes `4..12` of immediate data storage.
519 ///
520 /// # Stage matching
521 ///
522 /// Every byte in the affected range of immediate data storage must be
523 /// accessible to exactly the same set of pipeline stages, which must match
524 /// `stages`. If there are two bytes of storage that are accessible by
525 /// different sets of pipeline stages - say, one is accessible by fragment
526 /// shaders, and the other is accessible by both fragment shaders and vertex
527 /// shaders - then no single `set_immediates` call may affect both of
528 /// them; to write both, you must make multiple calls, each with the
529 /// appropriate `stages` value.
530 ///
531 /// Which pipeline stages may access a given byte is determined by the
532 /// pipeline's [`Immediate`] global variable and (if it is a struct) its
533 /// members' offsets.
534 ///
535 /// For example, suppose you have twelve bytes of immediate data storage,
536 /// where bytes `0..8` are accessed by the vertex shader, and bytes `4..12`
537 /// are accessed by the fragment shader. This means there are three byte
538 /// ranges each accessed by a different set of stages:
539 ///
540 /// - Bytes `0..4` are accessed only by the fragment shader.
541 ///
542 /// - Bytes `4..8` are accessed by both the fragment shader and the vertex shader.
543 ///
544 /// - Bytes `8..12` are accessed only by the vertex shader.
545 ///
546 /// To write all twelve bytes requires three `set_immediates` calls, one
547 /// for each range, each passing the matching `stages` mask.
548 ///
549 /// [`Immediate`]: https://docs.rs/naga/latest/naga/enum.StorageClass.html#variant.Immediate
550 pub fn set_immediates(&mut self, stages: ShaderStages, offset: u32, data: &[u8]) {
551 self.inner.set_immediates(stages, offset, data);
552 }
553}
554
555/// [`Features::TIMESTAMP_QUERY_INSIDE_PASSES`] must be enabled on the device in order to call these functions.
556impl RenderPass<'_> {
557 /// Issue a timestamp command at this point in the queue. The
558 /// timestamp will be written to the specified query set, at the specified index.
559 ///
560 /// Must be multiplied by [`Queue::get_timestamp_period`] to get
561 /// the value in nanoseconds. Absolute values have no meaning,
562 /// but timestamps can be subtracted to get the time it takes
563 /// for a string of operations to complete.
564 pub fn write_timestamp(&mut self, query_set: &QuerySet, query_index: u32) {
565 self.inner.write_timestamp(&query_set.inner, query_index);
566 }
567}
568
569impl RenderPass<'_> {
570 /// Start a occlusion query on this render pass. It can be ended with
571 /// [`end_occlusion_query`](Self::end_occlusion_query).
572 /// Occlusion queries may not be nested.
573 pub fn begin_occlusion_query(&mut self, query_index: u32) {
574 self.inner.begin_occlusion_query(query_index);
575 }
576
577 /// End the occlusion query on this render pass. It can be started with
578 /// [`begin_occlusion_query`](Self::begin_occlusion_query).
579 /// Occlusion queries may not be nested.
580 pub fn end_occlusion_query(&mut self) {
581 self.inner.end_occlusion_query();
582 }
583}
584
585/// [`Features::PIPELINE_STATISTICS_QUERY`] must be enabled on the device in order to call these functions.
586impl RenderPass<'_> {
587 /// Start a pipeline statistics query on this render pass. It can be ended with
588 /// [`end_pipeline_statistics_query`](Self::end_pipeline_statistics_query).
589 /// Pipeline statistics queries may not be nested.
590 pub fn begin_pipeline_statistics_query(&mut self, query_set: &QuerySet, query_index: u32) {
591 self.inner
592 .begin_pipeline_statistics_query(&query_set.inner, query_index);
593 }
594
595 /// End the pipeline statistics query on this render pass. It can be started with
596 /// [`begin_pipeline_statistics_query`](Self::begin_pipeline_statistics_query).
597 /// Pipeline statistics queries may not be nested.
598 pub fn end_pipeline_statistics_query(&mut self) {
599 self.inner.end_pipeline_statistics_query();
600 }
601}
602
603/// Describes the timestamp writes of a render pass.
604///
605/// For use with [`RenderPassDescriptor`].
606/// At least one of [`Self::beginning_of_pass_write_index`] and [`Self::end_of_pass_write_index`]
607/// must be `Some`.
608///
609/// Corresponds to [WebGPU `GPURenderPassTimestampWrite`](
610/// https://gpuweb.github.io/gpuweb/#dictdef-gpurenderpasstimestampwrites).
611#[derive(Clone, Debug)]
612pub struct RenderPassTimestampWrites<'a> {
613 /// The query set to write to.
614 pub query_set: &'a QuerySet,
615 /// The index of the query set at which a start timestamp of this pass is written, if any.
616 pub beginning_of_pass_write_index: Option<u32>,
617 /// The index of the query set at which an end timestamp of this pass is written, if any.
618 pub end_of_pass_write_index: Option<u32>,
619}
620#[cfg(send_sync)]
621static_assertions::assert_impl_all!(RenderPassTimestampWrites<'_>: Send, Sync);
622
623/// Describes a color attachment to a [`RenderPass`].
624///
625/// For use with [`RenderPassDescriptor`].
626///
627/// Corresponds to [WebGPU `GPURenderPassColorAttachment`](
628/// https://gpuweb.github.io/gpuweb/#color-attachments).
629#[derive(Clone, Debug)]
630pub struct RenderPassColorAttachment<'tex> {
631 /// The view to use as an attachment.
632 pub view: &'tex TextureView,
633 /// The depth slice index of a 3D view. It must not be provided if the view is not 3D.
634 pub depth_slice: Option<u32>,
635 /// The view that will receive the resolved output if multisampling is used.
636 ///
637 /// If set, it is always written to, regardless of how [`Self::ops`] is configured.
638 pub resolve_target: Option<&'tex TextureView>,
639 /// What operations will be performed on this color attachment.
640 pub ops: Operations<Color>,
641}
642#[cfg(send_sync)]
643static_assertions::assert_impl_all!(RenderPassColorAttachment<'_>: Send, Sync);
644
645/// Describes a depth/stencil attachment to a [`RenderPass`].
646///
647/// For use with [`RenderPassDescriptor`].
648///
649/// Corresponds to [WebGPU `GPURenderPassDepthStencilAttachment`](
650/// https://gpuweb.github.io/gpuweb/#depth-stencil-attachments).
651#[derive(Clone, Debug)]
652pub struct RenderPassDepthStencilAttachment<'tex> {
653 /// The view to use as an attachment.
654 pub view: &'tex TextureView,
655 /// What operations will be performed on the depth part of the attachment.
656 pub depth_ops: Option<Operations<f32>>,
657 /// What operations will be performed on the stencil part of the attachment.
658 pub stencil_ops: Option<Operations<u32>>,
659}
660#[cfg(send_sync)]
661static_assertions::assert_impl_all!(RenderPassDepthStencilAttachment<'_>: Send, Sync);
662
663/// Describes the attachments of a render pass.
664///
665/// For use with [`CommandEncoder::begin_render_pass`].
666///
667/// Corresponds to [WebGPU `GPURenderPassDescriptor`](
668/// https://gpuweb.github.io/gpuweb/#dictdef-gpurenderpassdescriptor).
669#[derive(Clone, Debug, Default)]
670pub struct RenderPassDescriptor<'a> {
671 /// Debug label of the render pass. This will show up in graphics debuggers for easy identification.
672 pub label: Label<'a>,
673 /// The color attachments of the render pass.
674 pub color_attachments: &'a [Option<RenderPassColorAttachment<'a>>],
675 /// The depth and stencil attachment of the render pass, if any.
676 pub depth_stencil_attachment: Option<RenderPassDepthStencilAttachment<'a>>,
677 /// Defines which timestamp values will be written for this pass, and where to write them to.
678 ///
679 /// Requires [`Features::TIMESTAMP_QUERY`] to be enabled.
680 pub timestamp_writes: Option<RenderPassTimestampWrites<'a>>,
681 /// Defines where the occlusion query results will be stored for this pass.
682 pub occlusion_query_set: Option<&'a QuerySet>,
683 /// The mask of multiview image layers to use for this render pass. For example, if you wish
684 /// to render to the first 2 layers, you would use 3=0b11. If you wanted ro render to only the
685 /// 2nd layer, you would use 2=0b10. If you aren't using multiview this should be `None`.
686 ///
687 /// Note that setting bits higher than the number of texture layers is a validation error.
688 ///
689 /// This doesn't influence load/store/clear/etc operations, as those are defined for attachments,
690 /// therefore affecting all attachments. Meaning, this affects only any shaders executed on the `RenderPass`.
691 pub multiview_mask: Option<NonZeroU32>,
692}
693#[cfg(send_sync)]
694static_assertions::assert_impl_all!(RenderPassDescriptor<'_>: Send, Sync);