Skip to main content

grana_gpu/
command.rs

1use bytemuck::bytes_of;
2use wgpu::{Buffer, BufferUsages, Device, Queue};
3
4#[repr(C)]
5#[derive(Clone, Copy)]
6struct IndexedArgs {
7    index_count: u32,
8    instance_count: u32,
9    first_index: u32,
10    base_vertex: i32,
11    first_instance: u32,
12}
13
14pub struct IndexedCommands {
15    buffer: Buffer,
16    count: u32,
17    stride: u64,
18}
19
20impl IndexedCommands {
21    pub fn new(device: &Device, label: &'static str, count: usize, regions: usize) -> Self {
22        assert!(
23            count > 0,
24            "an indirect draw table holds at least one command"
25        );
26        assert!(regions > 0, "an indirect draw table holds a region");
27        let stride = (count * size_of::<IndexedArgs>()) as u64;
28        let buffer = device.create_buffer(&wgpu::BufferDescriptor {
29            label: Some(label),
30            size: stride * regions as u64,
31            usage: BufferUsages::INDIRECT | BufferUsages::STORAGE | BufferUsages::COPY_DST,
32            mapped_at_creation: false,
33        });
34        Self {
35            buffer,
36            count: count as u32,
37            stride,
38        }
39    }
40
41    pub fn buffer(&self) -> &Buffer {
42        &self.buffer
43    }
44
45    pub fn count(&self) -> u32 {
46        self.count
47    }
48
49    pub fn offset(&self, region: usize) -> u64 {
50        self.stride * region as u64
51    }
52}
53
54pub struct InstanceCommands {
55    buffer: Buffer,
56}
57
58impl InstanceCommands {
59    pub fn new(device: &Device, label: &'static str) -> Self {
60        let buffer = device.create_buffer(&wgpu::BufferDescriptor {
61            label: Some(label),
62            size: size_of::<[u32; 4]>() as u64,
63            usage: BufferUsages::INDIRECT | BufferUsages::STORAGE | BufferUsages::COPY_DST,
64            mapped_at_creation: false,
65        });
66        Self { buffer }
67    }
68
69    pub fn reset(&self, queue: &Queue, vertex_count: u32) {
70        queue.write_buffer(&self.buffer, 0, bytes_of(&[vertex_count, 0, 0, 0]));
71    }
72
73    pub fn buffer(&self) -> &Buffer {
74        &self.buffer
75    }
76}