mewgpu 3.7.3-1

Maybe Easier Wgpu (mew), a thin abstraction over wgpu's chaos
//#![allow(non_camel_case_types)]

//! Regular buffers are packed a lot more loosely than vertex buffers, requiring
//! different alignment. The naming convention tries to look like _wgsl_ types
//! for clarity.
//!
//! All these types are internally represented by arrays. For example
//! [`Vec3f`] is just a unit struct over `[f32; 3]`, but a single `[F32]`
//! is also an array of length 1 (`[f32; 1]`). Of course you can deref them into
//! regular arrays, but keep in mind that's not what they directly are.
//!
//! ```
//! // There shouldn't be a reason to construct these explicitly, just pass
//! // arrays into shader struct constructors, but for the sake of the example
//! let mut vec3f: Vec3f = [1.0, 2.0, 3.0].into();
//! *vec3f = [3.0, 2.0, 1.0];
//! vec3f[2] = 0.0;
//! let bytes: &[u32] = vec3f.as_ref();
//! ```

use std::ops::{ Deref, DerefMut, };


macro_rules! primitive {
    { $name:ident [ $ty:ty ; $len:literal ] => $align:literal } => {
        /// Auto-generated wrapper representing the _wgsl_ type of the same name.
        #[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
        #[repr(align($align))]
        pub struct $name([$ty; $len]);

        impl $name {
            pub const BYTES: usize = size_of::<$ty>() * $len;
            //const PADDING: usize = Self::BYTES.next_multiple_of($crate::wgpu::VERTEX_STRIDE_ALIGNMENT as usize) - Self::BYTES;
        }

        impl $crate::shaderprimitive::MewShaderPrimitive for $name {
            type Bytes = [u8; Self::BYTES];
            type Inner = [$ty; $len];

            fn from_inner(inner: Self::Inner) -> Self {
                //value.iter_mut().for_each(|val| *val = ::std::mem::transmute(val.to_le_bytes()));
                Self(inner)
            }

            fn from_bytes(bytes: Self::Bytes) -> Self {
                unsafe { Self(::std::mem::transmute::<[u8; Self::BYTES], [$ty; $len]>(bytes)) }
            }

            fn zeroed() -> Self {
                unsafe { Self(::std::mem::zeroed()) }
            }
        }

        impl From<[u8; Self::BYTES]> for $name {
            fn from(bytes: [u8; Self::BYTES]) -> Self {
                Self::from_bytes(bytes)
            }
        }
        impl From<[$ty; $len]> for $name {
            fn from(inner: [$ty; $len]) -> Self {
                Self::from_inner(inner)
            }
        }

        impl Deref for $name {
            type Target = [$ty; $len];
            fn deref(&self) -> &Self::Target {
                &self.0
            }
        }
        impl DerefMut for $name {
            fn deref_mut(&mut self) -> &mut Self::Target {
                &mut self.0
            }
        }

        impl AsRef<[u8; Self::BYTES]> for $name {
            fn as_ref(&self) -> &[u8; Self::BYTES] {
                unsafe { &*(&raw const self.0).cast() }
            }
        }
        impl AsMut<[u8; Self::BYTES]> for $name {
            fn as_mut(&mut self) -> &mut [u8; Self::BYTES] {
                unsafe { &mut *(&raw mut self.0).cast() }
            }
        }

        impl Default for $name {
            fn default() -> Self {
                Self::zeroed()
            }
        }
    };
}

primitive! { I32 [i32; 1] => 4 }
primitive! { U32 [u32; 1] => 4 }
primitive! { F32 [f32; 1] => 4 }

primitive! { Vec2i [i32; 2] => 8 }
primitive! { Vec2u [u32; 2] => 8 }
primitive! { Vec2f [f32; 2] => 8 }

primitive! { Vec3i [i32; 3] => 16 }
primitive! { Vec3u [u32; 3] => 16 }
primitive! { Vec3f [f32; 3] => 16 }

primitive! { Vec4i [i32; 4] => 16 }
primitive! { Vec4u [u32; 4] => 16 }
primitive! { Vec4f [f32; 4] => 16 }


primitive! { Mat2x2i [[i32; 2]; 2] => 16 }
primitive! { Mat2x2u [[u32; 2]; 2] => 16 }
primitive! { Mat2x2f [[f32; 2]; 2] => 16 }

primitive! { Mat3x2i [[i32; 2]; 3] => 32 }
primitive! { Mat3x2u [[u32; 2]; 3] => 32 }
primitive! { Mat3x2f [[f32; 2]; 3] => 32 }

primitive! { Mat4x2i [[i32; 2]; 4] => 32 }
primitive! { Mat4x2u [[u32; 2]; 4] => 32 }
primitive! { Mat4x2f [[f32; 2]; 4] => 32 }


primitive! { Mat2x3i [[i32; 3]; 2] => 32 }
primitive! { Mat2x3u [[u32; 3]; 2] => 32 }
primitive! { Mat2x3f [[f32; 3]; 2] => 32 }

primitive! { Mat3x3i [[i32; 3]; 3] => 64 }
primitive! { Mat3x3u [[u32; 3]; 3] => 64 }
primitive! { Mat3x3f [[f32; 3]; 3] => 64 }

primitive! { Mat4x3i [[i32; 3]; 4] => 64 }
primitive! { Mat4x3u [[u32; 3]; 4] => 64 }
primitive! { Mat4x3f [[f32; 3]; 4] => 64 }


primitive! { Mat2x4i [[i32; 4]; 2] => 32 }
primitive! { Mat2x4u [[u32; 4]; 2] => 32 }
primitive! { Mat2x4f [[f32; 4]; 2] => 32 }

primitive! { Mat3x4i [[i32; 4]; 3] => 64 }
primitive! { Mat3x4u [[u32; 4]; 3] => 64 }
primitive! { Mat3x4f [[f32; 4]; 3] => 64 }

primitive! { Mat4x4i [[i32; 4]; 4] => 64 }
primitive! { Mat4x4u [[u32; 4]; 4] => 64 }
primitive! { Mat4x4f [[f32; 4]; 4] => 64 }


pub trait MewShaderPrimitive {
    type Bytes;
    type Inner;
    fn from_inner(inner: Self::Inner) -> Self;
    fn from_bytes(bytes: Self::Bytes) -> Self;
    fn zeroed() -> Self;
}