use crate::types::UniformData;
use wgpu::{
BindGroup, BindGroupEntry, BindGroupLayout, BindGroupLayoutEntry, BindingType, Buffer,
BufferDescriptor, Device, Queue,
};
#[derive(Debug)]
pub struct UniformBufferResources {
buffer: Buffer,
bind_group_layout: BindGroupLayout,
bind_group: BindGroup,
data_copy: Option<UniformData>,
}
impl UniformBufferResources {
pub fn new(device: &Device) -> UniformBufferResources {
let buffer = device.create_buffer(&BufferDescriptor {
label: Some("ViewPort Buffer"),
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
size: size_of::<UniformData>() as u64,
mapped_at_creation: false,
});
let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
entries: &[BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStages::VERTEX_FRAGMENT | wgpu::ShaderStages::COMPUTE,
ty: BindingType::Buffer {
ty: wgpu::BufferBindingType::Uniform,
has_dynamic_offset: false,
min_binding_size: None,
},
count: None,
}],
label: Some("uniform bind group layout"),
});
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
layout: &bind_group_layout,
entries: &[BindGroupEntry {
binding: 0,
resource: buffer.as_entire_binding(),
}],
label: Some("viewport_bind_group"),
});
UniformBufferResources {
buffer,
bind_group_layout,
bind_group,
data_copy: None,
}
}
pub fn bind_group_layout(&self) -> &BindGroupLayout {
&self.bind_group_layout
}
pub fn bind_group(&self) -> &BindGroup {
&self.bind_group
}
pub fn buffer(&self) -> &Buffer {
&self.buffer
}
pub fn update_data(&mut self, queue: &Queue, data: UniformData) {
match self.data_copy {
Some(previous_data) if previous_data == data => {}
_ => {
self.data_copy = Some(data);
queue.write_buffer(self.buffer(), 0, bytemuck::cast_slice(&[data]));
}
}
}
}