mew/
shaderstruct.rs

1pub mod vertexprimitive {
2    use std::{
3        mem::size_of,
4        ops::{ Deref, DerefMut, },
5    };
6
7    macro_rules! primitive {
8        { $name:ident [ $innerty:ty ; $innerlen:literal ] $align:literal } => {
9            #[derive(Debug)]
10            #[repr(C)]
11            pub struct $name (
12                [u8; Self::BYTES],
13                //_padding: [u8; Self::PADDING],
14            );
15
16            impl $name {
17                const BYTE: usize = size_of::<$innerty>();
18                const BYTES: usize = Self::BYTE * $innerlen;
19                //const PADDING: usize = Self::BYTES.next_multiple_of($crate::wgpu::VERTEX_STRIDE_ALIGNMENT as usize) - Self::BYTES;
20            }
21            impl $crate::vertexprimitive::MewVertexPrimitive for $name {
22                type Inner = [$innerty; $innerlen];
23
24                fn new() -> Self {
25                    Self (
26                        [0; Self::BYTES],
27                        //_padding: [0; Self::PADDING],
28                    )
29                }
30                fn from_inner(mut value: Self::Inner) -> Self {
31                    unsafe {
32                        value.iter_mut().for_each(|val| *val = ::std::mem::transmute(val.to_le_bytes()));
33                        Self (
34                            ::std::mem::transmute(value),
35                            //_padding: [0; Self::PADDING],
36                        )
37                    }
38                }
39
40                #[cfg(target_endian = "little")]
41                fn as_inner_ref(&self) -> &Self::Inner {
42                    unsafe { ::std::mem::transmute(&self.0) }
43                }
44                #[cfg(target_endian = "little")]
45                fn as_inner_mut(&mut self) -> &mut Self::Inner {
46                    unsafe { ::std::mem::transmute(&mut self.0) }
47                }
48            }
49            impl From<[u8; Self::BYTES]> for $name {
50                fn from(value: [u8; Self::BYTES]) -> Self {
51                    Self (
52                        value,
53                        //_padding: [0; Self::PADDING],
54                    )
55                }
56            }
57            /*
58            impl From<&[$innerty; $innerlen]> for $name {
59                fn from(value: &[$innerty; $innerlen]) -> Self {
60                    let mut bytes = [0; Self::BYTES];
61                    value.iter().enumerate().for_each(|(i, val)| {
62                        bytes[Self::BYTE * i..Self::BYTE * (i + 1)].copy_from_slice(&val.to_le_bytes());
63                    });
64                    Self(bytes)
65                }
66            }
67            */
68            /*
69            impl From<[$innerty; $innerlen]> for $name {
70                fn from(mut value: [$innerty; $innerlen]) -> Self {
71                    unsate {
72                        value.iter_mut().for_each(|val| *val = ::std::mem::transmute(val.to_le_bytes()));
73                        Self(::std::mem::transmute(value))
74                    }
75                }
76            }
77            */
78            impl Default for $name {
79                fn default() -> Self {
80                    Self::new()
81                }
82            }
83
84            impl AsRef<[u8]> for $name {
85                fn as_ref(&self) -> &[u8] {
86                    &self.0
87                }
88            }
89            impl AsMut<[u8]> for $name {
90                fn as_mut(&mut self) -> &mut [u8] {
91                    &mut self.0
92                }
93            }
94            impl Deref for $name {
95                type Target = [u8];
96                fn deref(&self) -> &Self::Target {
97                    &self.0
98                }
99            }
100            impl DerefMut for $name {
101                fn deref_mut(&mut self) -> &mut Self::Target {
102                    &mut self.0
103                }
104            }
105        }
106    }
107
108    primitive! { Uint8x2 [u8; 2] 2 }
109    primitive! { Uint8x4 [u8; 4] 4 }
110    primitive! { Sint8x2 [u8; 2] 2 }
111    primitive! { Sint8x4 [u8; 4] 4 }
112
113    primitive! { Unorm8x2 [u8; 2] 2 }
114    primitive! { Unorm8x4 [u8; 4] 4 }
115    primitive! { Snorm8x2 [u8; 2] 2 }
116    primitive! { Snorm8x4 [u8; 4] 4 }
117
118
119    primitive! { Uint16x2 [u16; 2] 4 }
120    primitive! { Uint16x4 [u16; 4] 8 }
121    primitive! { Sint16x2 [u16; 2] 4 }
122    primitive! { Sint16x4 [u16; 4] 8 }
123
124    primitive! { Unorm16x2 [u16; 2] 4 }
125    primitive! { Unorm16x4 [u16; 4] 8 }
126    primitive! { Snorm16x2 [u16; 2] 4 }
127    primitive! { Snorm16x4 [u16; 4] 8 }
128
129    primitive! { Float16x2 [u32; 1] 4 }
130    primitive! { Float16x4 [u64; 1] 8 }
131
132
133    primitive! { Uint32 [u32; 1] 4 }
134    primitive! { Uint32x2 [u32; 2] 8 }
135    primitive! { Uint32x3 [u32; 3] 16 }
136    primitive! { Uint32x4 [u32; 4] 16 }
137    primitive! { Sint32 [u32; 1] 4 }
138    primitive! { Sint32x2 [u32; 2] 8 }
139    primitive! { Sint32x3 [u32; 3] 16 }
140    primitive! { Sint32x4 [u32; 4] 16 }
141
142    primitive! { Float32 [f32; 1] 4 }
143    primitive! { Float32x2 [f32; 2] 8 }
144    primitive! { Float32x3 [f32; 3] 16 }
145    primitive! { Float32x4 [f32; 4] 16 }
146
147    primitive! { Unorm10_10_2 [u32; 1] 16 }
148
149
150    primitive! { Float64 [f64; 1] 8 }
151    primitive! { Float64x2 [f64; 2] 16 }
152    primitive! { Float64x3 [f64; 3] 32 }
153    primitive! { Float64x4 [f64; 4] 32 }
154
155    pub trait MewVertexPrimitive {
156        type Inner;
157        fn new() -> Self;
158        fn from_inner(inner: Self::Inner) -> Self;
159        #[cfg(target_endian = "little")]
160        fn as_inner_ref(&self) -> &Self::Inner;
161        #[cfg(target_endian = "little")]
162        fn as_inner_mut(&mut self) -> &mut Self::Inner;
163    }
164}
165pub use vertexprimitive::*;
166
167#[macro_export]
168macro_rules! vertex_struct {
169    { @len } => {
170        0
171    };
172    { @len $last:tt } => {
173        $last + 1
174    };
175    { @len $first:tt $( $rest:tt )+ } => {
176        $crate::vertex_struct!{ @len $( $rest )+ }
177    };
178
179    { $struct:ident [
180        $( $num:tt $field:ident => $attr:ident ),* $(,)?
181    ] } => {
182        $crate::vertex_struct! { $struct step Vertex [
183            $( $num $field => $attr , )*
184        ] }
185    };
186    { $struct:ident step $step:ident [
187        $( $num:tt $field:ident => $attr:ident ),* $(,)?
188    ] } => {
189        #[derive(Debug)]
190        #[repr(C)]
191        pub struct $struct {
192            $(
193                pub $field : $crate::vertexprimitive::$attr ,
194            )*
195            _padding: [u8; Self::PADDING],
196        }
197
198        impl $struct {
199            const SUM_SIZE: usize = $crate::shader_struct!{ @sum_size $( $attr )* };
200            const NEXT_MULT: usize = Self::SUM_SIZE.next_multiple_of($crate::wgpu::VERTEX_STRIDE_ALIGNMENT as usize);
201            const PADDING: usize = Self::NEXT_MULT - Self::SUM_SIZE;
202        }
203
204        impl Default for $struct {
205            fn default() -> Self {
206                Self::new()
207            }
208        }
209        impl $crate::MewVertexStruct for $struct {
210            type Inners = ( $( <$crate::vertexprimitive::$attr as $crate::vertexprimitive::MewVertexPrimitive>::Inner , )* );
211
212            fn new() -> Self {
213                Self {
214                    $(
215                        $field : $crate::vertexprimitive::$attr::new(),
216                    )*
217                    _padding: [0; Self::PADDING],
218                }
219            }
220
221            fn from_inners(inners: Self::Inners) -> Self {
222                Self {
223                    $(
224                        $field : $crate::vertexprimitive::$attr::from_inner(inners.$num),
225                    )*
226                    _padding: [0; Self::PADDING],
227                }
228            }
229
230            fn vertex_layout() -> $crate::wgpu::VertexBufferLayout<'static> {
231                static ATTRIBUTES: [$crate::wgpu::VertexAttribute; $crate::vertex_struct!{@len $( $num )* }] = $crate::wgpu::vertex_attr_array![ $( $num => $attr , )* ];
232                $crate::wgpu::VertexBufferLayout {
233                    array_stride: ::std::mem::size_of::<Self>() as u64,
234                    step_mode: $crate::wgpu::VertexStepMode::$step,
235                    attributes: &ATTRIBUTES,
236                }
237            }
238        }
239    }
240}
241
242
243pub trait MewVertexStruct {
244    type Inners;
245
246    fn new() -> Self;
247    fn from_inners(inners: Self::Inners) -> Self;
248    fn vertex_layout() -> wgpu::VertexBufferLayout<'static>;
249}
250
251
252
253#[macro_export]
254macro_rules! shader_struct {
255    { @sum $( $size:expr ; )* } => {
256        0 $( + { $size } )*
257    };
258
259    { @size $ty:ty } => {
260        {
261            const SIZE: usize = ::std::mem::size_of::<$ty>();
262            if SIZE == 0 { 0 } else { SIZE.next_power_of_two() }
263        }
264    };
265
266    { @max } => {
267        0
268    };
269    { @max $size:expr ; } => {
270        $size
271    };
272    { @max $size:expr ; $( $rest:expr ; )+ } => {
273        {
274            const FIRST: usize = $size;
275            const REST: usize = $crate::shader_struct!{ @max $( $rest ; )+ };
276            if FIRST > REST { FIRST } else { REST }
277        }
278    };
279
280    { @sum_size $( $ty:ty )* } => {
281        $crate::shader_struct!{ @sum $( $crate::shader_struct!{ @size $ty } ; )* }
282    };
283    { @max_size $( $ty:ty )* } => {
284        $crate::shader_struct!{ @max $( $crate::shader_struct!{ @size $ty } ; )* }
285    };
286
287    { $struct:ident [
288        $( $num:tt $field:ident => $ty:ty ),* $(,)?
289    ] } => {
290        #[derive(Debug)]
291        #[repr(C)]
292        pub struct $struct {
293            $(
294                pub $field: [u8; $crate::shader_struct!{ @size $ty } ],
295            )*
296            _padding: [u8; Self::PADDING],
297        }
298
299        impl $struct {
300            const SUM_SIZE: usize = $crate::shader_struct!{ @sum_size $( $ty )* };
301            const MAX_SIZE: usize = $crate::shader_struct!{ @max_size $( $ty )* };
302            const NEXT_MULT: usize = Self::SUM_SIZE.next_multiple_of(Self::MAX_SIZE);
303            const PADDING: usize = Self::NEXT_MULT - Self::SUM_SIZE;
304        }
305
306        impl $crate::MewShaderStruct for $struct {
307            #[cfg(target_endian = "little")]
308            type InnerRefs<'a> = ( $( &'a $ty , )* );
309            #[cfg(target_endian = "little")]
310            type InnerMuts<'a> = ( $( &'a mut $ty , )* );
311
312            fn new() -> Self {
313                Self {
314                    $( $field: [0; $crate::shader_struct!{ @size $ty } ], )*
315                    _padding: [0; Self::PADDING],
316                }
317            }
318
319            #[cfg(target_endian = "little")]
320            fn as_refs<'a>(&'a self) -> Self::InnerRefs<'a> {
321                ( $( unsafe {
322                    &*::std::mem::transmute::<*const u8, *const $ty>(&self.$field as *const u8)
323                }, )* )
324            }
325
326            #[cfg(target_endian = "little")]
327            fn as_muts<'a>(&'a mut self) -> Self::InnerMuts<'a> {
328                ( $( unsafe {
329                    &mut *::std::mem::transmute::<*mut u8, *mut $ty>(&mut self.$field as *mut u8)
330                }, )* )
331            }
332        }
333    }
334}
335
336pub trait MewShaderStruct {
337    #[cfg(target_endian = "little")]
338    type InnerRefs<'a> where Self: 'a;
339    #[cfg(target_endian = "little")]
340    type InnerMuts<'a> where Self: 'a;
341    fn new() -> Self;
342    #[cfg(target_endian = "little")]
343    fn as_refs<'a>(&'a self) -> Self::InnerRefs<'a>;
344    #[cfg(target_endian = "little")]
345    fn as_muts<'a>(&'a mut self) -> Self::InnerMuts<'a>;
346}