spirv_std/image/
params.rs

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