tridify_rs/render/
gpu_buffer.rs

1use std::rc::Rc;
2
3use wgpu::{util::DeviceExt, Buffer};
4
5use crate::{GpuCtx, ToBinder, Window};
6
7pub trait ToGpuBuf {
8    fn build_buffer(&self, wnd: &GpuCtx) -> GpuBuffer;
9}
10
11/// Handle to a GPU buffer.
12pub struct GpuBuffer {
13    buffer: Rc<Buffer>,
14}
15
16impl GpuBuffer {
17    /// Creates a new buffer with uninitialized data.
18    fn new(wnd: &GpuCtx) -> Self {
19        let buffer = wnd.device.create_buffer(&wgpu::BufferDescriptor {
20            label: None,
21            size: todo!(),
22            usage: todo!(),
23            mapped_at_creation: todo!(),
24        });
25        Self {
26            buffer: Rc::new(buffer),
27        }
28    }
29
30    /// Creates a buffer with the given bytes.
31    pub fn init(wnd: &GpuCtx, data: &[u8]) -> Self {
32        let buffer = wnd
33            .device
34            .create_buffer_init(&wgpu::util::BufferInitDescriptor {
35                label: None,
36                contents: data,
37                //TODO: User config
38                usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
39            });
40
41        Self {
42            buffer: Rc::new(buffer),
43        }
44    }
45
46    /// Update buffer GPU data with bytes provided.
47    pub fn write(&mut self, wnd: &GpuCtx, data: &[u8]) {
48        wnd.queue.write_buffer(&self.buffer, 0, data);
49    }
50}
51
52impl ToBinder for GpuBuffer {
53    fn get_layout(&self, index: u32) -> wgpu::BindGroupLayoutEntry {
54        wgpu::BindGroupLayoutEntry {
55            binding: index,
56            //TODO: User should be able to config this.
57            visibility: wgpu::ShaderStages::VERTEX_FRAGMENT,
58            ty: wgpu::BindingType::Buffer {
59                //TODO: User should be able to config this.
60                ty: wgpu::BufferBindingType::Uniform,
61                has_dynamic_offset: false,
62                min_binding_size: None,
63            },
64            count: None,
65        }
66    }
67
68    fn get_group(&self, index: u32) -> wgpu::BindGroupEntry {
69        wgpu::BindGroupEntry {
70            binding: index,
71            resource: self.buffer.as_entire_binding(),
72        }
73    }
74
75    fn debug_name(&self) -> &'static str { "GPU Buffer" }
76}
77
78impl Clone for GpuBuffer {
79    fn clone(&self) -> Self {
80        Self {
81            buffer: Rc::clone(&self.buffer),
82        }
83    }
84}