spirv_std/image/
params.rs

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