maplibre/render/resource/tracked_render_pass.rs
1//! A render pass which allows tracking, for example using a tracing framework.
2
3use std::ops::Range;
4
5/// A [`RenderPass`], which tracks the current pipeline state to ensure all draw calls are valid.
6/// It is used to set the current [`RenderPipeline`], [`BindGroups`](BindGroup) and buffers.
7/// After all requirements are specified, draw calls can be issued.
8pub struct TrackedRenderPass<'a> {
9 pass: wgpu::RenderPass<'a>,
10}
11
12impl<'a> TrackedRenderPass<'a> {
13 /// Tracks the supplied render pass.
14 pub fn new(pass: wgpu::RenderPass<'a>) -> Self {
15 Self { pass }
16 }
17
18 /// Sets the active [`RenderPipeline`].
19 ///
20 /// Subsequent draw calls will exhibit the behavior defined by the `pipeline`.
21 pub fn set_render_pipeline(&mut self, pipeline: &'a wgpu::RenderPipeline) {
22 self.pass.set_pipeline(pipeline);
23 }
24
25 /// Sets the active [`BindGroup`] for a given bind group index. The bind group layout in the
26 /// active pipeline when any `draw()` function is called must match the layout of this `bind group`.
27 pub fn set_bind_group(
28 &mut self,
29 index: usize,
30 bind_group: &'a wgpu::BindGroup,
31 dynamic_uniform_indices: &[u32],
32 ) {
33 self.pass
34 .set_bind_group(index as u32, bind_group, dynamic_uniform_indices);
35 }
36
37 /// Assign a vertex buffer to a slot.
38 ///
39 /// Subsequent calls to [`TrackedRenderPass::draw`] and [`TrackedRenderPass::draw_indexed`]
40 /// will use the buffer referenced by `buffer_slice` as one of the source vertex buffer(s).
41 ///
42 /// The `slot_index` refers to the index of the matching descriptor in
43 /// [`VertexState::buffers`](crate::render_resource::VertexState::buffers).
44 pub fn set_vertex_buffer(&mut self, slot_index: usize, buffer_slice: wgpu::BufferSlice<'a>) {
45 self.pass.set_vertex_buffer(slot_index as u32, buffer_slice);
46 }
47
48 /// Sets the active index buffer.
49 ///
50 /// Subsequent calls to [`TrackedRenderPass::draw_indexed`] will use the buffer referenced by
51 /// `buffer_slice` as the source index buffer.
52 pub fn set_index_buffer(
53 &mut self,
54 buffer_slice: wgpu::BufferSlice<'a>,
55 index_format: wgpu::IndexFormat,
56 ) {
57 self.pass.set_index_buffer(buffer_slice, index_format);
58 }
59
60 /// Draws primitives from the active vertex buffer(s).
61 ///
62 /// The active vertex buffer(s) can be set with [`TrackedRenderPass::set_vertex_buffer`].
63 pub fn draw(&mut self, vertices: Range<u32>, instances: Range<u32>) {
64 self.pass.draw(vertices, instances);
65 }
66
67 /// Draws indexed primitives using the active index buffer and the active vertex buffer(s).
68 ///
69 /// The active index buffer can be set with [`TrackedRenderPass::set_index_buffer`], while the
70 /// active vertex buffer(s) can be set with [`TrackedRenderPass::set_vertex_buffer`].
71 pub fn draw_indexed(&mut self, indices: Range<u32>, base_vertex: i32, instances: Range<u32>) {
72 self.pass.draw_indexed(indices, base_vertex, instances);
73 }
74
75 /// Draws primitives from the active vertex buffer(s) based on the contents of the `indirect_buffer`.
76 ///
77 /// The active vertex buffers can be set with [`TrackedRenderPass::set_vertex_buffer`].
78 ///
79 /// The structure expected in `indirect_buffer` is the following:
80 ///
81 /// ```rust
82 /// #[repr(C)]
83 /// struct DrawIndirect {
84 /// vertex_count: u32, // The number of vertices to draw.
85 /// instance_count: u32, // The number of instances to draw.
86 /// first_vertex: u32, // The Index of the first vertex to draw.
87 /// first_instance: u32, // The instance ID of the first instance to draw.
88 /// // has to be 0, unless [`Features::INDIRECT_FIRST_INSTANCE`] is enabled.
89 /// }
90 /// ```
91 pub fn draw_indirect(&mut self, indirect_buffer: &'a wgpu::Buffer, indirect_offset: u64) {
92 self.pass.draw_indirect(indirect_buffer, indirect_offset);
93 }
94
95 /// Draws indexed primitives using the active index buffer and the active vertex buffers,
96 /// based on the contents of the `indirect_buffer`.
97 ///
98 /// The active index buffer can be set with [`TrackedRenderPass::set_index_buffer`], while the active
99 /// vertex buffers can be set with [`TrackedRenderPass::set_vertex_buffer`].
100 ///
101 /// The structure expected in `indirect_buffer` is the following:
102 ///
103 /// ```rust
104 /// #[repr(C)]
105 /// struct DrawIndexedIndirect {
106 /// vertex_count: u32, // The number of vertices to draw.
107 /// instance_count: u32, // The number of instances to draw.
108 /// first_index: u32, // The base index within the index buffer.
109 /// vertex_offset: i32, // The value added to the vertex index before indexing into the vertex buffer.
110 /// first_instance: u32, // The instance ID of the first instance to draw.
111 /// // has to be 0, unless [`Features::INDIRECT_FIRST_INSTANCE`] is enabled.
112 /// }
113 /// ```
114 pub fn draw_indexed_indirect(
115 &mut self,
116 indirect_buffer: &'a wgpu::Buffer,
117 indirect_offset: u64,
118 ) {
119 self.pass
120 .draw_indexed_indirect(indirect_buffer, indirect_offset);
121 }
122
123 /// Sets the stencil reference.
124 ///
125 /// Subsequent stencil tests will test against this value.
126 pub fn set_stencil_reference(&mut self, reference: u32) {
127 self.pass.set_stencil_reference(reference);
128 }
129
130 /// Sets the scissor region.
131 ///
132 /// Subsequent draw calls will discard any fragments that fall outside this region.
133 pub fn set_scissor_rect(&mut self, x: u32, y: u32, width: u32, height: u32) {
134 self.pass.set_scissor_rect(x, y, width, height);
135 }
136
137 /// Set push constant data.
138 ///
139 /// `Features::PUSH_CONSTANTS` must be enabled on the device in order to call these functions.
140 pub fn set_push_constants(&mut self, stages: wgpu::ShaderStages, offset: u32, data: &[u8]) {
141 self.pass.set_push_constants(stages, offset, data);
142 }
143
144 /// Set the rendering viewport.
145 ///
146 /// Subsequent draw calls will be projected into that viewport.
147 pub fn set_viewport(
148 &mut self,
149 x: f32,
150 y: f32,
151 width: f32,
152 height: f32,
153 min_depth: f32,
154 max_depth: f32,
155 ) {
156 self.pass
157 .set_viewport(x, y, width, height, min_depth, max_depth);
158 }
159
160 /// Insert a single debug marker.
161 ///
162 /// This is a GPU debugging feature. This has no effect on the rendering itself.
163 pub fn insert_debug_marker(&mut self, label: &str) {
164 self.pass.insert_debug_marker(label);
165 }
166
167 /// Start a new debug group.
168 ///
169 /// Push a new debug group over the internal stack. Subsequent render commands and debug
170 /// markers are grouped into this new group, until [`pop_debug_group`] is called.
171 ///
172 /// ```
173 /// # fn example(mut pass: maplibre::render::resource::TrackedRenderPass<'static>) {
174 /// pass.push_debug_group("Render the car");
175 /// // [setup pipeline etc...]
176 /// pass.draw(0..64, 0..1);
177 /// pass.pop_debug_group();
178 /// # }
179 /// ```
180 ///
181 /// Note that [`push_debug_group`] and [`pop_debug_group`] must always be called in pairs.
182 ///
183 /// This is a GPU debugging feature. This has no effect on the rendering itself.
184 ///
185 /// [`push_debug_group`]: TrackedRenderPass::push_debug_group
186 /// [`pop_debug_group`]: TrackedRenderPass::pop_debug_group
187 pub fn push_debug_group(&mut self, label: &str) {
188 self.pass.push_debug_group(label);
189 }
190
191 /// End the current debug group.
192 ///
193 /// Subsequent render commands and debug markers are not grouped anymore in
194 /// this group, but in the previous one (if any) or the default top-level one
195 /// if the debug group was the last one on the stack.
196 ///
197 /// Note that [`push_debug_group`] and [`pop_debug_group`] must always be called in pairs.
198 ///
199 /// This is a GPU debugging feature. This has no effect on the rendering itself.
200 ///
201 /// [`push_debug_group`]: TrackedRenderPass::push_debug_group
202 /// [`pop_debug_group`]: TrackedRenderPass::pop_debug_group
203 pub fn pop_debug_group(&mut self) {
204 self.pass.pop_debug_group();
205 }
206
207 pub fn set_blend_constant(&mut self, color: wgpu::Color) {
208 self.pass.set_blend_constant(color);
209 }
210}