1use alloc::vec::Vec;
2use core::mem;
3use core::ops::Range;
4
5use super::{Api, Buffer, DeviceResult, Resource};
6
7#[derive(Debug)]
9pub struct CommandBuffer {
10 commands: Vec<Command>,
11}
12
13#[derive(Debug)]
14enum Command {
15 ClearBuffer {
16 buffer: Buffer,
17 range: crate::MemoryRange,
18 },
19 CopyBufferToBuffer {
20 src: Buffer,
21 dst: Buffer,
22 regions: Vec<crate::BufferCopy>,
23 },
24}
25
26impl CommandBuffer {
27 pub(crate) unsafe fn execute(&self) {
32 for command in &self.commands {
33 unsafe { command.execute() };
34 }
35 }
36
37 pub(crate) fn new() -> Self {
38 Self {
39 commands: Vec::new(),
40 }
41 }
42}
43
44impl crate::CommandEncoder for CommandBuffer {
45 type A = Api;
46
47 unsafe fn begin_encoding(&mut self, label: crate::Label) -> DeviceResult<()> {
48 assert!(self.commands.is_empty());
49 Ok(())
50 }
51 unsafe fn discard_encoding(&mut self) {
52 self.commands.clear();
53 }
54 unsafe fn end_encoding(&mut self) -> DeviceResult<CommandBuffer> {
55 Ok(CommandBuffer {
56 commands: mem::take(&mut self.commands),
57 })
58 }
59 unsafe fn reset_all<I>(&mut self, command_buffers: I) {}
60
61 unsafe fn transition_buffers<'a, T>(&mut self, barriers: T)
62 where
63 T: Iterator<Item = crate::BufferBarrier<'a, Buffer>>,
64 {
65 }
66
67 unsafe fn transition_textures<'a, T>(&mut self, barriers: T)
68 where
69 T: Iterator<Item = crate::TextureBarrier<'a, Resource>>,
70 {
71 }
72
73 unsafe fn clear_buffer(&mut self, buffer: &Buffer, range: crate::MemoryRange) {
74 self.commands.push(Command::ClearBuffer {
75 buffer: buffer.clone(),
76 range,
77 })
78 }
79
80 unsafe fn copy_buffer_to_buffer<T>(&mut self, src: &Buffer, dst: &Buffer, regions: T)
81 where
82 T: Iterator<Item = crate::BufferCopy>,
83 {
84 self.commands.push(Command::CopyBufferToBuffer {
85 src: src.clone(),
86 dst: dst.clone(),
87 regions: regions.collect(),
88 });
89 }
90
91 #[cfg(webgl)]
92 unsafe fn copy_external_image_to_texture<T>(
93 &mut self,
94 src: &wgt::CopyExternalImageSourceInfo,
95 dst: &Resource,
96 dst_premultiplication: bool,
97 regions: T,
98 ) where
99 T: Iterator<Item = crate::TextureCopy>,
100 {
101 }
102
103 unsafe fn copy_texture_to_texture<T>(
104 &mut self,
105 src: &Resource,
106 src_usage: wgt::TextureUses,
107 dst: &Resource,
108 regions: T,
109 ) {
110 }
112
113 unsafe fn copy_buffer_to_texture<T>(&mut self, src: &Buffer, dst: &Resource, regions: T) {
114 }
116
117 unsafe fn copy_texture_to_buffer<T>(
118 &mut self,
119 src: &Resource,
120 src_usage: wgt::TextureUses,
121 dst: &Buffer,
122 regions: T,
123 ) {
124 }
126
127 unsafe fn begin_query(&mut self, set: &Resource, index: u32) {}
128 unsafe fn end_query(&mut self, set: &Resource, index: u32) {}
129 unsafe fn write_timestamp(&mut self, set: &Resource, index: u32) {}
130 unsafe fn read_acceleration_structure_compact_size(
131 &mut self,
132 acceleration_structure: &Resource,
133 buf: &Buffer,
134 ) {
135 }
136 unsafe fn reset_queries(&mut self, set: &Resource, range: Range<u32>) {}
137 unsafe fn copy_query_results(
138 &mut self,
139 set: &Resource,
140 range: Range<u32>,
141 buffer: &Buffer,
142 offset: wgt::BufferAddress,
143 stride: wgt::BufferSize,
144 ) {
145 }
146
147 unsafe fn begin_render_pass(&mut self, desc: &crate::RenderPassDescriptor<Resource, Resource>) {
150 }
151 unsafe fn end_render_pass(&mut self) {}
152
153 unsafe fn set_bind_group(
154 &mut self,
155 layout: &Resource,
156 index: u32,
157 group: &Resource,
158 dynamic_offsets: &[wgt::DynamicOffset],
159 ) {
160 }
161 unsafe fn set_push_constants(
162 &mut self,
163 layout: &Resource,
164 stages: wgt::ShaderStages,
165 offset_bytes: u32,
166 data: &[u32],
167 ) {
168 }
169
170 unsafe fn insert_debug_marker(&mut self, label: &str) {}
171 unsafe fn begin_debug_marker(&mut self, group_label: &str) {}
172 unsafe fn end_debug_marker(&mut self) {}
173
174 unsafe fn set_render_pipeline(&mut self, pipeline: &Resource) {}
175
176 unsafe fn set_index_buffer<'a>(
177 &mut self,
178 binding: crate::BufferBinding<'a, Buffer>,
179 format: wgt::IndexFormat,
180 ) {
181 }
182 unsafe fn set_vertex_buffer<'a>(
183 &mut self,
184 index: u32,
185 binding: crate::BufferBinding<'a, Buffer>,
186 ) {
187 }
188 unsafe fn set_viewport(&mut self, rect: &crate::Rect<f32>, depth_range: Range<f32>) {}
189 unsafe fn set_scissor_rect(&mut self, rect: &crate::Rect<u32>) {}
190 unsafe fn set_stencil_reference(&mut self, value: u32) {}
191 unsafe fn set_blend_constants(&mut self, color: &[f32; 4]) {}
192
193 unsafe fn draw(
194 &mut self,
195 first_vertex: u32,
196 vertex_count: u32,
197 first_instance: u32,
198 instance_count: u32,
199 ) {
200 }
201 unsafe fn draw_indexed(
202 &mut self,
203 first_index: u32,
204 index_count: u32,
205 base_vertex: i32,
206 first_instance: u32,
207 instance_count: u32,
208 ) {
209 }
210 unsafe fn draw_mesh_tasks(
211 &mut self,
212 group_count_x: u32,
213 group_count_y: u32,
214 group_count_z: u32,
215 ) {
216 }
217 unsafe fn draw_indirect(
218 &mut self,
219 buffer: &Buffer,
220 offset: wgt::BufferAddress,
221 draw_count: u32,
222 ) {
223 }
224 unsafe fn draw_indexed_indirect(
225 &mut self,
226 buffer: &Buffer,
227 offset: wgt::BufferAddress,
228 draw_count: u32,
229 ) {
230 }
231 unsafe fn draw_mesh_tasks_indirect(
232 &mut self,
233 buffer: &<Self::A as crate::Api>::Buffer,
234 offset: wgt::BufferAddress,
235 draw_count: u32,
236 ) {
237 }
238 unsafe fn draw_indirect_count(
239 &mut self,
240 buffer: &Buffer,
241 offset: wgt::BufferAddress,
242 count_buffer: &Buffer,
243 count_offset: wgt::BufferAddress,
244 max_count: u32,
245 ) {
246 }
247 unsafe fn draw_indexed_indirect_count(
248 &mut self,
249 buffer: &Buffer,
250 offset: wgt::BufferAddress,
251 count_buffer: &Buffer,
252 count_offset: wgt::BufferAddress,
253 max_count: u32,
254 ) {
255 }
256 unsafe fn draw_mesh_tasks_indirect_count(
257 &mut self,
258 buffer: &<Self::A as crate::Api>::Buffer,
259 offset: wgt::BufferAddress,
260 count_buffer: &<Self::A as crate::Api>::Buffer,
261 count_offset: wgt::BufferAddress,
262 max_count: u32,
263 ) {
264 }
265
266 unsafe fn begin_compute_pass(&mut self, desc: &crate::ComputePassDescriptor<Resource>) {}
269 unsafe fn end_compute_pass(&mut self) {}
270
271 unsafe fn set_compute_pipeline(&mut self, pipeline: &Resource) {}
272
273 unsafe fn dispatch(&mut self, count: [u32; 3]) {}
274 unsafe fn dispatch_indirect(&mut self, buffer: &Buffer, offset: wgt::BufferAddress) {}
275
276 unsafe fn build_acceleration_structures<'a, T>(
277 &mut self,
278 _descriptor_count: u32,
279 descriptors: T,
280 ) where
281 Api: 'a,
282 T: IntoIterator<Item = crate::BuildAccelerationStructureDescriptor<'a, Buffer, Resource>>,
283 {
284 }
285
286 unsafe fn place_acceleration_structure_barrier(
287 &mut self,
288 _barriers: crate::AccelerationStructureBarrier,
289 ) {
290 }
291
292 unsafe fn copy_acceleration_structure_to_acceleration_structure(
293 &mut self,
294 src: &Resource,
295 dst: &Resource,
296 copy: wgt::AccelerationStructureCopy,
297 ) {
298 }
299}
300
301impl Command {
302 unsafe fn execute(&self) {
307 match self {
308 Command::ClearBuffer { ref buffer, range } => {
309 let buffer_slice: &mut [u8] = unsafe { &mut *buffer.get_slice_ptr(range.clone()) };
312 buffer_slice.fill(0);
313 }
314
315 Command::CopyBufferToBuffer { src, dst, regions } => {
316 for &crate::BufferCopy {
317 src_offset,
318 dst_offset,
319 size,
320 } in regions
321 {
322 let src_region: &[u8] =
325 unsafe { &*src.get_slice_ptr(src_offset..src_offset + size.get()) };
326 let dst_region: &mut [u8] =
327 unsafe { &mut *dst.get_slice_ptr(dst_offset..dst_offset + size.get()) };
328 dst_region.copy_from_slice(src_region);
329 }
330 }
331 }
332 }
333}