phosphor-crt 0.1.0

A real-time plotter of waveforms, imitating oscillscope CRTs
Documentation
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,

    /// A copy of the data currently in the buffer. We compare to this before writing the real buffer.
    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]));
            }
        }
    }
}