encase/types/
vector.rs

1pub trait VectorScalar: crate::ShaderSize {}
2impl_marker_trait_for_f32!(VectorScalar);
3impl_marker_trait_for_u32!(VectorScalar);
4impl_marker_trait_for_i32!(VectorScalar);
5
6/// Enables reading from the vector (via `&[T; N]`)
7pub trait AsRefVectorParts<T: VectorScalar, const N: usize> {
8    fn as_ref_parts(&self) -> &[T; N];
9}
10
11/// Enables writing to the vector (via `&mut [T; N]`)
12pub trait AsMutVectorParts<T: VectorScalar, const N: usize> {
13    fn as_mut_parts(&mut self) -> &mut [T; N];
14}
15
16/// Enables the creation of a vector (via `[T; N]`)
17pub trait FromVectorParts<T: VectorScalar, const N: usize> {
18    fn from_parts(parts: [T; N]) -> Self;
19}
20
21/// Used to implement `ShaderType` for the given vector type
22///
23/// The given vector type should implement any combination of
24/// [`AsRefVectorParts`], [`AsMutVectorParts`], [`FromVectorParts`]
25/// depending on needed capability (they can also be derived via `$using`)
26///
27/// # Args
28///
29/// - `$n` nr of elements the given vector contains
30///
31/// - `$type` the type (representing a vector) for which `ShaderType` will be implemented for
32///
33/// - `$generics` \[optional\] generics that will be passed into the `impl< >`
34///
35/// - `$el_type` \[optional\] inner element type of the vector (should implement [`VectorScalar`])
36///
37/// - `$using` \[optional\] can be any combination of `AsRef AsMut From`
38#[macro_export]
39macro_rules! impl_vector {
40    ($n:literal, $type:ty $( ; using $($using:tt)* )?) => {
41        $crate::impl_vector_inner!(__inner, ($n, $type, T, (T)); $( $($using)* )?);
42    };
43    ($n:literal, $type:ty; ($($generics:tt)*) $( ; using $($using:tt)* )?) => {
44        $crate::impl_vector_inner!(__inner, ($n, $type, T, ($($generics)*)); $( $($using)* )?);
45    };
46    ($n:literal, $type:ty, $el_ty:ty $( ; using $($using:tt)* )?) => {
47        $crate::impl_vector_inner!(__inner, ($n, $type, $el_ty, ()); $( $($using)* )?);
48    };
49}
50
51#[doc(hidden)]
52#[macro_export]
53macro_rules! impl_vector_inner {
54    (__inner, ($($other:tt)*); AsRef $($using:tt)*) => {
55        $crate::impl_vector_inner!(__ref, $($other)*);
56        $crate::impl_vector_inner!(__inner, ($($other)*); $($using)*);
57    };
58    (__inner, ($($other:tt)*); AsMut $($using:tt)*) => {
59        $crate::impl_vector_inner!(__mut, $($other)*);
60        $crate::impl_vector_inner!(__inner, ($($other)*); $($using)*);
61    };
62    (__inner, ($($other:tt)*); From $($using:tt)*) => {
63        $crate::impl_vector_inner!(__from, $($other)*);
64        $crate::impl_vector_inner!(__inner, ($($other)*); $($using)*);
65    };
66    (__inner, ($n:literal, $type:ty, $el_ty:ty, ($($generics:tt)*)); ) => {
67        $crate::impl_vector_inner!(__main, $n, $type, $el_ty, ($($generics)*));
68    };
69
70    (__ref, $n:literal, $type:ty, $el_ty:ty, ($($generics:tt)*)) => {
71        impl<$($generics)*> $crate::private::AsRefVectorParts<$el_ty, $n> for $type
72        where
73            Self: ::core::convert::AsRef<[$el_ty; $n]>,
74            $el_ty: $crate::private::VectorScalar,
75        {
76            #[inline]
77            fn as_ref_parts(&self) -> &[$el_ty; $n] {
78                ::core::convert::AsRef::as_ref(self)
79            }
80        }
81    };
82    (__mut, $n:literal, $type:ty, $el_ty:ty, ($($generics:tt)*)) => {
83        impl<$($generics)*> $crate::private::AsMutVectorParts<$el_ty, $n> for $type
84        where
85            Self: ::core::convert::AsMut<[$el_ty; $n]>,
86            $el_ty: $crate::private::VectorScalar,
87        {
88            #[inline]
89            fn as_mut_parts(&mut self) -> &mut [$el_ty; $n] {
90                ::core::convert::AsMut::as_mut(self)
91            }
92        }
93    };
94    (__from, $n:literal, $type:ty, $el_ty:ty, ($($generics:tt)*)) => {
95        impl<$($generics)*> $crate::private::FromVectorParts<$el_ty, $n> for $type
96        where
97            Self: ::core::convert::From<[$el_ty; $n]>,
98            $el_ty: $crate::private::VectorScalar,
99        {
100            #[inline]
101            fn from_parts(parts: [$el_ty; $n]) -> Self {
102                ::core::convert::From::from(parts)
103            }
104        }
105    };
106
107    (__main, $n:literal, $type:ty, $el_ty:ty, ($($generics:tt)*)) => {
108        const _: () = assert!(
109            2 <= $n && $n <= 4,
110            "Vector should have at least 2 elements and at most 4!",
111        );
112
113        impl<$($generics)*> $crate::private::ShaderType for $type
114        where
115            $el_ty: $crate::private::ShaderSize,
116        {
117            type ExtraMetadata = ();
118            const METADATA: $crate::private::Metadata<Self::ExtraMetadata> = {
119                let size = $crate::private::SizeValue::from(<$el_ty as $crate::private::ShaderSize>::SHADER_SIZE).mul($n);
120                let alignment = $crate::private::AlignmentValue::from_next_power_of_two_size(size);
121
122                $crate::private::Metadata {
123                    alignment,
124                    has_uniform_min_alignment: false,
125                    min_size: size,
126                    is_pod: <[$el_ty; $n] as $crate::private::ShaderType>::METADATA.is_pod(),
127                    extra: ()
128                }
129            };
130        }
131
132        impl<$($generics)*> $crate::private::ShaderSize for $type
133        where
134            $el_ty: $crate::private::ShaderSize
135        {}
136
137        impl<$($generics)*> $crate::private::WriteInto for $type
138        where
139            Self: $crate::private::AsRefVectorParts<$el_ty, $n>,
140            $el_ty: $crate::private::VectorScalar + $crate::private::WriteInto,
141        {
142            #[inline]
143            fn write_into<B: $crate::private::BufferMut>(&self, writer: &mut $crate::private::Writer<B>) {
144                let elements = $crate::private::AsRefVectorParts::<$el_ty, $n>::as_ref_parts(self);
145                $crate::private::WriteInto::write_into(elements, writer);
146            }
147        }
148
149        impl<$($generics)*> $crate::private::ReadFrom for $type
150        where
151            Self: $crate::private::AsMutVectorParts<$el_ty, $n>,
152            $el_ty: $crate::private::VectorScalar + $crate::private::ReadFrom,
153        {
154            #[inline]
155            fn read_from<B: $crate::private::BufferRef>(&mut self, reader: &mut $crate::private::Reader<B>) {
156                let elements = $crate::private::AsMutVectorParts::<$el_ty, $n>::as_mut_parts(self);
157                $crate::private::ReadFrom::read_from(elements, reader);
158            }
159        }
160
161        impl<$($generics)*> $crate::private::CreateFrom for $type
162        where
163            Self: $crate::private::FromVectorParts<$el_ty, $n>,
164            $el_ty: $crate::private::VectorScalar + $crate::private::CreateFrom,
165        {
166            #[inline]
167            fn create_from<B: $crate::private::BufferRef>(reader: &mut $crate::private::Reader<B>) -> Self {
168                let elements = $crate::private::CreateFrom::create_from(reader);
169                $crate::private::FromVectorParts::<$el_ty, $n>::from_parts(elements)
170            }
171        }
172    };
173}