wgpu_hal/noop/
command.rs

1use alloc::vec::Vec;
2use core::mem;
3use core::ops::Range;
4
5use super::{Api, Buffer, DeviceResult, Resource};
6
7/// Command buffer type, which performs double duty as the command encoder type too.
8#[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    /// # Safety
28    ///
29    /// Must be called with appropriate synchronization for the resources affected by the command,
30    /// such as ensuring that buffers are not accessed by a command while aliasing references exist.
31    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        // TODO: consider implementing this and other texture manipulation
111    }
112
113    unsafe fn copy_buffer_to_texture<T>(&mut self, src: &Buffer, dst: &Resource, regions: T) {
114        // TODO: consider implementing this and other texture manipulation
115    }
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        // TODO: consider implementing this and other texture manipulation
125    }
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    // render
148
149    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    // compute
267
268    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    /// # Safety
303    ///
304    /// Must be called with appropriate synchronization for the resources affected by the command,
305    /// such as ensuring that buffers are not accessed by a command while aliasing references exist.
306    unsafe fn execute(&self) {
307        match self {
308            Command::ClearBuffer { ref buffer, range } => {
309                // SAFETY:
310                // Caller is responsible for ensuring this does not alias.
311                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                    // SAFETY:
323                    // Caller is responsible for ensuring this does not alias.
324                    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}