use alloc::vec::Vec;
use core::mem;
use core::ops::Range;
use super::{Api, Buffer, DeviceResult, Resource};
#[derive(Debug)]
pub struct CommandBuffer {
commands: Vec<Command>,
}
#[derive(Debug)]
enum Command {
ClearBuffer {
buffer: Buffer,
range: crate::MemoryRange,
},
CopyBufferToBuffer {
src: Buffer,
dst: Buffer,
regions: Vec<crate::BufferCopy>,
},
}
impl CommandBuffer {
pub(crate) unsafe fn execute(&self) {
for command in &self.commands {
unsafe { command.execute() };
}
}
pub(crate) fn new() -> Self {
Self {
commands: Vec::new(),
}
}
}
impl crate::CommandEncoder for CommandBuffer {
type A = Api;
unsafe fn begin_encoding(&mut self, label: crate::Label) -> DeviceResult<()> {
assert!(self.commands.is_empty());
Ok(())
}
unsafe fn discard_encoding(&mut self) {
self.commands.clear();
}
unsafe fn end_encoding(&mut self) -> DeviceResult<CommandBuffer> {
Ok(CommandBuffer {
commands: mem::take(&mut self.commands),
})
}
unsafe fn reset_all<I>(&mut self, command_buffers: I) {}
unsafe fn transition_buffers<'a, T>(&mut self, barriers: T)
where
T: Iterator<Item = crate::BufferBarrier<'a, Buffer>>,
{
}
unsafe fn transition_textures<'a, T>(&mut self, barriers: T)
where
T: Iterator<Item = crate::TextureBarrier<'a, Resource>>,
{
}
unsafe fn clear_buffer(&mut self, buffer: &Buffer, range: crate::MemoryRange) {
self.commands.push(Command::ClearBuffer {
buffer: buffer.clone(),
range,
})
}
unsafe fn copy_buffer_to_buffer<T>(&mut self, src: &Buffer, dst: &Buffer, regions: T)
where
T: Iterator<Item = crate::BufferCopy>,
{
self.commands.push(Command::CopyBufferToBuffer {
src: src.clone(),
dst: dst.clone(),
regions: regions.collect(),
});
}
#[cfg(webgl)]
unsafe fn copy_external_image_to_texture<T>(
&mut self,
src: &wgt::CopyExternalImageSourceInfo,
dst: &Resource,
dst_premultiplication: bool,
regions: T,
) where
T: Iterator<Item = crate::TextureCopy>,
{
}
unsafe fn copy_texture_to_texture<T>(
&mut self,
src: &Resource,
src_usage: wgt::TextureUses,
dst: &Resource,
regions: T,
) {
}
unsafe fn copy_buffer_to_texture<T>(&mut self, src: &Buffer, dst: &Resource, regions: T) {
}
unsafe fn copy_texture_to_buffer<T>(
&mut self,
src: &Resource,
src_usage: wgt::TextureUses,
dst: &Buffer,
regions: T,
) {
}
unsafe fn begin_query(&mut self, set: &Resource, index: u32) {}
unsafe fn end_query(&mut self, set: &Resource, index: u32) {}
unsafe fn write_timestamp(&mut self, set: &Resource, index: u32) {}
unsafe fn read_acceleration_structure_compact_size(
&mut self,
acceleration_structure: &Resource,
buf: &Buffer,
) {
}
unsafe fn reset_queries(&mut self, set: &Resource, range: Range<u32>) {}
unsafe fn copy_query_results(
&mut self,
set: &Resource,
range: Range<u32>,
buffer: &Buffer,
offset: wgt::BufferAddress,
stride: wgt::BufferSize,
) {
}
unsafe fn begin_render_pass(&mut self, desc: &crate::RenderPassDescriptor<Resource, Resource>) {
}
unsafe fn end_render_pass(&mut self) {}
unsafe fn set_bind_group(
&mut self,
layout: &Resource,
index: u32,
group: &Resource,
dynamic_offsets: &[wgt::DynamicOffset],
) {
}
unsafe fn set_push_constants(
&mut self,
layout: &Resource,
stages: wgt::ShaderStages,
offset_bytes: u32,
data: &[u32],
) {
}
unsafe fn insert_debug_marker(&mut self, label: &str) {}
unsafe fn begin_debug_marker(&mut self, group_label: &str) {}
unsafe fn end_debug_marker(&mut self) {}
unsafe fn set_render_pipeline(&mut self, pipeline: &Resource) {}
unsafe fn set_index_buffer<'a>(
&mut self,
binding: crate::BufferBinding<'a, Buffer>,
format: wgt::IndexFormat,
) {
}
unsafe fn set_vertex_buffer<'a>(
&mut self,
index: u32,
binding: crate::BufferBinding<'a, Buffer>,
) {
}
unsafe fn set_viewport(&mut self, rect: &crate::Rect<f32>, depth_range: Range<f32>) {}
unsafe fn set_scissor_rect(&mut self, rect: &crate::Rect<u32>) {}
unsafe fn set_stencil_reference(&mut self, value: u32) {}
unsafe fn set_blend_constants(&mut self, color: &[f32; 4]) {}
unsafe fn draw(
&mut self,
first_vertex: u32,
vertex_count: u32,
first_instance: u32,
instance_count: u32,
) {
}
unsafe fn draw_indexed(
&mut self,
first_index: u32,
index_count: u32,
base_vertex: i32,
first_instance: u32,
instance_count: u32,
) {
}
unsafe fn draw_indirect(
&mut self,
buffer: &Buffer,
offset: wgt::BufferAddress,
draw_count: u32,
) {
}
unsafe fn draw_indexed_indirect(
&mut self,
buffer: &Buffer,
offset: wgt::BufferAddress,
draw_count: u32,
) {
}
unsafe fn draw_indirect_count(
&mut self,
buffer: &Buffer,
offset: wgt::BufferAddress,
count_buffer: &Buffer,
count_offset: wgt::BufferAddress,
max_count: u32,
) {
}
unsafe fn draw_indexed_indirect_count(
&mut self,
buffer: &Buffer,
offset: wgt::BufferAddress,
count_buffer: &Buffer,
count_offset: wgt::BufferAddress,
max_count: u32,
) {
}
unsafe fn begin_compute_pass(&mut self, desc: &crate::ComputePassDescriptor<Resource>) {}
unsafe fn end_compute_pass(&mut self) {}
unsafe fn set_compute_pipeline(&mut self, pipeline: &Resource) {}
unsafe fn dispatch(&mut self, count: [u32; 3]) {}
unsafe fn dispatch_indirect(&mut self, buffer: &Buffer, offset: wgt::BufferAddress) {}
unsafe fn build_acceleration_structures<'a, T>(
&mut self,
_descriptor_count: u32,
descriptors: T,
) where
Api: 'a,
T: IntoIterator<Item = crate::BuildAccelerationStructureDescriptor<'a, Buffer, Resource>>,
{
}
unsafe fn place_acceleration_structure_barrier(
&mut self,
_barriers: crate::AccelerationStructureBarrier,
) {
}
unsafe fn copy_acceleration_structure_to_acceleration_structure(
&mut self,
src: &Resource,
dst: &Resource,
copy: wgt::AccelerationStructureCopy,
) {
}
}
impl Command {
unsafe fn execute(&self) {
match self {
Command::ClearBuffer { ref buffer, range } => {
let buffer_slice: &mut [u8] = unsafe { &mut *buffer.get_slice_ptr(range.clone()) };
buffer_slice.fill(0);
}
Command::CopyBufferToBuffer { src, dst, regions } => {
for &crate::BufferCopy {
src_offset,
dst_offset,
size,
} in regions
{
let src_region: &[u8] =
unsafe { &*src.get_slice_ptr(src_offset..src_offset + size.get()) };
let dst_region: &mut [u8] =
unsafe { &mut *dst.get_slice_ptr(dst_offset..dst_offset + size.get()) };
dst_region.copy_from_slice(src_region);
}
}
}
}
}