wgpu_dynamic_buffer/
lib.rs

1use wgpu::util::DeviceExt as _;
2
3#[derive(Debug)]
4pub struct DynamicBuffer {
5    raw: wgpu::Buffer,
6    descriptor: wgpu::BufferDescriptor<'static>,
7}
8
9impl DynamicBuffer {
10    pub fn new(device: &wgpu::Device, descriptor: wgpu::BufferDescriptor<'static>) -> Self {
11        let raw = device.create_buffer(&descriptor);
12        Self { raw, descriptor }
13    }
14
15    pub fn new_init(device: &wgpu::Device, descriptor: wgpu::util::BufferInitDescriptor) -> Self {
16        let raw = device.create_buffer_init(&descriptor);
17
18        let descriptor = wgpu::BufferDescriptor {
19            label: None,
20            size: descriptor.contents.len() as wgpu::BufferAddress,
21            usage: descriptor.usage,
22            mapped_at_creation: false,
23        };
24
25        Self { raw, descriptor }
26    }
27
28    pub fn update(&mut self, device: &wgpu::Device, queue: &wgpu::Queue, data: &[u8]) {
29        if self.try_update(queue, data).is_err() {
30            self.update_by_init(device, data)
31        }
32    }
33
34    pub fn try_update(
35        &mut self,
36        queue: &wgpu::Queue,
37        data: &[u8],
38    ) -> Result<(), wgpu::BufferAddress> {
39        let data_len = data.len() as wgpu::BufferAddress;
40        if data_len < self.descriptor.size {
41            queue.write_buffer(&self.raw, 0, data);
42            self.descriptor.size = data_len;
43            Ok(())
44        } else {
45            Err(data_len - self.descriptor.size)
46        }
47    }
48
49    pub fn update_by_init(&mut self, device: &wgpu::Device, data: &[u8]) {
50        device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
51            label: None,
52            contents: data,
53            usage: self.descriptor.usage,
54        });
55        self.descriptor.size = data.len() as wgpu::BufferAddress;
56    }
57
58    /// Get a reference to the dynamic buffer's raw.
59    pub fn raw(&self) -> &wgpu::Buffer {
60        &self.raw
61    }
62
63    /// Get a reference to the dynamic buffer's descriptor.
64    pub fn descriptor(&self) -> &wgpu::BufferDescriptor<'static> {
65        &self.descriptor
66    }
67}
68
69// TODO: let buffer grow differently
70//fn new_size(last_size: wgpu::BufferAddress) -> wgpu::BufferAddress {
71//    last_size.pow(2)
72//}