|
1 | 1 | //! Traits related to vectors. |
2 | 2 |
|
3 | 3 | use crate::Scalar; |
| 4 | +use crate::sealed::Sealed; |
4 | 5 | use core::num::NonZeroUsize; |
5 | 6 | use glam::{Vec3Swizzles, Vec4Swizzles}; |
6 | 7 |
|
@@ -54,28 +55,46 @@ pub unsafe trait VectorOrScalar: Copy + Default + Send + Sync + 'static { |
54 | 55 | /// |
55 | 56 | /// |
56 | 57 | /// # Safety |
57 | | -/// Must only be implemented on types that the spirv codegen emits as valid `OpTypeVector`. This includes all structs |
58 | | -/// marked with `#[rust_gpu::vector::v1]`, like [`glam`]'s non-SIMD "scalar" vector types. |
| 58 | +/// * Must only be implemented on types that the spirv codegen emits as valid `OpTypeVector`. This includes all structs |
| 59 | +/// marked with `#[rust_gpu::vector::v1]`, like [`glam`]'s non-SIMD "scalar" vector types. |
| 60 | +/// * `VectorOrScalar::DIM == N`, since const equality is behind rustc feature `associated_const_equality` |
| 61 | +// Note(@firestar99) I would like to have these two generics be associated types instead. Doesn't make much sense for |
| 62 | +// a vector type to implement this interface multiple times with different Scalar types or N, after all. |
| 63 | +// While it's possible with `T: Scalar`, it's not with `const N: usize`, since some impl blocks in `image::params` need |
| 64 | +// to be conditional on a specific N value. And you can only express that with const generics, but not with associated |
| 65 | +// constants due to lack of const generics support in rustc. |
59 | 66 | pub unsafe trait Vector<T: Scalar, const N: usize>: VectorOrScalar<Scalar = T> {} |
60 | 67 |
|
61 | 68 | macro_rules! impl_vector { |
62 | | - ($($scalar:ty: $($vec:ty => $dim:literal),+;)+) => { |
63 | | - $($( |
64 | | - unsafe impl VectorOrScalar for $vec { |
| 69 | + ($($ty:ty: [$scalar:ty; $n:literal];)+) => { |
| 70 | + $( |
| 71 | + impl Sealed for $ty {} |
| 72 | + unsafe impl VectorOrScalar for $ty { |
65 | 73 | type Scalar = $scalar; |
66 | | - const DIM: NonZeroUsize = NonZeroUsize::new($dim).unwrap(); |
| 74 | + const DIM: NonZeroUsize = NonZeroUsize::new($n).unwrap(); |
67 | 75 | } |
68 | | - unsafe impl Vector<$scalar, $dim> for $vec {} |
69 | | - )+)+ |
| 76 | + unsafe impl Vector<$scalar, $n> for $ty {} |
| 77 | + )+ |
70 | 78 | }; |
71 | 79 | } |
72 | 80 |
|
73 | 81 | impl_vector! { |
74 | | - f32: glam::Vec2 => 2, glam::Vec3 => 3, glam::Vec3A => 3, glam::Vec4 => 4; |
75 | | - f64: glam::DVec2 => 2, glam::DVec3 => 3, glam::DVec4 => 4; |
76 | | - u32: glam::UVec2 => 2, glam::UVec3 => 3, glam::UVec4 => 4; |
77 | | - i32: glam::IVec2 => 2, glam::IVec3 => 3, glam::IVec4 => 4; |
78 | | - bool: glam::BVec2 => 2, glam::BVec3 => 3, glam::BVec4 => 4; |
| 82 | + glam::Vec2: [f32; 2]; |
| 83 | + glam::Vec3: [f32; 3]; |
| 84 | + glam::Vec3A: [f32; 3]; |
| 85 | + glam::Vec4: [f32; 4]; |
| 86 | + glam::DVec2: [f64; 2]; |
| 87 | + glam::DVec3: [f64; 3]; |
| 88 | + glam::DVec4: [f64; 4]; |
| 89 | + glam::UVec2: [u32; 2]; |
| 90 | + glam::UVec3: [u32; 3]; |
| 91 | + glam::UVec4: [u32; 4]; |
| 92 | + glam::IVec2: [i32; 2]; |
| 93 | + glam::IVec3: [i32; 3]; |
| 94 | + glam::IVec4: [i32; 4]; |
| 95 | + glam::BVec2: [bool; 2]; |
| 96 | + glam::BVec3: [bool; 3]; |
| 97 | + glam::BVec4: [bool; 4]; |
79 | 98 | } |
80 | 99 |
|
81 | 100 | /// Trait that implements slicing of a vector into a scalar or vector of lower dimensions, by |
|
0 commit comments