From 31ff096d247d6f69bad98945e2b81844b498fc4c Mon Sep 17 00:00:00 2001 From: Sylvester Hesp Date: Wed, 12 Apr 2023 14:58:21 +0200 Subject: [PATCH] Added generic parameter for number of components to `Image` --- CHANGELOG.md | 1 + crates/spirv-std/macros/src/image.rs | 94 ++++- crates/spirv-std/src/image.rs | 349 +++++++++++++----- crates/spirv-std/src/image/params.rs | 177 ++++++--- crates/spirv-std/src/vector.rs | 41 ++ tests/ui/image/components.rs | 30 ++ tests/ui/image/gather_err.stderr | 36 +- .../ui/image/implicit_not_in_fragment.stderr | 4 +- tests/ui/image/query/query_levels_err.stderr | 20 +- tests/ui/image/query/query_lod_err.stderr | 20 +- tests/ui/image/query/query_size_err.stderr | 28 +- .../ui/image/query/query_size_lod_err.stderr | 20 +- .../bad-deduce-storage-class.stderr | 2 +- 13 files changed, 607 insertions(+), 215 deletions(-) create mode 100644 tests/ui/image/components.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 617f14eaf4..97feb4454a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Changed 🛠 +- [PR#1031](https://github.com/EmbarkStudios/rust-gpu/pull/1031) Added `Components` generic parameter to `Image` type, allowing images to return lower dimensional vectors and even scalars from the sampling API. - [PR#1011](https://github.com/EmbarkStudios/rust-gpu/pull/1011) made `NonWritable` all read-only storage buffers (i.e. those typed `&T`, where `T` doesn't have interior mutability) - [PR#1029](https://github.com/EmbarkStudios/rust-gpu/pull/1029) fixed SampledImage::sample() fns being unnecessarily marked as unsafe diff --git a/crates/spirv-std/macros/src/image.rs b/crates/spirv-std/macros/src/image.rs index 165e0342f2..654779a10d 100644 --- a/crates/spirv-std/macros/src/image.rs +++ b/crates/spirv-std/macros/src/image.rs @@ -33,6 +33,7 @@ pub struct ImageType { multisampled: Multisampled, sampled: Sampled, sampled_type: SampledType, + components: u32, } impl Parse for ImageType { @@ -45,6 +46,7 @@ impl Parse for ImageType { let mut multisampled = None; let mut sampled: Option = None; let mut crate_root = None; + let mut components = None; let starting_span = input.span(); @@ -137,6 +139,27 @@ impl Parse for ImageType { } format = value.ok(); + } else if ident == "components" { + let value = peek_and_eat_value!(syn::LitInt); + + if value.is_none() { + return Err(syn::Error::new( + ident.span(), + "Expected argument for `components`.", + )); + } + + let value = value.unwrap(); + set_unique!( + components = match value.base10_parse() { + Ok(n) if n >= 1 && n <= 4 => n, + _ => + return Err(syn::Error::new( + value.span(), + "Unexpected integer for `components`." + )), + } + ); } else if ident == "__crate_root" { input.parse::()?; crate_root = Some(input.parse::()?); @@ -216,17 +239,23 @@ impl Parse for ImageType { ) })?; - if format.is_some() && sampled_type.is_some() { - if format != Some(ImageFormat::Unknown) { + if format.is_some() && format != Some(ImageFormat::Unknown) { + if sampled_type.is_some() { return Err(syn::Error::new( starting_span, "Can't specify `type` with a known image format. Either \ specify just the `format` or use `format=unknown`.", )); } - } else if sampled_type.is_some() { - format = Some(ImageFormat::Unknown); - } else if let Some(format) = &format { + if components.is_some() { + return Err(syn::Error::new( + starting_span, + "Can't specify `components` with a known image format. Either \ + specify just the `format` or use `format=unknown`.", + )); + } + + let format = format.as_ref().unwrap(); sampled_type = Some(match format { ImageFormat::Rgba32f | ImageFormat::Rgba16f @@ -276,6 +305,57 @@ impl Parse for ImageType { ImageFormat::Unknown => unreachable!(), }); + + components = Some(match format { + ImageFormat::Rgba32f + | ImageFormat::Rgba16f + | ImageFormat::Rgba8 + | ImageFormat::Rgba8Snorm + | ImageFormat::Rgba16 + | ImageFormat::Rgb10A2 + | ImageFormat::Rgba16Snorm + | ImageFormat::Rgba32i + | ImageFormat::Rgba16i + | ImageFormat::Rgba8i + | ImageFormat::Rgba32ui + | ImageFormat::Rgba16ui + | ImageFormat::Rgba8ui + | ImageFormat::Rgb10A2ui => 4, + + ImageFormat::R11fG11fB10f => 3, + + ImageFormat::Rg32f + | ImageFormat::Rg16f + | ImageFormat::Rg16 + | ImageFormat::Rg8 + | ImageFormat::Rg16Snorm + | ImageFormat::Rg8Snorm + | ImageFormat::Rg32i + | ImageFormat::Rg16i + | ImageFormat::Rg8i + | ImageFormat::Rg32ui + | ImageFormat::Rg16ui + | ImageFormat::Rg8ui => 2, + + ImageFormat::R32f + | ImageFormat::R16f + | ImageFormat::R16 + | ImageFormat::R8 + | ImageFormat::R16Snorm + | ImageFormat::R8Snorm + | ImageFormat::R32i + | ImageFormat::R16i + | ImageFormat::R8i + | ImageFormat::R32ui + | ImageFormat::R16ui + | ImageFormat::R8ui + | ImageFormat::R64ui + | ImageFormat::R64i => 1, + + ImageFormat::Unknown => unreachable!(), + }); + } else if sampled_type.is_some() { + format = Some(ImageFormat::Unknown); } let sampled_type = @@ -285,6 +365,7 @@ impl Parse for ImageType { let arrayed = arrayed.unwrap_or(Arrayed::False); let multisampled = multisampled.unwrap_or(Multisampled::False); let sampled = sampled.unwrap_or(Sampled::Unknown); + let components = components.unwrap_or(4); Ok(Self { arrayed, @@ -295,6 +376,7 @@ impl Parse for ImageType { multisampled, sampled, sampled_type, + components, }) } } @@ -317,6 +399,7 @@ impl quote::ToTokens for ImageType { let multisampled = params::multisampled_to_tokens(&self.multisampled); let sampled = params::sampled_to_tokens(&self.sampled); let sampled_type = &self.sampled_type; + let components = self.components; tokens.append_all(quote::quote! { #crate_root::image::Image< @@ -327,6 +410,7 @@ impl quote::ToTokens for ImageType { { #crate_root::image::#multisampled as u32 }, { #crate_root::image::#sampled as u32 }, { #crate_root::image::#format as u32 }, + { #components as u32 }, > }); } diff --git a/crates/spirv-std/src/image.rs b/crates/spirv-std/src/image.rs index 0853d2ecd1..19d048ccaa 100644 --- a/crates/spirv-std/src/image.rs +++ b/crates/spirv-std/src/image.rs @@ -14,7 +14,12 @@ pub use spirv_std_types::image_params::{ AccessQualifier, Arrayed, Dimensionality, ImageDepth, ImageFormat, Multisampled, Sampled, }; -use crate::{float::Float, integer::Integer, vector::Vector, Sampler}; +use crate::{ + float::Float, + integer::Integer, + vector::{Vector, VectorTruncateInto}, + Sampler, +}; /// Re-export of primitive types to ensure the `Image` proc macro always points /// to the right type. @@ -97,13 +102,14 @@ pub type Cubemap = crate::Image!(cube, type=f32, sampled, __crate_root=crate); // HACK(eddyb) avoids "transparent newtype of `_anti_zst_padding`" misinterpretation. #[repr(C)] pub struct Image< - SampledType: SampleType, + SampledType: SampleType, const DIM: u32, // Dimensionality, const DEPTH: u32, // ImageDepth, const ARRAYED: u32, // Arrayed, const MULTISAMPLED: u32, // Multisampled, const SAMPLED: u32, // Sampled, const FORMAT: u32, // ImageFormat, + const COMPONENTS: u32, // NumberOfComponents, > { // HACK(eddyb) avoids the layout becoming ZST (and being elided in one way // or another, before `#[spirv(generic_image_type)]` can special-case it). @@ -112,22 +118,36 @@ pub struct Image< } impl< - SampledType: SampleType, + SampledType: SampleType, const DIM: u32, const DEPTH: u32, const ARRAYED: u32, const MULTISAMPLED: u32, const FORMAT: u32, - > Image + const COMPONENTS: u32, + > + Image< + SampledType, + DIM, + DEPTH, + ARRAYED, + MULTISAMPLED, + { Sampled::Yes as u32 }, + FORMAT, + COMPONENTS, + > { /// Fetch a single texel with a sampler set at compile time #[crate::macros::gpu_only] #[doc(alias = "OpImageFetch")] - pub fn fetch(&self, coordinate: impl ImageCoordinate) -> SampledType::Vec4 + pub fn fetch( + &self, + coordinate: impl ImageCoordinate, + ) -> SampledType::SampleResult where I: Integer, { - let mut result = Default::default(); + let mut result = SampledType::Vec4::default(); unsafe { asm! { "%image = OpLoad _ {this}", @@ -139,18 +159,29 @@ impl< coordinate = in(reg) &coordinate, } } - result + result.truncate_into() } } impl< - SampledType: SampleType, + SampledType: SampleType, const DIM: u32, const DEPTH: u32, const FORMAT: u32, const ARRAYED: u32, const SAMPLED: u32, - > Image + const COMPONENTS: u32, + > + Image< + SampledType, + DIM, + DEPTH, + ARRAYED, + { Multisampled::False as u32 }, + SAMPLED, + FORMAT, + COMPONENTS, + > { // Note: #[inline] is needed because in vulkan, the component must be a constant expression. /// Gathers the requested component from four texels. @@ -162,12 +193,12 @@ impl< sampler: Sampler, coordinate: impl ImageCoordinate, component: u32, - ) -> SampledType::Vec4 + ) -> SampledType::SampleResult where Self: HasGather, F: Float, { - let mut result = Default::default(); + let mut result = SampledType::Vec4::default(); unsafe { asm! { "%typeSampledImage = OpTypeSampledImage typeof*{this}", @@ -184,7 +215,7 @@ impl< component = in(reg) component, } } - result + result.truncate_into() } /// Sample texels at `coord` from the image using `sampler`. @@ -193,12 +224,12 @@ impl< &self, sampler: Sampler, coord: impl ImageCoordinate, - ) -> SampledType::Vec4 + ) -> SampledType::SampleResult where F: Float, { unsafe { - let mut result = Default::default(); + let mut result = SampledType::Vec4::default(); asm!( "%typeSampledImage = OpTypeSampledImage typeof*{1}", "%image = OpLoad typeof*{1} {1}", @@ -212,7 +243,7 @@ impl< in(reg) &sampler, in(reg) &coord ); - result + result.truncate_into() } } @@ -224,12 +255,13 @@ impl< sampler: Sampler, coord: impl ImageCoordinate, bias: f32, - ) -> SampledType::Vec4 + ) -> SampledType::SampleResult where F: Float, { unsafe { - let mut result = Default::default(); + let mut result = SampledType::Vec4::default(); + asm!( "%typeSampledImage = OpTypeSampledImage typeof*{1}", "%image = OpLoad typeof*{1} {1}", @@ -244,7 +276,7 @@ impl< in(reg) &coord, in(reg) bias, ); - result + result.truncate_into() } } @@ -257,11 +289,11 @@ impl< sampler: Sampler, coordinate: impl ImageCoordinate, lod: f32, - ) -> SampledType::Vec4 + ) -> SampledType::SampleResult where F: Float, { - let mut result = Default::default(); + let mut result = SampledType::Vec4::default(); unsafe { asm!( "%image = OpLoad _ {this}", @@ -278,7 +310,7 @@ impl< lod = in(reg) &lod ); } - result + result.truncate_into() } #[crate::macros::gpu_only] @@ -290,11 +322,11 @@ impl< coordinate: impl ImageCoordinate, gradient_dx: impl ImageCoordinate, gradient_dy: impl ImageCoordinate, - ) -> SampledType::Vec4 + ) -> SampledType::SampleResult where F: Float, { - let mut result = Default::default(); + let mut result = SampledType::Vec4::default(); unsafe { asm!( "%image = OpLoad _ {this}", @@ -313,7 +345,7 @@ impl< gradient_dy = in(reg) &gradient_dy, ); } - result + result.truncate_into() } #[crate::macros::gpu_only] @@ -424,11 +456,12 @@ impl< } impl< - SampledType: SampleType, + SampledType: SampleType, const DIM: u32, const DEPTH: u32, const SAMPLED: u32, const FORMAT: u32, + const COMPONENTS: u32, > Image< SampledType, @@ -438,6 +471,7 @@ impl< { Multisampled::False as u32 }, SAMPLED, FORMAT, + COMPONENTS, > { /// Sample the image with a project coordinate @@ -447,12 +481,12 @@ impl< &self, sampler: Sampler, project_coordinate: impl ImageCoordinate, - ) -> SampledType::Vec4 + ) -> SampledType::SampleResult where F: Float, { unsafe { - let mut result = Default::default(); + let mut result = SampledType::Vec4::default(); asm!( "%image = OpLoad _ {this}", "%sampler = OpLoad _ {sampler}", @@ -465,7 +499,7 @@ impl< sampler = in(reg) &sampler, project_coordinate = in(reg) &project_coordinate, ); - result + result.truncate_into() } } @@ -644,22 +678,36 @@ impl< } impl< - SampledType: SampleType, + SampledType: SampleType, const DIM: u32, const DEPTH: u32, const ARRAYED: u32, const MULTISAMPLED: u32, const FORMAT: u32, - > Image + const COMPONENTS: u32, + > + Image< + SampledType, + DIM, + DEPTH, + ARRAYED, + MULTISAMPLED, + { Sampled::No as u32 }, + FORMAT, + COMPONENTS, + > { /// Read a texel from an image without a sampler. #[crate::macros::gpu_only] #[doc(alias = "OpImageRead")] - pub fn read(&self, coordinate: impl ImageCoordinate) -> SampledType::Vec4 + pub fn read( + &self, + coordinate: impl ImageCoordinate, + ) -> SampledType::SampleResult where I: Integer, { - let mut result = Default::default(); + let mut result = SampledType::Vec4::default(); unsafe { asm! { @@ -673,7 +721,7 @@ impl< } } - result + result.truncate_into() } /// Write a texel to an image without a sampler. @@ -699,22 +747,36 @@ impl< } impl< - SampledType: SampleType, + SampledType: SampleType, const DIM: u32, const DEPTH: u32, const FORMAT: u32, const ARRAYED: u32, const MULTISAMPLED: u32, - > Image + const COMPONENTS: u32, + > + Image< + SampledType, + DIM, + DEPTH, + ARRAYED, + MULTISAMPLED, + { Sampled::Unknown as u32 }, + FORMAT, + COMPONENTS, + > { /// Read a texel from an image without a sampler. #[crate::macros::gpu_only] #[doc(alias = "OpImageRead")] - pub fn read(&self, coordinate: impl ImageCoordinate) -> SampledType::Vec4 + pub fn read( + &self, + coordinate: impl ImageCoordinate, + ) -> SampledType::SampleResult where I: Integer, { - let mut result = Default::default(); + let mut result = SampledType::Vec4::default(); unsafe { asm! { @@ -728,7 +790,7 @@ impl< } } - result + result.truncate_into() } /// Write a texel to an image without a sampler. @@ -754,11 +816,12 @@ impl< } impl< - SampledType: SampleType, + SampledType: SampleType, const DEPTH: u32, const ARRAYED: u32, const MULTISAMPLED: u32, const FORMAT: u32, + const COMPONENTS: u32, > Image< SampledType, @@ -768,6 +831,7 @@ impl< MULTISAMPLED, { Sampled::No as u32 }, FORMAT, + COMPONENTS, > { /// Read a texel from subpass input attachment. @@ -777,11 +841,11 @@ impl< pub fn read_subpass( &self, coordinate: impl ImageCoordinateSubpassData, - ) -> SampledType::Vec4 + ) -> SampledType::SampleResult where I: Integer, { - let mut result = Default::default(); + let mut result = SampledType::Vec4::default(); unsafe { asm! { @@ -795,19 +859,20 @@ impl< } } - result + result.truncate_into() } } impl< - SampledType: SampleType, + SampledType: SampleType, const DIM: u32, const DEPTH: u32, const ARRAYED: u32, const MULTISAMPLED: u32, const SAMPLED: u32, const FORMAT: u32, - > Image + const COMPONENTS: u32, + > Image { /// Query the number of mipmap levels. #[crate::macros::gpu_only] @@ -888,13 +953,24 @@ impl< } impl< - SampledType: SampleType, + SampledType: SampleType, const DIM: u32, const DEPTH: u32, const ARRAYED: u32, const SAMPLED: u32, const FORMAT: u32, - > Image + const COMPONENTS: u32, + > + Image< + SampledType, + DIM, + DEPTH, + ARRAYED, + { Multisampled::False as u32 }, + SAMPLED, + FORMAT, + COMPONENTS, + > { /// Query the dimensions of Image, with no level of detail. #[crate::macros::gpu_only] @@ -922,11 +998,12 @@ impl< } impl< - SampledType: SampleType, + SampledType: SampleType, const DEPTH: u32, const ARRAYED: u32, const SAMPLED: u32, const FORMAT: u32, + const COMPONENTS: u32, > Image< SampledType, @@ -936,6 +1013,7 @@ impl< { Multisampled::True as u32 }, SAMPLED, FORMAT, + COMPONENTS, > { /// Query the number of samples available per texel fetch in a multisample image. @@ -967,24 +1045,37 @@ pub struct SampledImage { } impl< - SampledType: SampleType, + SampledType: SampleType, const DIM: u32, const DEPTH: u32, const ARRAYED: u32, const SAMPLED: u32, const FORMAT: u32, + const COMPONENTS: u32, > SampledImage< - Image, + Image< + SampledType, + DIM, + DEPTH, + ARRAYED, + { Multisampled::False as u32 }, + SAMPLED, + FORMAT, + COMPONENTS, + >, > { /// Sample texels at `coord` from the sampled image with an implicit lod. #[crate::macros::gpu_only] - pub fn sample(&self, coord: impl ImageCoordinate) -> SampledType::Vec4 + pub fn sample( + &self, + coord: impl ImageCoordinate, + ) -> SampledType::SampleResult where F: Float, { - let mut result = Default::default(); + let mut result = SampledType::Vec4::default(); unsafe { asm!( "%sampledImage = OpLoad typeof*{1} {1}", @@ -996,7 +1087,7 @@ impl< in(reg) &coord ); } - result + result.truncate_into() } /// Sample texels at `coord` from the sampled image with an explicit lod. @@ -1005,11 +1096,11 @@ impl< &self, coord: impl ImageCoordinate, lod: f32, - ) -> SampledType::Vec4 + ) -> SampledType::SampleResult where F: Float, { - let mut result = Default::default(); + let mut result = SampledType::Vec4::default(); unsafe { asm!( "%sampledImage = OpLoad typeof*{1} {1}", @@ -1023,7 +1114,7 @@ impl< in(reg) &lod, ); } - result + result.truncate_into() } } @@ -1034,11 +1125,12 @@ impl< /// `OpTypeImage` must be 0." pub trait HasGather {} impl< - SampledType: SampleType, + SampledType: SampleType, const DEPTH: u32, const FORMAT: u32, const ARRAYED: u32, const SAMPLED: u32, + const COMPONENTS: u32, > HasGather for Image< SampledType, @@ -1048,15 +1140,17 @@ impl< { Multisampled::False as u32 }, SAMPLED, FORMAT, + COMPONENTS, > { } impl< - SampledType: SampleType, + SampledType: SampleType, const DEPTH: u32, const FORMAT: u32, const ARRAYED: u32, const SAMPLED: u32, + const COMPONENTS: u32, > HasGather for Image< SampledType, @@ -1066,15 +1160,17 @@ impl< { Multisampled::False as u32 }, SAMPLED, FORMAT, + COMPONENTS, > { } impl< - SampledType: SampleType, + SampledType: SampleType, const DEPTH: u32, const FORMAT: u32, const ARRAYED: u32, const SAMPLED: u32, + const COMPONENTS: u32, > HasGather for Image< SampledType, @@ -1084,6 +1180,7 @@ impl< { Multisampled::False as u32 }, SAMPLED, FORMAT, + COMPONENTS, > { } @@ -1094,12 +1191,13 @@ impl< /// "Its Dim operand must be one of 1D, 2D, 3D, or Cube." pub trait HasQueryLevels {} impl< - SampledType: SampleType, + SampledType: SampleType, const DEPTH: u32, const FORMAT: u32, const ARRAYED: u32, const MULTISAMPLED: u32, const SAMPLED: u32, + const COMPONENTS: u32, > HasQueryLevels for Image< SampledType, @@ -1109,16 +1207,18 @@ impl< MULTISAMPLED, SAMPLED, FORMAT, + COMPONENTS, > { } impl< - SampledType: SampleType, + SampledType: SampleType, const DEPTH: u32, const FORMAT: u32, const ARRAYED: u32, const MULTISAMPLED: u32, const SAMPLED: u32, + const COMPONENTS: u32, > HasQueryLevels for Image< SampledType, @@ -1128,16 +1228,18 @@ impl< MULTISAMPLED, SAMPLED, FORMAT, + COMPONENTS, > { } impl< - SampledType: SampleType, + SampledType: SampleType, const DEPTH: u32, const FORMAT: u32, const ARRAYED: u32, const MULTISAMPLED: u32, const SAMPLED: u32, + const COMPONENTS: u32, > HasQueryLevels for Image< SampledType, @@ -1147,16 +1249,18 @@ impl< MULTISAMPLED, SAMPLED, FORMAT, + COMPONENTS, > { } impl< - SampledType: SampleType, + SampledType: SampleType, const DEPTH: u32, const FORMAT: u32, const ARRAYED: u32, const MULTISAMPLED: u32, const SAMPLED: u32, + const COMPONENTS: u32, > HasQueryLevels for Image< SampledType, @@ -1166,6 +1270,7 @@ impl< MULTISAMPLED, SAMPLED, FORMAT, + COMPONENTS, > { } @@ -1177,11 +1282,12 @@ impl< /// 3D, or Cube, it must also have either an MS of 1 or a Sampled of 0 or 2." pub trait HasQuerySize {} impl< - SampledType: SampleType, + SampledType: SampleType, const DEPTH: u32, const FORMAT: u32, const ARRAYED: u32, const SAMPLED: u32, + const COMPONENTS: u32, > HasQuerySize for Image< SampledType, @@ -1191,11 +1297,17 @@ impl< { Multisampled::True as u32 }, SAMPLED, FORMAT, + COMPONENTS, > { } -impl, const DEPTH: u32, const FORMAT: u32, const ARRAYED: u32> - HasQuerySize +impl< + SampledType: SampleType, + const DEPTH: u32, + const FORMAT: u32, + const ARRAYED: u32, + const COMPONENTS: u32, + > HasQuerySize for Image< SampledType, { Dimensionality::OneD as u32 }, @@ -1204,11 +1316,17 @@ impl, const DEPTH: u32, const FORMAT: u32, const { Multisampled::False as u32 }, { Sampled::Unknown as u32 }, FORMAT, + COMPONENTS, > { } -impl, const DEPTH: u32, const FORMAT: u32, const ARRAYED: u32> - HasQuerySize +impl< + SampledType: SampleType, + const DEPTH: u32, + const FORMAT: u32, + const ARRAYED: u32, + const COMPONENTS: u32, + > HasQuerySize for Image< SampledType, { Dimensionality::OneD as u32 }, @@ -1217,15 +1335,17 @@ impl, const DEPTH: u32, const FORMAT: u32, const { Multisampled::False as u32 }, { Sampled::No as u32 }, FORMAT, + COMPONENTS, > { } impl< - SampledType: SampleType, + SampledType: SampleType, const DEPTH: u32, const FORMAT: u32, const ARRAYED: u32, const SAMPLED: u32, + const COMPONENTS: u32, > HasQuerySize for Image< SampledType, @@ -1235,11 +1355,17 @@ impl< { Multisampled::True as u32 }, SAMPLED, FORMAT, + COMPONENTS, > { } -impl, const DEPTH: u32, const FORMAT: u32, const ARRAYED: u32> - HasQuerySize +impl< + SampledType: SampleType, + const DEPTH: u32, + const FORMAT: u32, + const ARRAYED: u32, + const COMPONENTS: u32, + > HasQuerySize for Image< SampledType, { Dimensionality::TwoD as u32 }, @@ -1248,11 +1374,17 @@ impl, const DEPTH: u32, const FORMAT: u32, const { Multisampled::False as u32 }, { Sampled::Unknown as u32 }, FORMAT, + COMPONENTS, > { } -impl, const DEPTH: u32, const FORMAT: u32, const ARRAYED: u32> - HasQuerySize +impl< + SampledType: SampleType, + const DEPTH: u32, + const FORMAT: u32, + const ARRAYED: u32, + const COMPONENTS: u32, + > HasQuerySize for Image< SampledType, { Dimensionality::TwoD as u32 }, @@ -1261,15 +1393,17 @@ impl, const DEPTH: u32, const FORMAT: u32, const { Multisampled::False as u32 }, { Sampled::No as u32 }, FORMAT, + COMPONENTS, > { } impl< - SampledType: SampleType, + SampledType: SampleType, const DEPTH: u32, const FORMAT: u32, const ARRAYED: u32, const SAMPLED: u32, + const COMPONENTS: u32, > HasQuerySize for Image< SampledType, @@ -1279,11 +1413,17 @@ impl< { Multisampled::True as u32 }, SAMPLED, FORMAT, + COMPONENTS, > { } -impl, const DEPTH: u32, const FORMAT: u32, const ARRAYED: u32> - HasQuerySize +impl< + SampledType: SampleType, + const DEPTH: u32, + const FORMAT: u32, + const ARRAYED: u32, + const COMPONENTS: u32, + > HasQuerySize for Image< SampledType, { Dimensionality::ThreeD as u32 }, @@ -1292,11 +1432,17 @@ impl, const DEPTH: u32, const FORMAT: u32, const { Multisampled::False as u32 }, { Sampled::Unknown as u32 }, FORMAT, + COMPONENTS, > { } -impl, const DEPTH: u32, const FORMAT: u32, const ARRAYED: u32> - HasQuerySize +impl< + SampledType: SampleType, + const DEPTH: u32, + const FORMAT: u32, + const ARRAYED: u32, + const COMPONENTS: u32, + > HasQuerySize for Image< SampledType, { Dimensionality::ThreeD as u32 }, @@ -1305,15 +1451,17 @@ impl, const DEPTH: u32, const FORMAT: u32, const { Multisampled::False as u32 }, { Sampled::No as u32 }, FORMAT, + COMPONENTS, > { } impl< - SampledType: SampleType, + SampledType: SampleType, const DEPTH: u32, const FORMAT: u32, const ARRAYED: u32, const SAMPLED: u32, + const COMPONENTS: u32, > HasQuerySize for Image< SampledType, @@ -1323,11 +1471,17 @@ impl< { Multisampled::True as u32 }, SAMPLED, FORMAT, + COMPONENTS, > { } -impl, const DEPTH: u32, const FORMAT: u32, const ARRAYED: u32> - HasQuerySize +impl< + SampledType: SampleType, + const DEPTH: u32, + const FORMAT: u32, + const ARRAYED: u32, + const COMPONENTS: u32, + > HasQuerySize for Image< SampledType, { Dimensionality::Cube as u32 }, @@ -1336,11 +1490,17 @@ impl, const DEPTH: u32, const FORMAT: u32, const { Multisampled::False as u32 }, { Sampled::Unknown as u32 }, FORMAT, + COMPONENTS, > { } -impl, const DEPTH: u32, const FORMAT: u32, const ARRAYED: u32> - HasQuerySize +impl< + SampledType: SampleType, + const DEPTH: u32, + const FORMAT: u32, + const ARRAYED: u32, + const COMPONENTS: u32, + > HasQuerySize for Image< SampledType, { Dimensionality::Cube as u32 }, @@ -1349,16 +1509,18 @@ impl, const DEPTH: u32, const FORMAT: u32, const { Multisampled::False as u32 }, { Sampled::No as u32 }, FORMAT, + COMPONENTS, > { } impl< - SampledType: SampleType, + SampledType: SampleType, const DEPTH: u32, const FORMAT: u32, const ARRAYED: u32, const MULTISAMPLED: u32, const SAMPLED: u32, + const COMPONENTS: u32, > HasQuerySize for Image< SampledType, @@ -1368,16 +1530,18 @@ impl< MULTISAMPLED, SAMPLED, FORMAT, + COMPONENTS, > { } impl< - SampledType: SampleType, + SampledType: SampleType, const DEPTH: u32, const FORMAT: u32, const ARRAYED: u32, const MULTISAMPLED: u32, const SAMPLED: u32, + const COMPONENTS: u32, > HasQuerySize for Image< SampledType, @@ -1387,6 +1551,7 @@ impl< MULTISAMPLED, SAMPLED, FORMAT, + COMPONENTS, > { } @@ -1397,11 +1562,12 @@ impl< /// "Its Dim operand must be one of 1D, 2D, 3D, or Cube, and its MS must be 0." pub trait HasQuerySizeLod {} impl< - SampledType: SampleType, + SampledType: SampleType, const DEPTH: u32, const FORMAT: u32, const ARRAYED: u32, const SAMPLED: u32, + const COMPONENTS: u32, > HasQuerySizeLod for Image< SampledType, @@ -1411,15 +1577,17 @@ impl< { Multisampled::False as u32 }, SAMPLED, FORMAT, + COMPONENTS, > { } impl< - SampledType: SampleType, + SampledType: SampleType, const DEPTH: u32, const FORMAT: u32, const ARRAYED: u32, const SAMPLED: u32, + const COMPONENTS: u32, > HasQuerySizeLod for Image< SampledType, @@ -1429,15 +1597,17 @@ impl< { Multisampled::False as u32 }, SAMPLED, FORMAT, + COMPONENTS, > { } impl< - SampledType: SampleType, + SampledType: SampleType, const DEPTH: u32, const FORMAT: u32, const ARRAYED: u32, const SAMPLED: u32, + const COMPONENTS: u32, > HasQuerySizeLod for Image< SampledType, @@ -1447,15 +1617,17 @@ impl< { Multisampled::False as u32 }, SAMPLED, FORMAT, + COMPONENTS, > { } impl< - SampledType: SampleType, + SampledType: SampleType, const DEPTH: u32, const FORMAT: u32, const ARRAYED: u32, const SAMPLED: u32, + const COMPONENTS: u32, > HasQuerySizeLod for Image< SampledType, @@ -1465,6 +1637,7 @@ impl< { Multisampled::False as u32 }, SAMPLED, FORMAT, + COMPONENTS, > { } diff --git a/crates/spirv-std/src/image/params.rs b/crates/spirv-std/src/image/params.rs index 0989c15ac4..e64b9e2d93 100644 --- a/crates/spirv-std/src/image/params.rs +++ b/crates/spirv-std/src/image/params.rs @@ -1,9 +1,12 @@ use super::{Arrayed, Dimensionality, ImageFormat}; -use crate::{integer::Integer, scalar::Scalar, vector::Vector}; +use crate::{integer::Integer, scalar::Scalar, vector::Vector, vector::VectorTruncateInto}; /// Marker trait for arguments that accept single scalar values or vectors /// of scalars. Defines 2-, 3- and 4-component vector types based on the sample type. -pub trait SampleType: Scalar { +pub trait SampleType: Scalar { + /// The default vector/scalar of ths sample type + type SampleResult: Default; + /// A 2-component vector of this sample type type Vec2: Default; @@ -11,74 +14,134 @@ pub trait SampleType: Scalar { type Vec3: Default; /// A 4-component vector of this sample type - type Vec4: Default; + type Vec4: Default + VectorTruncateInto; } /// Helper macro to implement `SampleType` of various formats for various scalar types. macro_rules! sample_type_impls { - ($($fmt:ident : $s:ty => ($v2:ty, $v3:ty, $v4:ty)),+ $(,)?) => { + ($($fmt:ident : $n:tt*$s:ty => ($v1:ty, $v2:ty, $v3:ty, $v4:ty)),+ $(,)?) => { + $(sample_type_impls!{@single_rule, $fmt : $n*$s => ($v1,$v2,$v3,$v4)})+ + }; + (@single_rule, $fmt:ident : n*$s:ty => ($v1:ty, $v2:ty, $v3:ty, $v4:ty)) => { + impl SampleType<{ ImageFormat::$fmt as u32 }, 1> for $s { + type SampleResult = $v1; + type Vec2 = $v2; + type Vec3 = $v3; + type Vec4 = $v4; + } + impl SampleType<{ ImageFormat::$fmt as u32 }, 2> for $s { + type SampleResult = $v2; + type Vec2 = $v2; + type Vec3 = $v3; + type Vec4 = $v4; + } + impl SampleType<{ ImageFormat::$fmt as u32 }, 3> for $s { + type SampleResult = $v3; + type Vec2 = $v2; + type Vec3 = $v3; + type Vec4 = $v4; + } + impl SampleType<{ ImageFormat::$fmt as u32 }, 4> for $s { + type SampleResult = $v4; + type Vec2 = $v2; + type Vec3 = $v3; + type Vec4 = $v4; + } + }; + (@single_rule, $($fmt:ident : 1*$s:ty => ($v1:ty, $v2:ty, $v3:ty, $v4:ty)),+ $(,)?) => { $( - impl SampleType<{ ImageFormat::$fmt as u32 }> for $s { + impl SampleType<{ ImageFormat::$fmt as u32 }, 1> for $s { + type SampleResult = $v1; type Vec2 = $v2; type Vec3 = $v3; type Vec4 = $v4; } )+ - } + }; + (@single_rule, $($fmt:ident : 2*$s:ty => ($v1:ty, $v2:ty, $v3:ty, $v4:ty)),+ $(,)?) => { + $( + impl SampleType<{ ImageFormat::$fmt as u32 }, 2> for $s { + type SampleResult = $v2; + type Vec2 = $v2; + type Vec3 = $v3; + type Vec4 = $v4; + } + )+ + }; + (@single_rule, $($fmt:ident : 3*$s:ty => ($v1:ty, $v2:ty, $v3:ty, $v4:ty)),+ $(,)?) => { + $( + impl SampleType<{ ImageFormat::$fmt as u32 }, 3> for $s { + type SampleResult = $v3; + type Vec2 = $v2; + type Vec3 = $v3; + type Vec4 = $v4; + } + )+ + }; + (@single_rule, $($fmt:ident : 4*$s:ty => ($v1:ty, $v2:ty, $v3:ty, $v4:ty)),+ $(,)?) => { + $( + impl SampleType<{ ImageFormat::$fmt as u32 }, 4> for $s { + type SampleResult = $v4; + type Vec2 = $v2; + type Vec3 = $v3; + type Vec4 = $v4; + } + )+ + }; } sample_type_impls! { - Unknown: i8 => (glam::IVec2, glam::IVec3, glam::IVec4), - Unknown: i16 => (glam::IVec2, glam::IVec3, glam::IVec4), - Unknown: i32 => (glam::IVec2, glam::IVec3, glam::IVec4), - Unknown: i64 => (glam::IVec2, glam::IVec3, glam::IVec4), - Unknown: u8 => (glam::UVec2, glam::UVec3, glam::UVec4), - Unknown: u16 => (glam::UVec2, glam::UVec3, glam::UVec4), - Unknown: u32 => (glam::UVec2, glam::UVec3, glam::UVec4), - Unknown: u64 => (glam::UVec2, glam::UVec3, glam::UVec4), - Unknown: f32 => (glam::Vec2, glam::Vec3, glam::Vec4), - Unknown: f64 => (glam::DVec2, glam::DVec3, glam::DVec4), - Rgba32f: f32 => (glam::Vec2, glam::Vec3, glam::Vec4), - Rgba16f: f32 => (glam::Vec2, glam::Vec3, glam::Vec4), - R32f: f32 => (glam::Vec2, glam::Vec3, glam::Vec4), - Rgba8: f32 => (glam::Vec2, glam::Vec3, glam::Vec4), - Rgba8Snorm: f32 => (glam::Vec2, glam::Vec3, glam::Vec4), - Rg32f: f32 => (glam::Vec2, glam::Vec3, glam::Vec4), - Rg16f: f32 => (glam::Vec2, glam::Vec3, glam::Vec4), - R11fG11fB10f: f32 => (glam::Vec2, glam::Vec3, glam::Vec4), - R16f: f32 => (glam::Vec2, glam::Vec3, glam::Vec4), - Rgba16: f32 => (glam::Vec2, glam::Vec3, glam::Vec4), - Rgb10A2: f32 => (glam::Vec2, glam::Vec3, glam::Vec4), - Rg16: f32 => (glam::Vec2, glam::Vec3, glam::Vec4), - Rg8: f32 => (glam::Vec2, glam::Vec3, glam::Vec4), - R16: f32 => (glam::Vec2, glam::Vec3, glam::Vec4), - R8: f32 => (glam::Vec2, glam::Vec3, glam::Vec4), - Rgba16Snorm: f32 => (glam::Vec2, glam::Vec3, glam::Vec4), - Rg16Snorm: f32 => (glam::Vec2, glam::Vec3, glam::Vec4), - Rg8Snorm: f32 => (glam::Vec2, glam::Vec3, glam::Vec4), - R16Snorm: f32 => (glam::Vec2, glam::Vec3, glam::Vec4), - R8Snorm: f32 => (glam::Vec2, glam::Vec3, glam::Vec4), - Rgba32i: i32 => (glam::IVec2, glam::IVec3, glam::IVec4), - Rgba16i: i32 => (glam::IVec2, glam::IVec3, glam::IVec4), - Rgba8i: i32 => (glam::IVec2, glam::IVec3, glam::IVec4), - R32i: i32 => (glam::IVec2, glam::IVec3, glam::IVec4), - Rg32i: i32 => (glam::IVec2, glam::IVec3, glam::IVec4), - Rg16i: i32 => (glam::IVec2, glam::IVec3, glam::IVec4), - Rg8i: i32 => (glam::IVec2, glam::IVec3, glam::IVec4), - R16i: i32 => (glam::IVec2, glam::IVec3, glam::IVec4), - R8i: i32 => (glam::IVec2, glam::IVec3, glam::IVec4), - Rgba32ui: u32 => (glam::UVec2, glam::UVec3, glam::UVec4), - Rgba16ui: u32 => (glam::UVec2, glam::UVec3, glam::UVec4), - Rgba8ui: u32 => (glam::UVec2, glam::UVec3, glam::UVec4), - R32ui: u32 => (glam::UVec2, glam::UVec3, glam::UVec4), - Rgb10A2ui: u32 => (glam::UVec2, glam::UVec3, glam::UVec4), - Rg32ui: u32 => (glam::UVec2, glam::UVec3, glam::UVec4), - Rg16ui: u32 => (glam::UVec2, glam::UVec3, glam::UVec4), - Rg8ui: u32 => (glam::UVec2, glam::UVec3, glam::UVec4), - R16ui: u32 => (glam::UVec2, glam::UVec3, glam::UVec4), - R8ui: u32 => (glam::UVec2, glam::UVec3, glam::UVec4), - R64ui: u64 => (glam::UVec2, glam::UVec3, glam::UVec4), - R64i: i64 => (glam::IVec2, glam::IVec3, glam::IVec4), + Unknown: n*i8 => (i32, glam::IVec2, glam::IVec3, glam::IVec4), + Unknown: n*i16 => (i32, glam::IVec2, glam::IVec3, glam::IVec4), + Unknown: n*i32 => (i32, glam::IVec2, glam::IVec3, glam::IVec4), + Unknown: n*i64 => (i32, glam::IVec2, glam::IVec3, glam::IVec4), + Unknown: n*u8 => (u32, glam::UVec2, glam::UVec3, glam::UVec4), + Unknown: n*u16 => (u32, glam::UVec2, glam::UVec3, glam::UVec4), + Unknown: n*u32 => (u32, glam::UVec2, glam::UVec3, glam::UVec4), + Unknown: n*u64 => (u32, glam::UVec2, glam::UVec3, glam::UVec4), + Unknown: n*f32 => (f32, glam::Vec2, glam::Vec3, glam::Vec4), + Unknown: n*f64 => (f64, glam::DVec2, glam::DVec3, glam::DVec4), + Rgba32f: 4*f32 => (f32, glam::Vec2, glam::Vec3, glam::Vec4), + Rgba16f: 4*f32 => (f32, glam::Vec2, glam::Vec3, glam::Vec4), + R32f: 1*f32 => (f32, glam::Vec2, glam::Vec3, glam::Vec4), + Rgba8: 4*f32 => (f32, glam::Vec2, glam::Vec3, glam::Vec4), + Rgba8Snorm: 4*f32 => (f32, glam::Vec2, glam::Vec3, glam::Vec4), + Rg32f: 2*f32 => (f32, glam::Vec2, glam::Vec3, glam::Vec4), + Rg16f: 2*f32 => (f32, glam::Vec2, glam::Vec3, glam::Vec4), + R11fG11fB10f: 3*f32 => (f32, glam::Vec2, glam::Vec3, glam::Vec4), + R16f: 1*f32 => (f32, glam::Vec2, glam::Vec3, glam::Vec4), + Rgba16: 4*f32 => (f32, glam::Vec2, glam::Vec3, glam::Vec4), + Rgb10A2: 4*f32 => (f32, glam::Vec2, glam::Vec3, glam::Vec4), + Rg16: 2*f32 => (f32, glam::Vec2, glam::Vec3, glam::Vec4), + Rg8: 2*f32 => (f32, glam::Vec2, glam::Vec3, glam::Vec4), + R16: 1*f32 => (f32, glam::Vec2, glam::Vec3, glam::Vec4), + R8: 1*f32 => (f32, glam::Vec2, glam::Vec3, glam::Vec4), + Rgba16Snorm: 4*f32 => (f32, glam::Vec2, glam::Vec3, glam::Vec4), + Rg16Snorm: 2*f32 => (f32, glam::Vec2, glam::Vec3, glam::Vec4), + Rg8Snorm: 2*f32 => (f32, glam::Vec2, glam::Vec3, glam::Vec4), + R16Snorm: 1*f32 => (f32, glam::Vec2, glam::Vec3, glam::Vec4), + R8Snorm: 1*f32 => (f32, glam::Vec2, glam::Vec3, glam::Vec4), + Rgba32i: 4*i32 => (i32, glam::IVec2, glam::IVec3, glam::IVec4), + Rgba16i: 4*i32 => (i32, glam::IVec2, glam::IVec3, glam::IVec4), + Rgba8i: 4*i32 => (i32, glam::IVec2, glam::IVec3, glam::IVec4), + R32i: 1*i32 => (i32, glam::IVec2, glam::IVec3, glam::IVec4), + Rg32i: 2*i32 => (i32, glam::IVec2, glam::IVec3, glam::IVec4), + Rg16i: 2*i32 => (i32, glam::IVec2, glam::IVec3, glam::IVec4), + Rg8i: 2*i32 => (i32, glam::IVec2, glam::IVec3, glam::IVec4), + R16i: 1*i32 => (i32, glam::IVec2, glam::IVec3, glam::IVec4), + R8i: 1*i32 => (i32, glam::IVec2, glam::IVec3, glam::IVec4), + Rgba32ui: 4*u32 => (u32, glam::UVec2, glam::UVec3, glam::UVec4), + Rgba16ui: 4*u32 => (u32, glam::UVec2, glam::UVec3, glam::UVec4), + Rgba8ui: 4*u32 => (u32, glam::UVec2, glam::UVec3, glam::UVec4), + R32ui: 1*u32 => (u32, glam::UVec2, glam::UVec3, glam::UVec4), + Rgb10A2ui: 4*u32 => (u32, glam::UVec2, glam::UVec3, glam::UVec4), + Rg32ui: 2*u32 => (u32, glam::UVec2, glam::UVec3, glam::UVec4), + Rg16ui: 2*u32 => (u32, glam::UVec2, glam::UVec3, glam::UVec4), + Rg8ui: 2*u32 => (u32, glam::UVec2, glam::UVec3, glam::UVec4), + R16ui: 1*u32 => (u32, glam::UVec2, glam::UVec3, glam::UVec4), + R8ui: 1*u32 => (u32, glam::UVec2, glam::UVec3, glam::UVec4), + R64ui: 1*u64 => (u32, glam::UVec2, glam::UVec3, glam::UVec4), + R64i: 1*i64 => (i32, glam::IVec2, glam::IVec3, glam::IVec4), } /// Marker trait for arguments that accept a coordinate for an [`crate::Image`]. diff --git a/crates/spirv-std/src/vector.rs b/crates/spirv-std/src/vector.rs index 4377086a67..19cdb144b9 100644 --- a/crates/spirv-std/src/vector.rs +++ b/crates/spirv-std/src/vector.rs @@ -1,5 +1,7 @@ //! Traits related to vectors. +use glam::{Vec3Swizzles, Vec4Swizzles}; + /// Abstract trait representing a SPIR-V vector type. /// /// # Safety @@ -23,3 +25,42 @@ unsafe impl Vector for glam::UVec4 {} unsafe impl Vector for glam::IVec2 {} unsafe impl Vector for glam::IVec3 {} unsafe impl Vector for glam::IVec4 {} + +/// Trait that implements slicing of a vector into a scalar or vector of lower dimensions, by +/// ignoring the highter dimensions +pub trait VectorTruncateInto { + /// Slices the vector into a lower dimensional type by ignoring the higher components + fn truncate_into(self) -> T; +} + +macro_rules! vec_trunc_impl { + ($a:ty, $b:ty, $self:ident $(.$($e:tt)*)?) => { + impl VectorTruncateInto<$a> for $b { + fn truncate_into($self) -> $a { + $self $(. $($e)*)? + } + } + }; +} +macro_rules! vec_trunc_impls { + ($s:ty, $v2:ty, $v3:ty, $v4:ty) => { + vec_trunc_impl! {$s, $s, self} + vec_trunc_impl! {$s, $v2, self.x} + vec_trunc_impl! {$s, $v3, self.x} + vec_trunc_impl! {$s, $v4, self.x} + + vec_trunc_impl! {$v2, $v2, self} + vec_trunc_impl! {$v2, $v3, self.xy()} + vec_trunc_impl! {$v2, $v4, self.xy()} + + vec_trunc_impl! {$v3, $v3, self} + vec_trunc_impl! {$v3, $v4, self.xyz()} + + vec_trunc_impl! {$v4, $v4, self} + }; +} + +vec_trunc_impls! { f32, glam::Vec2, glam::Vec3, glam::Vec4 } +vec_trunc_impls! { f64, glam::DVec2, glam::DVec3, glam::DVec4 } +vec_trunc_impls! { i32, glam::IVec2, glam::IVec3, glam::IVec4 } +vec_trunc_impls! { u32, glam::UVec2, glam::UVec3, glam::UVec4 } diff --git a/tests/ui/image/components.rs b/tests/ui/image/components.rs new file mode 100644 index 0000000000..f63c7ea0c7 --- /dev/null +++ b/tests/ui/image/components.rs @@ -0,0 +1,30 @@ +// build-pass +// compile-flags: -Ctarget-feature=+StorageImageExtendedFormats + +use glam::{Vec2, Vec3, Vec4}; +use spirv_std::spirv; +use spirv_std::{arch, Image}; + +#[spirv(fragment)] +pub fn main( + #[spirv(descriptor_set = 0, binding = 0)] image1: &Image!(2D, type=f32, sampled, components=1), + #[spirv(descriptor_set = 0, binding = 1)] image2: &Image!(2D, type=f32, sampled, components=2), + #[spirv(descriptor_set = 0, binding = 2)] image3: &Image!(2D, type=f32, sampled, components=3), + #[spirv(descriptor_set = 0, binding = 3)] image4: &Image!(2D, type=f32, sampled), + #[spirv(descriptor_set = 0, binding = 4)] image2_implied: &Image!(2D, format = rg16f, sampled), + #[spirv(descriptor_set = 0, binding = 5)] image3_implied: &Image!( + 2D, + format = r11f_g11f_b10f, + sampled + ), + output: &mut glam::Vec4, +) { + let coords = glam::IVec2::new(0, 1); + let t1: f32 = image1.fetch(coords); + let t2: Vec2 = image2.fetch(coords); + let t3: Vec3 = image3.fetch(coords); + let t4: Vec4 = image4.fetch(coords); + let t5: Vec2 = image2_implied.fetch(coords); + let t6: Vec3 = image3_implied.fetch(coords); + *output = Vec4::splat(t1) + ((t2 + t5).extend(0.0) + t3 + t6).extend(0.0) + t4; +} diff --git a/tests/ui/image/gather_err.stderr b/tests/ui/image/gather_err.stderr index 0859eb76d8..b86b37eef5 100644 --- a/tests/ui/image/gather_err.stderr +++ b/tests/ui/image/gather_err.stderr @@ -1,34 +1,34 @@ -error[E0277]: the trait bound `Image: HasGather` is not satisfied +error[E0277]: the trait bound `Image: HasGather` is not satisfied --> $DIR/gather_err.rs:15:34 | 15 | let r1: glam::Vec4 = image1d.gather(*sampler, 0.0f32, 0); - | ^^^^^^ the trait `HasGather` is not implemented for `Image` + | ^^^^^^ the trait `HasGather` is not implemented for `Image` | = help: the following other types implement trait `HasGather`: - Image - Image - Image -note: required by a bound in `Image::::gather` - --> $SPIRV_STD_SRC/image.rs:167:15 + Image + Image + Image +note: required by a bound in `Image::::gather` + --> $SPIRV_STD_SRC/image.rs:198:15 | -167 | Self: HasGather, - | ^^^^^^^^^ required by this bound in `Image::::gather` +198 | Self: HasGather, + | ^^^^^^^^^ required by this bound in `Image::::gather` -error[E0277]: the trait bound `Image: HasGather` is not satisfied +error[E0277]: the trait bound `Image: HasGather` is not satisfied --> $DIR/gather_err.rs:16:34 | 16 | let r2: glam::Vec4 = image3d.gather(*sampler, v3, 0); - | ^^^^^^ the trait `HasGather` is not implemented for `Image` + | ^^^^^^ the trait `HasGather` is not implemented for `Image` | = help: the following other types implement trait `HasGather`: - Image - Image - Image -note: required by a bound in `Image::::gather` - --> $SPIRV_STD_SRC/image.rs:167:15 + Image + Image + Image +note: required by a bound in `Image::::gather` + --> $SPIRV_STD_SRC/image.rs:198:15 | -167 | Self: HasGather, - | ^^^^^^^^^ required by this bound in `Image::::gather` +198 | Self: HasGather, + | ^^^^^^^^^ required by this bound in `Image::::gather` error: aborting due to 2 previous errors diff --git a/tests/ui/image/implicit_not_in_fragment.stderr b/tests/ui/image/implicit_not_in_fragment.stderr index aeb5476f1f..e799fee473 100644 --- a/tests/ui/image/implicit_not_in_fragment.stderr +++ b/tests/ui/image/implicit_not_in_fragment.stderr @@ -1,7 +1,7 @@ error: ImageSampleImplicitLod cannot be used outside a fragment shader | = note: Stack: - >::sample:: + >::sample:: implicit_not_in_fragment::deeper_stack implicit_not_in_fragment::deep_stack implicit_not_in_fragment::main @@ -10,7 +10,7 @@ error: ImageSampleImplicitLod cannot be used outside a fragment shader error: ImageSampleImplicitLod cannot be used outside a fragment shader | = note: Stack: - >::sample:: + >::sample:: implicit_not_in_fragment::main main diff --git a/tests/ui/image/query/query_levels_err.stderr b/tests/ui/image/query/query_levels_err.stderr index 7309e4c789..629594f07b 100644 --- a/tests/ui/image/query/query_levels_err.stderr +++ b/tests/ui/image/query/query_levels_err.stderr @@ -1,19 +1,19 @@ -error[E0277]: the trait bound `Image: HasQueryLevels` is not satisfied +error[E0277]: the trait bound `Image: HasQueryLevels` is not satisfied --> $DIR/query_levels_err.rs:12:21 | 12 | *output = image.query_levels(); - | ^^^^^^^^^^^^ the trait `HasQueryLevels` is not implemented for `Image` + | ^^^^^^^^^^^^ the trait `HasQueryLevels` is not implemented for `Image` | = help: the following other types implement trait `HasQueryLevels`: - Image - Image - Image - Image -note: required by a bound in `Image::::query_levels` - --> $SPIRV_STD_SRC/image.rs:817:15 + Image + Image + Image + Image +note: required by a bound in `Image::::query_levels` + --> $SPIRV_STD_SRC/image.rs:882:15 | -817 | Self: HasQueryLevels, - | ^^^^^^^^^^^^^^ required by this bound in `Image::::query_levels` +882 | Self: HasQueryLevels, + | ^^^^^^^^^^^^^^ required by this bound in `Image::::query_levels` error: aborting due to previous error diff --git a/tests/ui/image/query/query_lod_err.stderr b/tests/ui/image/query/query_lod_err.stderr index 2bb3f58573..32ca0fa1ad 100644 --- a/tests/ui/image/query/query_lod_err.stderr +++ b/tests/ui/image/query/query_lod_err.stderr @@ -1,19 +1,19 @@ -error[E0277]: the trait bound `Image: HasQueryLevels` is not satisfied +error[E0277]: the trait bound `Image: HasQueryLevels` is not satisfied --> $DIR/query_lod_err.rs:13:21 | 13 | *output = image.query_lod(*sampler, glam::Vec2::new(0.0, 1.0)); - | ^^^^^^^^^ the trait `HasQueryLevels` is not implemented for `Image` + | ^^^^^^^^^ the trait `HasQueryLevels` is not implemented for `Image` | = help: the following other types implement trait `HasQueryLevels`: - Image - Image - Image - Image -note: required by a bound in `Image::::query_lod` - --> $SPIRV_STD_SRC/image.rs:843:15 + Image + Image + Image + Image +note: required by a bound in `Image::::query_lod` + --> $SPIRV_STD_SRC/image.rs:908:15 | -843 | Self: HasQueryLevels, - | ^^^^^^^^^^^^^^ required by this bound in `Image::::query_lod` +908 | Self: HasQueryLevels, + | ^^^^^^^^^^^^^^ required by this bound in `Image::::query_lod` error: aborting due to previous error diff --git a/tests/ui/image/query/query_size_err.stderr b/tests/ui/image/query/query_size_err.stderr index 0e56d8efaf..7d730341cd 100644 --- a/tests/ui/image/query/query_size_err.stderr +++ b/tests/ui/image/query/query_size_err.stderr @@ -1,24 +1,24 @@ -error[E0277]: the trait bound `Image: HasQuerySize` is not satisfied +error[E0277]: the trait bound `Image: HasQuerySize` is not satisfied --> $DIR/query_size_err.rs:12:21 | 12 | *output = image.query_size(); - | ^^^^^^^^^^ the trait `HasQuerySize` is not implemented for `Image` + | ^^^^^^^^^^ the trait `HasQuerySize` is not implemented for `Image` | = help: the following other types implement trait `HasQuerySize`: - Image - Image - Image - Image - Image - Image - Image - Image + Image + Image + Image + Image + Image + Image + Image + Image and 6 others -note: required by a bound in `Image::::query_size` - --> $SPIRV_STD_SRC/image.rs:874:15 +note: required by a bound in `Image::::query_size` + --> $SPIRV_STD_SRC/image.rs:939:15 | -874 | Self: HasQuerySize, - | ^^^^^^^^^^^^ required by this bound in `Image::::query_size` +939 | Self: HasQuerySize, + | ^^^^^^^^^^^^ required by this bound in `Image::::query_size` error: aborting due to previous error diff --git a/tests/ui/image/query/query_size_lod_err.stderr b/tests/ui/image/query/query_size_lod_err.stderr index 490eab595f..a2db4397ed 100644 --- a/tests/ui/image/query/query_size_lod_err.stderr +++ b/tests/ui/image/query/query_size_lod_err.stderr @@ -1,19 +1,19 @@ -error[E0277]: the trait bound `Image: HasQuerySizeLod` is not satisfied +error[E0277]: the trait bound `Image: HasQuerySizeLod` is not satisfied --> $DIR/query_size_lod_err.rs:12:21 | 12 | *output = image.query_size_lod(0); - | ^^^^^^^^^^^^^^ the trait `HasQuerySizeLod` is not implemented for `Image` + | ^^^^^^^^^^^^^^ the trait `HasQuerySizeLod` is not implemented for `Image` | = help: the following other types implement trait `HasQuerySizeLod`: - Image - Image - Image - Image -note: required by a bound in `Image::::query_size_lod` - --> $SPIRV_STD_SRC/image.rs:907:15 + Image + Image + Image + Image +note: required by a bound in `Image::::query_size_lod` + --> $SPIRV_STD_SRC/image.rs:983:15 | -907 | Self: HasQuerySizeLod, - | ^^^^^^^^^^^^^^^ required by this bound in `Image::::query_size_lod` +983 | Self: HasQuerySizeLod, + | ^^^^^^^^^^^^^^^ required by this bound in `Image::::query_size_lod` error: aborting due to previous error diff --git a/tests/ui/spirv-attr/bad-deduce-storage-class.stderr b/tests/ui/spirv-attr/bad-deduce-storage-class.stderr index 1986c69429..55643c7604 100644 --- a/tests/ui/spirv-attr/bad-deduce-storage-class.stderr +++ b/tests/ui/spirv-attr/bad-deduce-storage-class.stderr @@ -19,7 +19,7 @@ warning: redundant storage class attribute, storage class is deduced from type 9 | #[spirv(uniform_constant)] warning: &Image!(2D, type=f32), | ^^^^^^^^^^^^^^^^ -error: entry parameter type must be by-reference: `&spirv_std::image::Image` +error: entry parameter type must be by-reference: `&spirv_std::image::Image` --> $DIR/bad-deduce-storage-class.rs:15:27 | 15 | pub fn issue_585(invalid: Image!(2D, type=f32)) {}