phosphor-crt 0.1.0

A real-time plotter of waveforms, imitating oscillscope CRTs
Documentation
use wgpu::{BindGroup, BindGroupEntry, BindGroupLayout, BindGroupLayoutEntry, BindingType, Device};

#[derive(Debug)]
pub(crate) struct AutoIntensityResources {
    bind_group_fragment: BindGroup,
    bind_group_layout_fragment: BindGroupLayout,
    #[cfg(feature = "auto-intensity")]
    bind_group_compute: BindGroup,
    #[cfg(feature = "auto-intensity")]
    bind_group_layout_compute: BindGroupLayout,
    #[cfg(feature = "auto-intensity")]
    max_value_buffer: wgpu::Buffer,
}

impl AutoIntensityResources {
    pub(crate) fn new(device: &Device) -> AutoIntensityResources {
        #[cfg(feature = "auto-intensity")]
        let max_value_buffer = device.create_buffer(&wgpu::BufferDescriptor {
            label: Some("Max Value Buffer"),
            size: size_of::<u32>() as u64,
            usage: if cfg!(feature = "auto-intensity") {
                wgpu::BufferUsages::STORAGE
                    | wgpu::BufferUsages::COPY_DST
                    | wgpu::BufferUsages::COPY_SRC
            } else {
                wgpu::BufferUsages::COPY_DST | wgpu::BufferUsages::COPY_SRC
            },
            mapped_at_creation: false,
        });

        let bind_group_layout_fragment =
            device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
                entries: if cfg!(feature = "auto-intensity") {
                    &[BindGroupLayoutEntry {
                        binding: 0,
                        visibility: wgpu::ShaderStages::FRAGMENT,
                        ty: BindingType::Buffer {
                            ty: wgpu::BufferBindingType::Storage { read_only: true },
                            has_dynamic_offset: false,
                            min_binding_size: None,
                        },
                        count: None,
                    }]
                } else {
                    &[]
                },
                label: Some("Auto Intensity Fragment Bind Group Layout"),
            });

        #[cfg(not(feature = "auto-intensity"))]
        let entries: &[BindGroupEntry; 0] = &[];
        #[cfg(feature = "auto-intensity")]
        let entries = &[BindGroupEntry {
            binding: 0,
            resource: max_value_buffer.as_entire_binding(),
        }];
        let bind_group_fragment = device.create_bind_group(&wgpu::BindGroupDescriptor {
            layout: &bind_group_layout_fragment,
            entries,
            label: Some("Auto Intensity Fragment Bind Group"),
        });

        #[cfg(feature = "auto-intensity")]
        let bind_group_layout_compute =
            device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
                entries: &[BindGroupLayoutEntry {
                    binding: 0,
                    visibility: wgpu::ShaderStages::COMPUTE,
                    ty: BindingType::Buffer {
                        ty: wgpu::BufferBindingType::Storage { read_only: false },
                        has_dynamic_offset: false,
                        min_binding_size: None,
                    },
                    count: None,
                }],
                label: Some("Auto Intensity Compute Bind Group Layout"),
            });

        #[cfg(feature = "auto-intensity")]
        let bind_group_compute = device.create_bind_group(&wgpu::BindGroupDescriptor {
            layout: &bind_group_layout_compute,
            entries: &[BindGroupEntry {
                binding: 0,
                resource: max_value_buffer.as_entire_binding(),
            }],
            label: Some("Auto Intensity Compute Bind Group"),
        });

        AutoIntensityResources {
            bind_group_fragment,
            bind_group_layout_fragment,
            #[cfg(feature = "auto-intensity")]
            max_value_buffer,
            #[cfg(feature = "auto-intensity")]
            bind_group_compute,
            #[cfg(feature = "auto-intensity")]
            bind_group_layout_compute,
        }
    }

    pub(crate) fn bind_group_layout_fragment(&self) -> &BindGroupLayout {
        &self.bind_group_layout_fragment
    }
    pub(crate) fn bind_group_fragment(&self) -> &BindGroup {
        &self.bind_group_fragment
    }
}

#[cfg(feature = "auto-intensity")]
impl AutoIntensityResources {
    pub(crate) fn max_value_buffer(&self) -> &wgpu::Buffer {
        &self.max_value_buffer
    }
    pub(crate) fn bind_group_compute(&self) -> &BindGroup {
        &self.bind_group_compute
    }

    pub(crate) fn bind_group_layout_compute(&self) -> &BindGroupLayout {
        &self.bind_group_layout_compute
    }
}