veloren_voxygen/render/
buffer.rs1use bytemuck::Pod;
2use wgpu::util::DeviceExt;
3
4pub struct Buffer<T: Copy + Pod> {
5 pub(super) buf: wgpu::Buffer,
6 len: usize,
9 phantom_data: std::marker::PhantomData<T>,
10}
11
12impl<T: Copy + Pod> Buffer<T> {
13 pub fn new(device: &wgpu::Device, usage: wgpu::BufferUsages, data: &[T]) -> Self {
14 let contents = bytemuck::cast_slice(data);
15
16 Self {
17 buf: device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
18 label: None,
19 contents,
20 usage,
21 }),
22 len: data.len(),
23 phantom_data: std::marker::PhantomData,
24 }
25 }
26
27 #[expect(clippy::len_without_is_empty)]
28 pub fn len(&self) -> usize { self.len }
29}
30
31pub struct DynamicBuffer<T: Copy + Pod>(Buffer<T>);
32
33impl<T: Copy + Pod> DynamicBuffer<T> {
34 pub fn new(device: &wgpu::Device, len: usize, usage: wgpu::BufferUsages) -> Self {
35 let buffer = Buffer {
36 buf: device.create_buffer(&wgpu::BufferDescriptor {
37 label: None,
38 mapped_at_creation: false,
39 size: len as u64 * std::mem::size_of::<T>() as u64,
40 usage: usage | wgpu::BufferUsages::COPY_DST,
41 }),
42 len,
43 phantom_data: std::marker::PhantomData,
44 };
45 Self(buffer)
46 }
47
48 pub fn update(&self, queue: &wgpu::Queue, vals: &[T], offset: usize) {
49 if !vals.is_empty() {
50 queue.write_buffer(
51 &self.buf,
52 offset as u64 * std::mem::size_of::<T>() as u64,
53 bytemuck::cast_slice(vals),
54 )
55 }
56 }
57}
58
59impl<T: Copy + Pod> std::ops::Deref for DynamicBuffer<T> {
60 type Target = Buffer<T>;
61
62 fn deref(&self) -> &Self::Target { &self.0 }
63}