sketchbook_wgpu/wgpu/
vec_buffer.rs1use 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 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 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}