rootvg_mesh/
pipeline.rs

1//! Draw meshes of triangles.
2pub mod solid;
3
4#[cfg(feature = "gradient")]
5pub mod gradient;
6
7use crate::MeshUniforms;
8
9const INITIAL_INDEX_COUNT: usize = 256;
10const INITIAL_VERTEX_COUNT: usize = 256;
11
12fn instance_uniforms_layout(device: &wgpu::Device) -> wgpu::BindGroupLayout {
13    device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
14        label: Some("rootvg-mesh instance uniforms layout"),
15        entries: &[InstanceUniforms::entry()],
16    })
17}
18
19fn color_target_state(format: wgpu::TextureFormat) -> [Option<wgpu::ColorTargetState>; 1] {
20    [Some(wgpu::ColorTargetState {
21        format,
22        blend: Some(wgpu::BlendState::ALPHA_BLENDING),
23        write_mask: wgpu::ColorWrites::ALL,
24    })]
25}
26
27// TODO: Use push constants instead if it is available.
28#[derive(Debug, Clone, Copy, bytemuck::Pod, bytemuck::Zeroable)]
29#[repr(C)]
30struct InstanceUniforms {
31    inner: MeshUniforms,
32    /// Uniform values must be 256-aligned;
33    /// see: [`wgpu::Limits`] `min_uniform_buffer_offset_alignment`.
34    _padding1: [f32; 32],
35    /// Bytemuck doesn't derive for arrays of size 55, so split it up.
36    _padding2: [f32; 23],
37}
38
39impl InstanceUniforms {
40    pub fn new(inner: MeshUniforms) -> Self {
41        // # SAFETY:
42        //
43        // Neither the rust code nor the shader code reads these padding bytes.
44        #[allow(invalid_value)]
45        let (_padding1, _padding2): ([f32; 32], [f32; 23]) = unsafe {
46            (
47                std::mem::MaybeUninit::uninit().assume_init(),
48                std::mem::MaybeUninit::uninit().assume_init(),
49            )
50        };
51
52        Self {
53            inner,
54            _padding1,
55            _padding2,
56        }
57    }
58
59    fn entry() -> wgpu::BindGroupLayoutEntry {
60        wgpu::BindGroupLayoutEntry {
61            binding: 0,
62            visibility: wgpu::ShaderStages::VERTEX_FRAGMENT,
63            ty: wgpu::BindingType::Buffer {
64                ty: wgpu::BufferBindingType::Uniform,
65                has_dynamic_offset: true,
66                min_binding_size: wgpu::BufferSize::new(std::mem::size_of::<Self>() as u64),
67            },
68            count: None,
69        }
70    }
71
72    pub fn min_size() -> Option<wgpu::BufferSize> {
73        wgpu::BufferSize::new(std::mem::size_of::<Self>() as u64)
74    }
75}