Skip to content

Commit 5ac7369

Browse files
committed
Add ImageSizeQuery
Without this cubemaps were broken...we were returning UVec3 but spirv validation required UVec2.
1 parent 3da2aff commit 5ac7369

File tree

5 files changed

+97
-8
lines changed

5 files changed

+97
-8
lines changed

crates/spirv-std/src/image.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ mod params;
1010
/// Contains extra image operands
1111
pub mod sample_with;
1212

13-
pub use self::params::{ImageCoordinate, ImageCoordinateSubpassData, SampleType};
13+
pub use self::params::{ImageCoordinate, ImageCoordinateSubpassData, ImageSizeQuery, SampleType};
1414
pub use crate::macros::Image;
1515
pub use spirv_std_types::image_params::{
1616
AccessQualifier, Arrayed, Dimensionality, ImageDepth, ImageFormat, Multisampled, Sampled,
@@ -933,7 +933,7 @@ impl<
933933
/// Query the dimensions of Image, with no level of detail.
934934
#[crate::macros::gpu_only]
935935
#[doc(alias = "OpImageQuerySize")]
936-
pub fn query_size<Size: ImageCoordinate<u32, DIM, ARRAYED> + Default>(&self) -> Size
936+
pub fn query_size<Size: ImageSizeQuery<u32, DIM, ARRAYED> + Default>(&self) -> Size
937937
where
938938
Self: HasQuerySize,
939939
{
@@ -971,10 +971,10 @@ impl<
971971
COMPONENTS,
972972
>
973973
{
974-
/// Query the dimensions of Image, with no level of detail.
974+
/// Query the dimensions of Image at a specific level of detail.
975975
#[crate::macros::gpu_only]
976976
#[doc(alias = "OpImageQuerySizeLod")]
977-
pub fn query_size_lod<Size: ImageCoordinate<u32, DIM, ARRAYED> + Default>(
977+
pub fn query_size_lod<Size: ImageSizeQuery<u32, DIM, ARRAYED> + Default>(
978978
&self,
979979
lod: u32,
980980
) -> Size
@@ -1121,7 +1121,7 @@ impl<
11211121
/// Query the dimensions of the image at the specified level of detail.
11221122
#[crate::macros::gpu_only]
11231123
#[doc(alias = "OpImageQuerySizeLod")]
1124-
pub fn query_size_lod<Size: ImageCoordinate<u32, DIM, ARRAYED> + Default>(
1124+
pub fn query_size_lod<Size: ImageSizeQuery<u32, DIM, ARRAYED> + Default>(
11251125
&self,
11261126
lod: u32,
11271127
) -> Size
@@ -1179,7 +1179,7 @@ impl<
11791179
/// Available only for multisampled images.
11801180
#[crate::macros::gpu_only]
11811181
#[doc(alias = "OpImageQuerySize")]
1182-
pub fn query_size<Size: ImageCoordinate<u32, DIM, ARRAYED> + Default>(&self) -> Size
1182+
pub fn query_size<Size: ImageSizeQuery<u32, DIM, ARRAYED> + Default>(&self) -> Size
11831183
where
11841184
Image<
11851185
SampledType,

crates/spirv-std/src/image/params.rs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,3 +194,68 @@ impl<V: Vector<S, 4>, S: Scalar>
194194
pub trait ImageCoordinateSubpassData<T, const ARRAYED: u32> {}
195195
impl<V: Vector<I, 2>, I: Integer> ImageCoordinateSubpassData<I, { Arrayed::False as u32 }> for V {}
196196
impl<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+
/// Unlike `ImageCoordinate`, 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
205+
pub trait ImageSizeQuery<T, const DIM: u32, const ARRAYED: u32> {}
206+
207+
// 1D images
208+
impl<T: Scalar> ImageSizeQuery<T, { Dimensionality::OneD as u32 }, { Arrayed::False as u32 }>
209+
for T
210+
{
211+
}
212+
impl<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
218+
impl<V: Vector<T, 2>, T: Scalar>
219+
ImageSizeQuery<T, { Dimensionality::TwoD as u32 }, { Arrayed::False as u32 }> for V
220+
{
221+
}
222+
impl<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
228+
impl<V: Vector<T, 3>, T: Scalar>
229+
ImageSizeQuery<T, { Dimensionality::ThreeD as u32 }, { Arrayed::False as u32 }> for V
230+
{
231+
}
232+
impl<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)
238+
impl<V: Vector<T, 2>, T: Scalar>
239+
ImageSizeQuery<T, { Dimensionality::Cube as u32 }, { Arrayed::False as u32 }> for V
240+
{
241+
}
242+
impl<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
248+
impl<V: Vector<T, 2>, T: Scalar>
249+
ImageSizeQuery<T, { Dimensionality::Rect as u32 }, { Arrayed::False as u32 }> for V
250+
{
251+
}
252+
impl<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
258+
impl<T: Scalar> ImageSizeQuery<T, { Dimensionality::Buffer as u32 }, { Arrayed::False as u32 }>
259+
for T
260+
{
261+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// build-pass
2+
// compile-flags: -C target-feature=+ImageQuery
3+
4+
use spirv_std::spirv;
5+
use spirv_std::{Image, arch, image::Cubemap};
6+
7+
#[spirv(fragment)]
8+
pub fn main(
9+
#[spirv(descriptor_set = 0, binding = 0)] cubemap: &Cubemap,
10+
#[spirv(descriptor_set = 1, binding = 1)] cubemap_array: &Image!(cube, type=f32, sampled, arrayed),
11+
#[spirv(descriptor_set = 2, binding = 2)] storage_cubemap: &Image!(cube, type=f32, sampled=false),
12+
output: &mut glam::UVec3,
13+
) {
14+
// Cubemaps return 2D size (width, height of one face)
15+
let size: glam::UVec2 = cubemap.query_size_lod(0);
16+
17+
// Arrayed cubemaps return 3D size (width, height, array_layers)
18+
let size_array: glam::UVec3 = cubemap_array.query_size_lod(0);
19+
20+
// Storage cubemaps can use query_size directly
21+
let storage_size: glam::UVec2 = storage_cubemap.query_size();
22+
23+
*output = glam::UVec3::new(size.x, size_array.z, storage_size.x);
24+
}

tests/compiletests/ui/image/query/query_size_err.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ error[E0277]: the trait bound `Image<f32, 1, 2, 0, 0, 1, 0, 4>: HasQuerySize` is
1717
note: required by a bound in `Image::<SampledType, DIM, DEPTH, ARRAYED, MULTISAMPLED, SAMPLED, FORMAT, COMPONENTS>::query_size`
1818
--> $SPIRV_STD_SRC/image.rs:938:15
1919
|
20-
936 | pub fn query_size<Size: ImageCoordinate<u32, DIM, ARRAYED> + Default>(&self) -> Size
20+
936 | pub fn query_size<Size: ImageSizeQuery<u32, DIM, ARRAYED> + Default>(&self) -> Size
2121
| ---------- required by a bound in this associated function
2222
937 | where
2323
938 | Self: HasQuerySize,

tests/compiletests/ui/image/query/query_size_lod_err.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ error[E0277]: the trait bound `Image<f32, 4, 2, 0, 0, 1, 0, 4>: HasQuerySizeLod`
1212
note: required by a bound in `Image::<SampledType, DIM, DEPTH, ARRAYED, spirv_std::::image::{impl#7}::{constant#0}, SAMPLED, FORMAT, COMPONENTS>::query_size_lod`
1313
--> $SPIRV_STD_SRC/image.rs:982:15
1414
|
15-
977 | pub fn query_size_lod<Size: ImageCoordinate<u32, DIM, ARRAYED> + Default>(
15+
977 | pub fn query_size_lod<Size: ImageSizeQuery<u32, DIM, ARRAYED> + Default>(
1616
| -------------- required by a bound in this associated function
1717
...
1818
982 | Self: HasQuerySizeLod,

0 commit comments

Comments
 (0)