dynamis-gpu 0.6.0

GPU-driven physics engine
Documentation
use wgpu::{BufferAddress, BufferUsages, Device};

#[repr(C)]
#[derive(Clone, Copy, bytemuck::Pod, bytemuck::Zeroable)]
struct DispatchArgs {
    per_row: u32,
    rows: u32,
    layers: u32,
    _pad: u32,
}

pub const DISPATCH_ARGS_BYTES: BufferAddress = size_of::<DispatchArgs>() as BufferAddress;

const _: () = assert!(DISPATCH_ARGS_BYTES == 16);

pub struct DispatchTable {
    buffer: crate::GpuBuffer,
    slots: u32,
}

impl DispatchTable {
    pub fn new(device: &Device, label: &str, slots: u32) -> Self {
        assert!(slots > 0, "a dispatch table needs at least one slot");
        Self {
            buffer: crate::GpuBuffer::new(
                device,
                label,
                slots as BufferAddress * DISPATCH_ARGS_BYTES,
                BufferUsages::STORAGE
                    .union(BufferUsages::INDIRECT)
                    .union(BufferUsages::COPY_DST),
            ),
            slots,
        }
    }

    pub fn buffer(&self) -> &crate::GpuBuffer {
        &self.buffer
    }

    pub fn slots(&self) -> u32 {
        self.slots
    }

    pub fn offset(&self, slot: u32) -> BufferAddress {
        assert!(
            slot < self.slots,
            "dispatch slot {slot} is outside the {} table slots",
            self.slots
        );
        slot as BufferAddress * DISPATCH_ARGS_BYTES
    }
}