Skip to main content

pax_gpu/render_backend/
data.rs

1use bytemuck::{Pod, Zeroable};
2
3use crate::Transform2D;
4
5pub(crate) const MAX_SCENE_LIGHTS: usize = 8;
6
7#[repr(C)]
8#[derive(Debug, Default, Copy, Clone, Pod, Zeroable)]
9pub struct GpuGlobals {
10    pub resolution: [f32; 2],
11    pub dpr: [f32; 2],
12    pub origin: [f32; 2],
13    pub _padding: [f32; 2],
14}
15
16#[repr(C)]
17#[derive(Debug, Default, Copy, Clone, Pod, Zeroable)]
18pub(crate) struct GpuPrimitive {
19    pub fill_id: u16,
20    pub fill_type_flag: u16,
21    pub z_index: i32,
22    pub material_id: u32,
23    pub transform_id: u32,
24    pub draw_range: [f32; 4],
25    pub light_mask: u32,
26    pub paint_count: u32,
27    pub _padding: [u32; 2],
28}
29
30#[repr(C)]
31#[derive(Debug, Default, Copy, Clone, Pod, Zeroable)]
32pub(crate) struct GpuColor {
33    pub color: [f32; 4],
34}
35
36#[repr(C)]
37#[derive(Debug, Default, Copy, Clone, Pod, Zeroable)]
38pub(crate) struct GpuMaterial {
39    pub coefficients: [f32; 4],
40    pub emissive: [f32; 4],
41}
42
43#[repr(C)]
44#[derive(Debug, Default, Copy, Clone, Pod, Zeroable)]
45pub(crate) struct GpuSceneLight {
46    pub position: [f32; 4],
47    pub direction: [f32; 4],
48    pub color: [f32; 4],
49    pub params: [f32; 4],
50}
51
52#[repr(C)]
53#[derive(Debug, Default, Copy, Clone, Pod, Zeroable)]
54pub(crate) struct GpuSceneLighting {
55    pub ambient: [f32; 4],
56    pub meta: [u32; 4],
57    pub lights: [GpuSceneLight; MAX_SCENE_LIGHTS],
58}
59
60// OBS: if you change this, you need to change the padding in GpuColoring to
61// match the alignment requirements (> 16 bytes + power of two).
62const MAX_GRADIENT_STOPS: usize = 8;
63
64#[repr(C)]
65#[derive(Debug, Default, Copy, Clone, Pod, Zeroable)]
66pub(crate) struct GpuGradient {
67    pub colors: [[f32; 4]; MAX_GRADIENT_STOPS],
68    pub stops: [f32; MAX_GRADIENT_STOPS],
69    pub position: [f32; 2],
70    pub main_axis: [f32; 2],
71    pub off_axis: [f32; 2],
72    pub stop_count: u32,
73    pub type_id: u32,
74    pub weight: f32,
75    pub _padding_0: u32,
76    pub focal_point: [f32; 2],
77    pub _padding: [u32; 12],
78}
79
80#[repr(C)]
81#[derive(Debug, Copy, Clone, Pod, Zeroable)]
82pub(crate) struct GpuTransform {
83    pub transform: [[f32; 2]; 3],
84    pub opacity: f32,
85    pub _pad: f32,
86}
87
88impl Default for GpuTransform {
89    fn default() -> Self {
90        Self {
91            transform: Transform2D::identity().to_arrays(),
92            opacity: 1.0,
93            _pad: 0.0,
94        }
95    }
96}
97
98#[repr(C)]
99#[derive(Debug, Default, Copy, Clone, Pod, Zeroable)]
100pub(crate) struct GpuVertex {
101    pub position: [f32; 2],
102    pub normal: [f32; 2],
103    pub prim_id: u32,
104    pub path_progress: f32,
105}
106
107#[cfg(test)]
108mod tests {
109    use super::*;
110
111    #[test]
112    fn gpu_primitive_matches_wgsl_storage_stride() {
113        assert_eq!(std::mem::size_of::<GpuPrimitive>(), 48);
114        assert_eq!(std::mem::align_of::<GpuPrimitive>(), 4);
115        assert_eq!(std::mem::size_of::<GpuGradient>(), 256);
116    }
117}
118
119impl GpuVertex {
120    pub(crate) fn desc() -> wgpu::VertexBufferLayout<'static> {
121        const ATTRIBS: [wgpu::VertexAttribute; 4] =
122            wgpu::vertex_attr_array![0 => Float32x2, 1 => Float32x2, 2 => Uint32, 3 => Float32];
123        wgpu::VertexBufferLayout {
124            array_stride: std::mem::size_of::<GpuVertex>() as wgpu::BufferAddress,
125            step_mode: wgpu::VertexStepMode::Vertex,
126            attributes: &ATTRIBS,
127        }
128    }
129}