sketchbook_wgpu/wgpu/
vec_buffer.rs

1use std::marker::PhantomData;
2use std::time::Instant;
3
4use bytemuck::Pod;
5
6use wgpu::util::DeviceExt;
7use wgpu::{Buffer, BufferSlice, BufferUsages, Device, Queue};
8
9pub struct VecBuffer<T> {
10    buffer_capacity: usize,
11    buffer_len: usize,
12    gpu_buffer: Buffer,
13    marker: PhantomData<T>,
14    usage: BufferUsages,
15}
16
17impl<T> VecBuffer<T>
18where
19    T: Pod,
20{
21    pub fn new(device: &Device, usage: BufferUsages) -> Self {
22        let gpu_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
23            label: Some("Vec Buffer"),
24            contents: &[],
25            usage,
26        });
27
28        Self {
29            gpu_buffer,
30            buffer_capacity: 0,
31            buffer_len: 0,
32            usage,
33            marker: PhantomData,
34        }
35    }
36
37    fn needs_alloc(&self, data: &[T]) -> bool {
38        self.buffer_capacity < data.len()
39    }
40
41    fn alloc_buffer(&mut self, device: &Device, data: &[T]) {
42        // destroy previous buffer
43        self.gpu_buffer.destroy();
44
45        println!("buffer alloc {}", data.len());
46
47        self.buffer_capacity = data.len();
48        self.buffer_len = data.len();
49
50        // create a new buffer
51        self.gpu_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
52            label: Some("Pool Buffer"),
53            contents: bytemuck::cast_slice(data),
54            usage: self.usage,
55        });
56    }
57
58    pub fn slice(&self) -> BufferSlice<'_> {
59        self.gpu_buffer.slice(..)
60    }
61
62    pub fn load_data(&mut self, device: &Device, queue: &Queue, data: &[T]) {
63        if self.needs_alloc(data) {
64            self.alloc_buffer(device, data);
65        } else {
66            queue.write_buffer(&self.gpu_buffer, 0, bytemuck::cast_slice(data));
67            self.buffer_len = data.len();
68        }
69    }
70
71    pub fn len(&self) -> usize {
72        self.buffer_len
73    }
74
75    pub fn is_empty(&self) -> bool {
76        self.buffer_len == 0
77    }
78}