use wgpu::Device;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PingPongState {
Read0Write1,
Read1Write0,
}
impl PingPongState {
#[inline]
pub fn toggle(&mut self) {
*self = match self {
Self::Read0Write1 => Self::Read1Write0,
Self::Read1Write0 => Self::Read0Write1,
};
}
#[inline]
pub fn read_index(&self) -> usize {
match self {
Self::Read0Write1 => 0,
Self::Read1Write0 => 1,
}
}
#[inline]
pub fn write_index(&self) -> usize {
match self {
Self::Read0Write1 => 1,
Self::Read1Write0 => 0,
}
}
#[inline]
pub fn buffers<'a>(&self, pair: &'a [wgpu::Buffer; 2]) -> (&'a wgpu::Buffer, &'a wgpu::Buffer) {
match self {
Self::Read0Write1 => (&pair[0], &pair[1]),
Self::Read1Write0 => (&pair[1], &pair[0]),
}
}
}
impl Default for PingPongState {
fn default() -> Self {
Self::Read0Write1
}
}
#[derive(Debug)]
pub struct PingPongBuffers {
pub buffers: [wgpu::Buffer; 2],
}
impl PingPongBuffers {
pub fn new(device: &Device, size: u64, label: &str) -> Self {
let make_buf = |idx: usize| {
device.create_buffer(&wgpu::BufferDescriptor {
label: Some(&format!("{label}_pingpong_{}", idx)),
size,
usage: wgpu::BufferUsages::STORAGE
| wgpu::BufferUsages::COPY_SRC
| wgpu::BufferUsages::COPY_DST,
mapped_at_creation: false,
})
};
Self {
buffers: [make_buf(0), make_buf(1)],
}
}
pub fn get(&self, state: PingPongState) -> (&wgpu::Buffer, &wgpu::Buffer) {
state.buffers(&self.buffers)
}
}