wgpu/util/
encoder.rs

1use core::ops::Range;
2
3use wgt::{BufferAddress, DynamicOffset, IndexFormat};
4
5use crate::{BindGroup, Buffer, BufferSlice, RenderBundleEncoder, RenderPass, RenderPipeline};
6
7/// Methods shared by [`RenderPass`] and [`RenderBundleEncoder`].
8pub trait RenderEncoder<'a> {
9    /// Sets the active bind group for a given bind group index. The bind group layout
10    /// in the active pipeline when any `draw()` function is called must match the layout of this bind group.
11    ///
12    /// If the bind group have dynamic offsets, provide them in order of their declaration.
13    fn set_bind_group(
14        &mut self,
15        index: u32,
16        bind_group: Option<&'a BindGroup>,
17        offsets: &[DynamicOffset],
18    );
19
20    /// Sets the active render pipeline.
21    ///
22    /// Subsequent draw calls will exhibit the behavior defined by `pipeline`.
23    fn set_pipeline(&mut self, pipeline: &'a RenderPipeline);
24
25    /// Sets the active index buffer.
26    ///
27    /// Subsequent calls to [`draw_indexed`](RenderEncoder::draw_indexed) on this [`RenderEncoder`] will
28    /// use `buffer` as the source index buffer.
29    fn set_index_buffer(&mut self, buffer_slice: BufferSlice<'a>, index_format: IndexFormat);
30
31    /// Assign a vertex buffer to a slot.
32    ///
33    /// Subsequent calls to [`draw`] and [`draw_indexed`] on this
34    /// [`RenderEncoder`] will use `buffer` as one of the source vertex buffers.
35    ///
36    /// The `slot` refers to the index of the matching descriptor in
37    /// [`VertexState::buffers`](crate::VertexState::buffers).
38    ///
39    /// [`draw`]: RenderEncoder::draw
40    /// [`draw_indexed`]: RenderEncoder::draw_indexed
41    fn set_vertex_buffer(&mut self, slot: u32, buffer_slice: BufferSlice<'a>);
42
43    /// Draws primitives from the active vertex buffer(s).
44    ///
45    /// The active vertex buffers can be set with [`RenderEncoder::set_vertex_buffer`].
46    fn draw(&mut self, vertices: Range<u32>, instances: Range<u32>);
47
48    /// Draws indexed primitives using the active index buffer and the active vertex buffers.
49    ///
50    /// The active index buffer can be set with [`RenderEncoder::set_index_buffer`], while the active
51    /// vertex buffers can be set with [`RenderEncoder::set_vertex_buffer`].
52    fn draw_indexed(&mut self, indices: Range<u32>, base_vertex: i32, instances: Range<u32>);
53
54    /// Draws primitives from the active vertex buffer(s) based on the contents of the `indirect_buffer`.
55    ///
56    /// The active vertex buffers can be set with [`RenderEncoder::set_vertex_buffer`].
57    ///
58    /// The structure expected in `indirect_buffer` must conform to [`DrawIndirectArgs`](crate::util::DrawIndirectArgs).
59    fn draw_indirect(&mut self, indirect_buffer: &'a Buffer, indirect_offset: BufferAddress);
60
61    /// Draws indexed primitives using the active index buffer and the active vertex buffers,
62    /// based on the contents of the `indirect_buffer`.
63    ///
64    /// The active index buffer can be set with [`RenderEncoder::set_index_buffer`], while the active
65    /// vertex buffers can be set with [`RenderEncoder::set_vertex_buffer`].
66    ///
67    /// The structure expected in `indirect_buffer` must conform to [`DrawIndexedIndirectArgs`](crate::util::DrawIndexedIndirectArgs).
68    fn draw_indexed_indirect(
69        &mut self,
70        indirect_buffer: &'a Buffer,
71        indirect_offset: BufferAddress,
72    );
73
74    /// [`wgt::Features::IMMEDIATES`] must be enabled on the device in order to call this function.
75    ///
76    /// Set immediate data for subsequent draw calls.
77    ///
78    /// Write the bytes in `data` at offset `offset` within immediate data
79    /// storage. Both `offset` and the length of `data` must be
80    /// multiples of [`crate::IMMEDIATE_DATA_ALIGNMENT`], which is always 4.
81    ///
82    /// For example, if `offset` is `4` and `data` is eight bytes long, this
83    /// call will write `data` to bytes `4..12` of immediate data storage.
84    fn set_immediates(&mut self, offset: u32, data: &[u8]);
85}
86
87impl<'a> RenderEncoder<'a> for RenderPass<'a> {
88    #[inline(always)]
89    fn set_bind_group(
90        &mut self,
91        index: u32,
92        bind_group: Option<&'a BindGroup>,
93        offsets: &[DynamicOffset],
94    ) {
95        Self::set_bind_group(self, index, bind_group, offsets);
96    }
97
98    #[inline(always)]
99    fn set_pipeline(&mut self, pipeline: &'a RenderPipeline) {
100        Self::set_pipeline(self, pipeline);
101    }
102
103    #[inline(always)]
104    fn set_index_buffer(&mut self, buffer_slice: BufferSlice<'a>, index_format: IndexFormat) {
105        Self::set_index_buffer(self, buffer_slice, index_format);
106    }
107
108    #[inline(always)]
109    fn set_vertex_buffer(&mut self, slot: u32, buffer_slice: BufferSlice<'a>) {
110        Self::set_vertex_buffer(self, slot, buffer_slice);
111    }
112
113    #[inline(always)]
114    fn draw(&mut self, vertices: Range<u32>, instances: Range<u32>) {
115        Self::draw(self, vertices, instances);
116    }
117
118    #[inline(always)]
119    fn draw_indexed(&mut self, indices: Range<u32>, base_vertex: i32, instances: Range<u32>) {
120        Self::draw_indexed(self, indices, base_vertex, instances);
121    }
122
123    #[inline(always)]
124    fn draw_indirect(&mut self, indirect_buffer: &'a Buffer, indirect_offset: BufferAddress) {
125        Self::draw_indirect(self, indirect_buffer, indirect_offset);
126    }
127
128    #[inline(always)]
129    fn draw_indexed_indirect(
130        &mut self,
131        indirect_buffer: &'a Buffer,
132        indirect_offset: BufferAddress,
133    ) {
134        Self::draw_indexed_indirect(self, indirect_buffer, indirect_offset);
135    }
136
137    #[inline(always)]
138    fn set_immediates(&mut self, offset: u32, data: &[u8]) {
139        Self::set_immediates(self, offset, data);
140    }
141}
142
143impl<'a> RenderEncoder<'a> for RenderBundleEncoder<'a> {
144    #[inline(always)]
145    fn set_bind_group(
146        &mut self,
147        index: u32,
148        bind_group: Option<&'a BindGroup>,
149        offsets: &[DynamicOffset],
150    ) {
151        Self::set_bind_group(self, index, bind_group, offsets);
152    }
153
154    #[inline(always)]
155    fn set_pipeline(&mut self, pipeline: &'a RenderPipeline) {
156        Self::set_pipeline(self, pipeline);
157    }
158
159    #[inline(always)]
160    fn set_index_buffer(&mut self, buffer_slice: BufferSlice<'a>, index_format: IndexFormat) {
161        Self::set_index_buffer(self, buffer_slice, index_format);
162    }
163
164    #[inline(always)]
165    fn set_vertex_buffer(&mut self, slot: u32, buffer_slice: BufferSlice<'a>) {
166        Self::set_vertex_buffer(self, slot, buffer_slice);
167    }
168
169    #[inline(always)]
170    fn draw(&mut self, vertices: Range<u32>, instances: Range<u32>) {
171        Self::draw(self, vertices, instances);
172    }
173
174    #[inline(always)]
175    fn draw_indexed(&mut self, indices: Range<u32>, base_vertex: i32, instances: Range<u32>) {
176        Self::draw_indexed(self, indices, base_vertex, instances);
177    }
178
179    #[inline(always)]
180    fn draw_indirect(&mut self, indirect_buffer: &'a Buffer, indirect_offset: BufferAddress) {
181        Self::draw_indirect(self, indirect_buffer, indirect_offset);
182    }
183
184    #[inline(always)]
185    fn draw_indexed_indirect(
186        &mut self,
187        indirect_buffer: &'a Buffer,
188        indirect_offset: BufferAddress,
189    ) {
190        Self::draw_indexed_indirect(self, indirect_buffer, indirect_offset);
191    }
192
193    #[inline(always)]
194    fn set_immediates(&mut self, offset: u32, data: &[u8]) {
195        Self::set_immediates(self, offset, data);
196    }
197}