Skip to main content

mew/
shaderprimitive.rs

1//#![allow(non_camel_case_types)]
2
3//! Yes, these differ from [`crate::vertexformat`]s.
4//!
5//! Regular bound buffers are packed a lot more loosely, requiring different
6//! alignment. The naming convention tries to look like _wgsl_ types for clarity.
7//!
8//! All these types are internally represented by arrays. For example
9//! [`Vec3f`] is just a unit struct over `[f32; 3]`, but a single `[F32]`
10//! is also an array of length 1 (`[f32; 1]`). Of course you can deref them into
11//! regular arrays, but keep in mind that's not what they directly are.
12//!
13//! ```
14//! // There shouldn't be a reason to construct these explicitly, just pass
15//! // arrays into shader struct constructors, but for the sake of the example
16//! let mut vec3f: Vec3f = [1.0, 2.0, 3.0].into();
17//! *vec3f = [3.0, 2.0, 1.0];
18//! vec3f[2] = 0.0;
19//! let bytes: &[u32] = vec3f.as_ref();
20//! ```
21
22use std::ops::{ Deref, DerefMut, };
23
24
25macro_rules! primitive {
26    { $name:ident [ $ty:ty ; $len:literal ] => $align:literal } => {
27        #[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
28        #[repr(align($align))]
29        pub struct $name([$ty; $len]);
30
31        impl $name {
32            pub const BYTES: usize = size_of::<$ty>() * $len;
33            //const PADDING: usize = Self::BYTES.next_multiple_of($crate::wgpu::VERTEX_STRIDE_ALIGNMENT as usize) - Self::BYTES;
34        }
35
36        impl $crate::shaderprimitive::MewShaderPrimitive for $name {
37            type Bytes = [u8; Self::BYTES];
38            type Inner = [$ty; $len];
39
40            fn from_inner(inner: Self::Inner) -> Self {
41                //value.iter_mut().for_each(|val| *val = ::std::mem::transmute(val.to_le_bytes()));
42                Self(inner)
43            }
44
45            fn from_bytes(bytes: Self::Bytes) -> Self {
46                unsafe { Self(::std::mem::transmute(bytes)) }
47            }
48
49            fn zeroed() -> Self {
50                unsafe { Self(::std::mem::zeroed()) }
51            }
52        }
53
54        impl From<[u8; Self::BYTES]> for $name {
55            fn from(bytes: [u8; Self::BYTES]) -> Self {
56                Self::from_bytes(bytes)
57            }
58        }
59        impl From<[$ty; $len]> for $name {
60            fn from(inner: [$ty; $len]) -> Self {
61                Self::from_inner(inner)
62            }
63        }
64
65        impl Deref for $name {
66            type Target = [$ty; $len];
67            fn deref(&self) -> &Self::Target {
68                &self.0
69            }
70        }
71        impl DerefMut for $name {
72            fn deref_mut(&mut self) -> &mut Self::Target {
73                &mut self.0
74            }
75        }
76
77        impl AsRef<[u8; Self::BYTES]> for $name {
78            fn as_ref(&self) -> &[u8; Self::BYTES] {
79                unsafe { ::std::mem::transmute(&self.0) }
80            }
81        }
82        impl AsMut<[u8; Self::BYTES]> for $name {
83            fn as_mut(&mut self) -> &mut [u8; Self::BYTES] {
84                unsafe { ::std::mem::transmute(&mut self.0) }
85            }
86        }
87
88        impl Default for $name {
89            fn default() -> Self {
90                Self::zeroed()
91            }
92        }
93    };
94}
95
96primitive! { I32 [i32; 1] => 4 }
97primitive! { U32 [u32; 1] => 4 }
98primitive! { F32 [f32; 1] => 4 }
99
100primitive! { Vec2i [i32; 2] => 8 }
101primitive! { Vec2u [u32; 2] => 8 }
102primitive! { Vec2f [f32; 2] => 8 }
103
104primitive! { Vec3i [i32; 3] => 16 }
105primitive! { Vec3u [u32; 3] => 16 }
106primitive! { Vec3f [f32; 3] => 16 }
107
108primitive! { Vec4i [i32; 4] => 16 }
109primitive! { Vec4u [u32; 4] => 16 }
110primitive! { Vec4f [f32; 4] => 16 }
111
112
113primitive! { Mat2x2i [[i32; 2]; 2] => 16 }
114primitive! { Mat2x2u [[u32; 2]; 2] => 16 }
115primitive! { Mat2x2f [[f32; 2]; 2] => 16 }
116
117primitive! { Mat3x2i [[i32; 2]; 3] => 32 }
118primitive! { Mat3x2u [[u32; 2]; 3] => 32 }
119primitive! { Mat3x2f [[f32; 2]; 3] => 32 }
120
121primitive! { Mat4x2i [[i32; 2]; 4] => 32 }
122primitive! { Mat4x2u [[u32; 2]; 4] => 32 }
123primitive! { Mat4x2f [[f32; 2]; 4] => 32 }
124
125
126primitive! { Mat2x3i [[i32; 3]; 2] => 32 }
127primitive! { Mat2x3u [[u32; 3]; 2] => 32 }
128primitive! { Mat2x3f [[f32; 3]; 2] => 32 }
129
130primitive! { Mat3x3i [[i32; 3]; 3] => 64 }
131primitive! { Mat3x3u [[u32; 3]; 3] => 64 }
132primitive! { Mat3x3f [[f32; 3]; 3] => 64 }
133
134primitive! { Mat4x3i [[i32; 3]; 4] => 64 }
135primitive! { Mat4x3u [[u32; 3]; 4] => 64 }
136primitive! { Mat4x3f [[f32; 3]; 4] => 64 }
137
138
139primitive! { Mat2x4i [[i32; 4]; 2] => 32 }
140primitive! { Mat2x4u [[u32; 4]; 2] => 32 }
141primitive! { Mat2x4f [[f32; 4]; 2] => 32 }
142
143primitive! { Mat3x4i [[i32; 4]; 3] => 64 }
144primitive! { Mat3x4u [[u32; 4]; 3] => 64 }
145primitive! { Mat3x4f [[f32; 4]; 3] => 64 }
146
147primitive! { Mat4x4i [[i32; 4]; 4] => 64 }
148primitive! { Mat4x4u [[u32; 4]; 4] => 64 }
149primitive! { Mat4x4f [[f32; 4]; 4] => 64 }
150
151
152pub trait MewShaderPrimitive {
153    type Bytes;
154    type Inner;
155    fn from_inner(inner: Self::Inner) -> Self;
156    fn from_bytes(bytes: Self::Bytes) -> Self;
157    fn zeroed() -> Self;
158}