Skip to main content

spirv_std/image/
params.rs

1use super::{Arrayed, Dimensionality, ImageFormat};
2use crate::glam;
3use crate::{Integer, Scalar, Vector, VectorTruncateInto};
4
5/// Marker trait for arguments that accept single scalar values or vectors
6/// of scalars. Defines 2-, 3- and 4-component vector types based on the sample type.
7pub trait SampleType<const FORMAT: u32, const COMPONENTS: u32>: Scalar {
8    /// The default vector/scalar of this sample type
9    type SampleResult: Default;
10
11    /// A 2-component vector of this sample type
12    type Vec2: Default;
13
14    /// A 3-component vector of this sample type
15    type Vec3: Default;
16
17    /// A 4-component vector of this sample type
18    type Vec4: Default + VectorTruncateInto<Self::SampleResult>;
19}
20
21/// Helper macro to implement `SampleType` of various formats for various scalar types.
22macro_rules! sample_type_impls {
23    ($($fmt:ident : $n:tt*$s:ty => ($v1:ty, $v2:ty, $v3:ty, $v4:ty)),+ $(,)?) => {
24        $(sample_type_impls! { @single_rule, $fmt : $n*$s => ($v1,$v2,$v3,$v4) })+
25    };
26    (@single_rule, $fmt:ident : n*$s:ty => ($v1:ty, $v2:ty, $v3:ty, $v4:ty)) => {
27        sample_type_impls! { @single_rule, $fmt: 1*$s => ($v1, $v2, $v3, $v4) }
28        sample_type_impls! { @single_rule, $fmt: 2*$s => ($v1, $v2, $v3, $v4) }
29        sample_type_impls! { @single_rule, $fmt: 3*$s => ($v1, $v2, $v3, $v4) }
30        sample_type_impls! { @single_rule, $fmt: 4*$s => ($v1, $v2, $v3, $v4) }
31    };
32    (@single_rule, $fmt:ident : 1*$s:ty => ($v1:ty, $v2:ty, $v3:ty, $v4:ty)) => {
33        impl SampleType<{ ImageFormat::$fmt as u32 }, 1> for $s {
34            type SampleResult = $v1;
35            type Vec2 = $v2;
36            type Vec3 = $v3;
37            type Vec4 = $v4;
38        }
39    };
40    (@single_rule, $fmt:ident : 2*$s:ty => ($v1:ty, $v2:ty, $v3:ty, $v4:ty)) => {
41        impl SampleType<{ ImageFormat::$fmt as u32 }, 2> for $s {
42            type SampleResult = $v2;
43            type Vec2 = $v2;
44            type Vec3 = $v3;
45            type Vec4 = $v4;
46        }
47    };
48    (@single_rule, $fmt:ident : 3*$s:ty => ($v1:ty, $v2:ty, $v3:ty, $v4:ty)) => {
49        impl SampleType<{ ImageFormat::$fmt as u32 }, 3> for $s {
50            type SampleResult = $v3;
51            type Vec2 = $v2;
52            type Vec3 = $v3;
53            type Vec4 = $v4;
54        }
55    };
56    (@single_rule, $fmt:ident : 4*$s:ty => ($v1:ty, $v2:ty, $v3:ty, $v4:ty)) => {
57        impl SampleType<{ ImageFormat::$fmt as u32 }, 4> for $s {
58            type SampleResult = $v4;
59            type Vec2 = $v2;
60            type Vec3 = $v3;
61            type Vec4 = $v4;
62        }
63    };
64}
65
66sample_type_impls! {
67    Unknown: n*i8 => (i32, glam::IVec2, glam::IVec3, glam::IVec4),
68    Unknown: n*i16 => (i32, glam::IVec2, glam::IVec3, glam::IVec4),
69    Unknown: n*i32 => (i32, glam::IVec2, glam::IVec3, glam::IVec4),
70    Unknown: n*i64 => (i32, glam::IVec2, glam::IVec3, glam::IVec4),
71    Unknown: n*u8 => (u32, glam::UVec2, glam::UVec3, glam::UVec4),
72    Unknown: n*u16 => (u32, glam::UVec2, glam::UVec3, glam::UVec4),
73    Unknown: n*u32 => (u32, glam::UVec2, glam::UVec3, glam::UVec4),
74    Unknown: n*u64 => (u32, glam::UVec2, glam::UVec3, glam::UVec4),
75    Unknown: n*f32 => (f32, glam::Vec2, glam::Vec3, glam::Vec4),
76    Unknown: n*f64 => (f64, glam::DVec2, glam::DVec3, glam::DVec4),
77    Rgba32f: 4*f32 => (f32, glam::Vec2, glam::Vec3, glam::Vec4),
78    Rgba16f: 4*f32 => (f32, glam::Vec2, glam::Vec3, glam::Vec4),
79    R32f: 1*f32 => (f32, glam::Vec2, glam::Vec3, glam::Vec4),
80    Rgba8: 4*f32 => (f32, glam::Vec2, glam::Vec3, glam::Vec4),
81    Rgba8Snorm: 4*f32 => (f32, glam::Vec2, glam::Vec3, glam::Vec4),
82    Rg32f: 2*f32 => (f32, glam::Vec2, glam::Vec3, glam::Vec4),
83    Rg16f: 2*f32 => (f32, glam::Vec2, glam::Vec3, glam::Vec4),
84    R11fG11fB10f: 3*f32 => (f32, glam::Vec2, glam::Vec3, glam::Vec4),
85    R16f: 1*f32 => (f32, glam::Vec2, glam::Vec3, glam::Vec4),
86    Rgba16: 4*f32 => (f32, glam::Vec2, glam::Vec3, glam::Vec4),
87    Rgb10A2: 4*f32 => (f32, glam::Vec2, glam::Vec3, glam::Vec4),
88    Rg16: 2*f32 => (f32, glam::Vec2, glam::Vec3, glam::Vec4),
89    Rg8: 2*f32 => (f32, glam::Vec2, glam::Vec3, glam::Vec4),
90    R16: 1*f32 => (f32, glam::Vec2, glam::Vec3, glam::Vec4),
91    R8: 1*f32 => (f32, glam::Vec2, glam::Vec3, glam::Vec4),
92    Rgba16Snorm: 4*f32 => (f32, glam::Vec2, glam::Vec3, glam::Vec4),
93    Rg16Snorm: 2*f32 => (f32, glam::Vec2, glam::Vec3, glam::Vec4),
94    Rg8Snorm: 2*f32 => (f32, glam::Vec2, glam::Vec3, glam::Vec4),
95    R16Snorm: 1*f32 => (f32, glam::Vec2, glam::Vec3, glam::Vec4),
96    R8Snorm: 1*f32 => (f32, glam::Vec2, glam::Vec3, glam::Vec4),
97    Rgba32i: 4*i32 => (i32, glam::IVec2, glam::IVec3, glam::IVec4),
98    Rgba16i: 4*i32 => (i32, glam::IVec2, glam::IVec3, glam::IVec4),
99    Rgba8i: 4*i32 => (i32, glam::IVec2, glam::IVec3, glam::IVec4),
100    R32i: 1*i32 => (i32, glam::IVec2, glam::IVec3, glam::IVec4),
101    Rg32i: 2*i32 => (i32, glam::IVec2, glam::IVec3, glam::IVec4),
102    Rg16i: 2*i32 => (i32, glam::IVec2, glam::IVec3, glam::IVec4),
103    Rg8i: 2*i32 => (i32, glam::IVec2, glam::IVec3, glam::IVec4),
104    R16i: 1*i32 => (i32, glam::IVec2, glam::IVec3, glam::IVec4),
105    R8i: 1*i32 => (i32, glam::IVec2, glam::IVec3, glam::IVec4),
106    Rgba32ui: 4*u32 => (u32, glam::UVec2, glam::UVec3, glam::UVec4),
107    Rgba16ui: 4*u32 => (u32, glam::UVec2, glam::UVec3, glam::UVec4),
108    Rgba8ui: 4*u32 => (u32, glam::UVec2, glam::UVec3, glam::UVec4),
109    R32ui: 1*u32 => (u32, glam::UVec2, glam::UVec3, glam::UVec4),
110    Rgb10A2ui: 4*u32 => (u32, glam::UVec2, glam::UVec3, glam::UVec4),
111    Rg32ui: 2*u32 => (u32, glam::UVec2, glam::UVec3, glam::UVec4),
112    Rg16ui: 2*u32 => (u32, glam::UVec2, glam::UVec3, glam::UVec4),
113    Rg8ui: 2*u32 => (u32, glam::UVec2, glam::UVec3, glam::UVec4),
114    R16ui: 1*u32 => (u32, glam::UVec2, glam::UVec3, glam::UVec4),
115    R8ui: 1*u32 => (u32, glam::UVec2, glam::UVec3, glam::UVec4),
116    R64ui: 1*u64 => (u32, glam::UVec2, glam::UVec3, glam::UVec4),
117    R64i: 1*i64 => (i32, glam::IVec2, glam::IVec3, glam::IVec4),
118}
119
120/// Marker trait for arguments that accept a coordinate for an [`crate::Image`].
121pub trait ImageCoordinate<T, const DIM: u32, const ARRAYED: u32> {}
122
123impl<S: Scalar> ImageCoordinate<S, { Dimensionality::OneD as u32 }, { Arrayed::False as u32 }>
124    for S
125{
126}
127impl<S: Scalar> ImageCoordinate<S, { Dimensionality::Buffer as u32 }, { Arrayed::False as u32 }>
128    for S
129{
130}
131
132impl<V: Vector<S, 2>, S: Scalar>
133    ImageCoordinate<S, { Dimensionality::TwoD as u32 }, { Arrayed::False as u32 }> for V
134{
135}
136impl<V: Vector<S, 2>, S: Scalar>
137    ImageCoordinate<S, { Dimensionality::Rect as u32 }, { Arrayed::False as u32 }> for V
138{
139}
140impl<V: Vector<S, 3>, S: Scalar>
141    ImageCoordinate<S, { Dimensionality::Cube as u32 }, { Arrayed::False as u32 }> for V
142{
143}
144impl<V: Vector<S, 3>, S: Scalar>
145    ImageCoordinate<S, { Dimensionality::ThreeD as u32 }, { Arrayed::False as u32 }> for V
146{
147}
148
149impl<V: Vector<S, 3>, S: Scalar>
150    ImageCoordinate<S, { Dimensionality::TwoD as u32 }, { Arrayed::True as u32 }> for V
151{
152}
153impl<V: Vector<S, 3>, S: Scalar>
154    ImageCoordinate<S, { Dimensionality::Rect as u32 }, { Arrayed::True as u32 }> for V
155{
156}
157impl<V: Vector<S, 4>, S: Scalar>
158    ImageCoordinate<S, { Dimensionality::Cube as u32 }, { Arrayed::True as u32 }> for V
159{
160}
161impl<V: Vector<S, 4>, S: Scalar>
162    ImageCoordinate<S, { Dimensionality::ThreeD as u32 }, { Arrayed::True as u32 }> for V
163{
164}
165
166/// Marker trait for arguments that are valid for a [`crate::image::Dimensionality::SubpassData`] image query.
167pub trait ImageCoordinateSubpassData<T, const ARRAYED: u32> {}
168impl<V: Vector<I, 2>, I: Integer> ImageCoordinateSubpassData<I, { Arrayed::False as u32 }> for V {}
169impl<V: Vector<I, 3>, I: Integer> ImageCoordinateSubpassData<I, { Arrayed::True as u32 }> for V {}
170
171/// Marker trait for query size results based on image dimension and arraying.
172///
173/// This trait represents the SPIR-V size query results:
174/// - 1D images return a scalar
175/// - 2D/Cube/Rect images return 2 components (Cube returns face width/height)
176/// - 3D images return 3 components
177/// - Arrayed images add one component for the array size
178pub trait ImageSizeQuery<T, const DIM: u32, const ARRAYED: u32> {}
179
180// 1D images
181impl<T: Scalar> ImageSizeQuery<T, { Dimensionality::OneD as u32 }, { Arrayed::False as u32 }>
182    for T
183{
184}
185impl<V: Vector<T, 2>, T: Scalar>
186    ImageSizeQuery<T, { Dimensionality::OneD as u32 }, { Arrayed::True as u32 }> for V
187{
188}
189
190// 2D images
191impl<V: Vector<T, 2>, T: Scalar>
192    ImageSizeQuery<T, { Dimensionality::TwoD as u32 }, { Arrayed::False as u32 }> for V
193{
194}
195impl<V: Vector<T, 3>, T: Scalar>
196    ImageSizeQuery<T, { Dimensionality::TwoD as u32 }, { Arrayed::True as u32 }> for V
197{
198}
199
200// 3D images
201impl<V: Vector<T, 3>, T: Scalar>
202    ImageSizeQuery<T, { Dimensionality::ThreeD as u32 }, { Arrayed::False as u32 }> for V
203{
204}
205impl<V: Vector<T, 4>, T: Scalar>
206    ImageSizeQuery<T, { Dimensionality::ThreeD as u32 }, { Arrayed::True as u32 }> for V
207{
208}
209
210// Cube images - returns 2D size (width/height of face)
211impl<V: Vector<T, 2>, T: Scalar>
212    ImageSizeQuery<T, { Dimensionality::Cube as u32 }, { Arrayed::False as u32 }> for V
213{
214}
215impl<V: Vector<T, 3>, T: Scalar>
216    ImageSizeQuery<T, { Dimensionality::Cube as u32 }, { Arrayed::True as u32 }> for V
217{
218}
219
220// Rect images
221impl<V: Vector<T, 2>, T: Scalar>
222    ImageSizeQuery<T, { Dimensionality::Rect as u32 }, { Arrayed::False as u32 }> for V
223{
224}
225impl<V: Vector<T, 3>, T: Scalar>
226    ImageSizeQuery<T, { Dimensionality::Rect as u32 }, { Arrayed::True as u32 }> for V
227{
228}
229
230// Buffer images
231impl<T: Scalar> ImageSizeQuery<T, { Dimensionality::Buffer as u32 }, { Arrayed::False as u32 }>
232    for T
233{
234}