diff --git a/crates/rustc_codegen_spirv/src/abi.rs b/crates/rustc_codegen_spirv/src/abi.rs index fbe20ed462..e15da55a45 100644 --- a/crates/rustc_codegen_spirv/src/abi.rs +++ b/crates/rustc_codegen_spirv/src/abi.rs @@ -877,6 +877,7 @@ fn trans_intrinsic_type<'tcx>( let multisampled = const_int_value(cx, args.const_at(4))?; let sampled = const_int_value(cx, args.const_at(5))?; let image_format = const_int_value(cx, args.const_at(6))?; + let access_qualifier = const_int_value(cx, args.const_at(7))?; let ty = SpirvType::Image { sampled_type, @@ -886,6 +887,7 @@ fn trans_intrinsic_type<'tcx>( multisampled, sampled, image_format, + access_qualifier, }; Ok(ty.def(span, cx)) } diff --git a/crates/rustc_codegen_spirv/src/builder/spirv_asm.rs b/crates/rustc_codegen_spirv/src/builder/spirv_asm.rs index 97c4d9cfa1..3522d1395a 100644 --- a/crates/rustc_codegen_spirv/src/builder/spirv_asm.rs +++ b/crates/rustc_codegen_spirv/src/builder/spirv_asm.rs @@ -327,6 +327,7 @@ impl<'cx, 'tcx> Builder<'cx, 'tcx> { multisampled: inst.operands[4].unwrap_literal_int32(), sampled: inst.operands[5].unwrap_literal_int32(), image_format: inst.operands[6].unwrap_image_format(), + access_qualifier: inst.operands[7].unwrap_access_qualifier() } .def(self.span(), self), Op::TypeSampledImage => SpirvType::SampledImage { diff --git a/crates/rustc_codegen_spirv/src/spirv_type.rs b/crates/rustc_codegen_spirv/src/spirv_type.rs index 73cfdc662f..17d108f6d2 100644 --- a/crates/rustc_codegen_spirv/src/spirv_type.rs +++ b/crates/rustc_codegen_spirv/src/spirv_type.rs @@ -3,7 +3,7 @@ use crate::builder_spirv::SpirvValue; use crate::codegen_cx::CodegenCx; use indexmap::IndexSet; use rspirv::dr::Operand; -use rspirv::spirv::{Capability, Decoration, Dim, ImageFormat, StorageClass, Word}; +use rspirv::spirv::{Capability, Decoration, Dim, ImageFormat, StorageClass, Word, AccessQualifier}; use rustc_data_structures::fx::FxHashMap; use rustc_middle::span_bug; use rustc_span::def_id::DefId; @@ -74,6 +74,7 @@ pub enum SpirvType<'tcx> { multisampled: u32, sampled: u32, image_format: ImageFormat, + access_qualifier: AccessQualifier, }, Sampler, SampledImage { @@ -236,6 +237,7 @@ impl SpirvType<'_> { multisampled, sampled, image_format, + access_qualifier, } => cx.emit_global().type_image_id( id, sampled_type, @@ -245,7 +247,7 @@ impl SpirvType<'_> { multisampled, sampled, image_format, - None, + Some(access_qualifier) ), Self::Sampler => cx.emit_global().type_sampler_id(id), Self::AccelerationStructureKhr => { @@ -413,6 +415,7 @@ impl SpirvType<'_> { multisampled, sampled, image_format, + access_qualifier } => SpirvType::Image { sampled_type, dim, @@ -421,6 +424,7 @@ impl SpirvType<'_> { multisampled, sampled, image_format, + access_qualifier, }, SpirvType::Sampler => SpirvType::Sampler, SpirvType::SampledImage { image_type } => SpirvType::SampledImage { image_type }, @@ -576,6 +580,7 @@ impl fmt::Debug for SpirvTypePrinter<'_, '_> { multisampled, sampled, image_format, + access_qualifier, } => f .debug_struct("Image") .field("id", &self.id) @@ -586,6 +591,7 @@ impl fmt::Debug for SpirvTypePrinter<'_, '_> { .field("multisampled", &multisampled) .field("sampled", &sampled) .field("image_format", &image_format) + .field("access_qualifier", &access_qualifier) .finish(), SpirvType::Sampler => f.debug_struct("Sampler").field("id", &self.id).finish(), SpirvType::SampledImage { image_type } => f @@ -731,6 +737,7 @@ impl SpirvTypePrinter<'_, '_> { multisampled, sampled, image_format, + access_qualifier } => f .debug_struct("Image") .field("sampled_type", &self.cx.debug_type(sampled_type)) @@ -740,6 +747,7 @@ impl SpirvTypePrinter<'_, '_> { .field("multisampled", &multisampled) .field("sampled", &sampled) .field("image_format", &image_format) + .field("access_qualifier", &access_qualifier) .finish(), SpirvType::Sampler => f.write_str("Sampler"), SpirvType::SampledImage { image_type } => f diff --git a/crates/spirv-std/macros/src/image.rs b/crates/spirv-std/macros/src/image.rs index b6566e78d4..bcceaef7c8 100644 --- a/crates/spirv-std/macros/src/image.rs +++ b/crates/spirv-std/macros/src/image.rs @@ -34,6 +34,7 @@ pub struct ImageType { sampled: Sampled, sampled_type: SampledType, components: u32, + access_qualifier: AccessQualifier, } impl Parse for ImageType { @@ -47,6 +48,7 @@ impl Parse for ImageType { let mut sampled: Option = None; let mut crate_root = None; let mut components = None; + let mut access_qualifier = None; let starting_span = input.span(); @@ -160,6 +162,22 @@ impl Parse for ImageType { )), } ); + } else if ident == "access" { + let value = peek_and_eat_value!(syn::Ident); + + if value.is_none() { + return Err(syn::Error::new( + ident.span(), + "Expected argument for `access`.", + )); + } + let value = params::access_qualifier_from_str(&value.unwrap().to_string()); + + if let Err(err) = value { + return Err(syn::Error::new(ident.span(), err)); + } + + access_qualifier = value.ok(); } else if ident == "__crate_root" { input.parse::()?; crate_root = Some(input.parse::()?); @@ -366,6 +384,7 @@ impl Parse for ImageType { let multisampled = multisampled.unwrap_or(Multisampled::False); let sampled = sampled.unwrap_or(Sampled::Unknown); let components = components.unwrap_or(4); + let access_qualifier = access_qualifier.unwrap_or(AccessQualifier::ReadOnly); Ok(Self { arrayed, @@ -377,6 +396,7 @@ impl Parse for ImageType { sampled, sampled_type, components, + access_qualifier, }) } } @@ -400,6 +420,7 @@ impl quote::ToTokens for ImageType { let sampled = params::sampled_to_tokens(&self.sampled); let sampled_type = &self.sampled_type; let components = self.components; + let access_qualifier = params::access_qualifier_to_tokens(&self.access_qualifier); tokens.append_all(quote::quote! { #crate_root::image::Image< @@ -410,6 +431,7 @@ impl quote::ToTokens for ImageType { { #crate_root::image::#multisampled as u32 }, { #crate_root::image::#sampled as u32 }, { #crate_root::image::#format as u32 }, + { #crate_root::image::#access_qualifier as u32 }, { #components as u32 }, > }); @@ -471,6 +493,19 @@ mod params { }) } + pub fn access_qualifier_from_str(s: &str) -> Result { + Ok(match s { + "readonly" => AccessQualifier::ReadOnly, + "writeonly" => AccessQualifier::WriteOnly, + "readwrite" => AccessQualifier::ReadWrite, + _ => { + return Err( + "Unknown specified access qualifier. Use `access=` instead if this is intentional.", + ); + } + }) + } + /// The sampled type of an unknown image format. pub enum SampledType { U8, @@ -598,4 +633,12 @@ mod params { quote!(ImageFormat::#variant) } + + pub fn access_qualifier_to_tokens(access: &AccessQualifier) -> proc_macro2::TokenStream { + match access { + AccessQualifier::ReadOnly => quote!(AccessQualifier::ReadOnly), + AccessQualifier::WriteOnly => quote!(AccessQualifier::WriteOnly), + AccessQualifier::ReadWrite => quote!(AccessQualifier::ReadWrite), + } + } } diff --git a/crates/spirv-std/src/image.rs b/crates/spirv-std/src/image.rs index 0a9924dbd9..1b4db98dd7 100644 --- a/crates/spirv-std/src/image.rs +++ b/crates/spirv-std/src/image.rs @@ -108,6 +108,7 @@ pub struct Image< const MULTISAMPLED: u32, // Multisampled, const SAMPLED: u32, // Sampled, const FORMAT: u32, // ImageFormat, + const ACCESS: u32, // AccessQualifier const COMPONENTS: u32, // NumberOfComponents, > { // HACK(eddyb) avoids the layout becoming ZST (and being elided in one way @@ -123,6 +124,7 @@ impl< const ARRAYED: u32, const MULTISAMPLED: u32, const FORMAT: u32, + const ACCESS: u32, const COMPONENTS: u32, > Image< @@ -133,6 +135,7 @@ impl< MULTISAMPLED, { Sampled::Yes as u32 }, FORMAT, + ACCESS, COMPONENTS, > { @@ -169,6 +172,7 @@ impl< const FORMAT: u32, const ARRAYED: u32, const SAMPLED: u32, + const ACCESS: u32, const COMPONENTS: u32, > Image< @@ -179,6 +183,7 @@ impl< { Multisampled::False as u32 }, SAMPLED, FORMAT, + ACCESS, COMPONENTS, > { @@ -460,6 +465,7 @@ impl< const DEPTH: u32, const SAMPLED: u32, const FORMAT: u32, + const ACCESS: u32, const COMPONENTS: u32, > Image< @@ -470,6 +476,7 @@ impl< { Multisampled::False as u32 }, SAMPLED, FORMAT, + ACCESS, COMPONENTS, > { @@ -683,6 +690,7 @@ impl< const ARRAYED: u32, const MULTISAMPLED: u32, const FORMAT: u32, + const ACCESS: u32, const COMPONENTS: u32, > Image< @@ -693,6 +701,7 @@ impl< MULTISAMPLED, { Sampled::No as u32 }, FORMAT, + ACCESS, COMPONENTS, > { @@ -752,6 +761,7 @@ impl< const FORMAT: u32, const ARRAYED: u32, const MULTISAMPLED: u32, + const ACCESS: u32, const COMPONENTS: u32, > Image< @@ -762,6 +772,7 @@ impl< MULTISAMPLED, { Sampled::Unknown as u32 }, FORMAT, + ACCESS, COMPONENTS, > { @@ -821,6 +832,7 @@ impl< const MULTISAMPLED: u32, const FORMAT: u32, const COMPONENTS: u32, + const ACCESS: u32, > Image< SampledType, @@ -830,6 +842,7 @@ impl< MULTISAMPLED, { Sampled::No as u32 }, FORMAT, + ACCESS, COMPONENTS, > { @@ -870,8 +883,9 @@ impl< const MULTISAMPLED: u32, const SAMPLED: u32, const FORMAT: u32, + const ACCESS: u32, const COMPONENTS: u32, -> Image +> Image { /// Query the number of mipmap levels. #[crate::macros::gpu_only] @@ -958,6 +972,7 @@ impl< const ARRAYED: u32, const SAMPLED: u32, const FORMAT: u32, + const ACCESS: u32, const COMPONENTS: u32, > Image< @@ -968,6 +983,7 @@ impl< { Multisampled::False as u32 }, SAMPLED, FORMAT, + ACCESS, COMPONENTS, > { @@ -1002,6 +1018,7 @@ impl< const ARRAYED: u32, const SAMPLED: u32, const FORMAT: u32, + const ACCESS: u32, const COMPONENTS: u32, > Image< @@ -1012,6 +1029,7 @@ impl< { Multisampled::True as u32 }, SAMPLED, FORMAT, + ACCESS, COMPONENTS, > { @@ -1050,6 +1068,7 @@ impl< const ARRAYED: u32, const SAMPLED: u32, const FORMAT: u32, + const ACCESS: u32, const COMPONENTS: u32, > SampledImage< @@ -1061,6 +1080,7 @@ impl< { Multisampled::False as u32 }, SAMPLED, FORMAT, + ACCESS, COMPONENTS, >, > @@ -1209,6 +1229,7 @@ impl< const MULTISAMPLED: u32, const SAMPLED: u32, const FORMAT: u32, + const ACCESS: u32, const COMPONENTS: u32, > ImageWithMethods< @@ -1221,7 +1242,7 @@ impl< FORMAT, COMPONENTS, SampleParams, - > for Image + > for Image { #[crate::macros::gpu_only] #[doc(alias = "OpImageFetch")] @@ -1422,6 +1443,7 @@ impl< const FORMAT: u32, const ARRAYED: u32, const SAMPLED: u32, + const ACCESS: u32, const COMPONENTS: u32, > HasGather for Image< @@ -1432,6 +1454,7 @@ impl< { Multisampled::False as u32 }, SAMPLED, FORMAT, + ACCESS, COMPONENTS, > { @@ -1442,6 +1465,7 @@ impl< const FORMAT: u32, const ARRAYED: u32, const SAMPLED: u32, + const ACCESS: u32, const COMPONENTS: u32, > HasGather for Image< @@ -1452,6 +1476,7 @@ impl< { Multisampled::False as u32 }, SAMPLED, FORMAT, + ACCESS, COMPONENTS, > { @@ -1462,6 +1487,7 @@ impl< const FORMAT: u32, const ARRAYED: u32, const SAMPLED: u32, + const ACCESS: u32, const COMPONENTS: u32, > HasGather for Image< @@ -1472,6 +1498,7 @@ impl< { Multisampled::False as u32 }, SAMPLED, FORMAT, + ACCESS, COMPONENTS, > { @@ -1489,6 +1516,7 @@ impl< const ARRAYED: u32, const MULTISAMPLED: u32, const SAMPLED: u32, + const ACCESS: u32, const COMPONENTS: u32, > HasQueryLevels for Image< @@ -1499,6 +1527,7 @@ impl< MULTISAMPLED, SAMPLED, FORMAT, + ACCESS, COMPONENTS, > { @@ -1510,6 +1539,7 @@ impl< const ARRAYED: u32, const MULTISAMPLED: u32, const SAMPLED: u32, + const ACCESS: u32, const COMPONENTS: u32, > HasQueryLevels for Image< @@ -1520,6 +1550,7 @@ impl< MULTISAMPLED, SAMPLED, FORMAT, + ACCESS, COMPONENTS, > { @@ -1531,6 +1562,7 @@ impl< const ARRAYED: u32, const MULTISAMPLED: u32, const SAMPLED: u32, + const ACCESS: u32, const COMPONENTS: u32, > HasQueryLevels for Image< @@ -1541,6 +1573,7 @@ impl< MULTISAMPLED, SAMPLED, FORMAT, + ACCESS, COMPONENTS, > { @@ -1552,6 +1585,7 @@ impl< const ARRAYED: u32, const MULTISAMPLED: u32, const SAMPLED: u32, + const ACCESS: u32, const COMPONENTS: u32, > HasQueryLevels for Image< @@ -1562,6 +1596,7 @@ impl< MULTISAMPLED, SAMPLED, FORMAT, + ACCESS, COMPONENTS, > { @@ -1579,6 +1614,7 @@ impl< const FORMAT: u32, const ARRAYED: u32, const SAMPLED: u32, + const ACCESS: u32, const COMPONENTS: u32, > HasQuerySize for Image< @@ -1589,6 +1625,7 @@ impl< { Multisampled::True as u32 }, SAMPLED, FORMAT, + ACCESS, COMPONENTS, > { @@ -1598,6 +1635,7 @@ impl< const DEPTH: u32, const FORMAT: u32, const ARRAYED: u32, + const ACCESS: u32, const COMPONENTS: u32, > HasQuerySize for Image< @@ -1608,6 +1646,7 @@ impl< { Multisampled::False as u32 }, { Sampled::Unknown as u32 }, FORMAT, + ACCESS, COMPONENTS, > { @@ -1617,6 +1656,7 @@ impl< const DEPTH: u32, const FORMAT: u32, const ARRAYED: u32, + const ACCESS: u32, const COMPONENTS: u32, > HasQuerySize for Image< @@ -1627,6 +1667,7 @@ impl< { Multisampled::False as u32 }, { Sampled::No as u32 }, FORMAT, + ACCESS, COMPONENTS, > { @@ -1637,6 +1678,7 @@ impl< const FORMAT: u32, const ARRAYED: u32, const SAMPLED: u32, + const ACCESS: u32, const COMPONENTS: u32, > HasQuerySize for Image< @@ -1647,6 +1689,7 @@ impl< { Multisampled::True as u32 }, SAMPLED, FORMAT, + ACCESS, COMPONENTS, > { @@ -1656,6 +1699,7 @@ impl< const DEPTH: u32, const FORMAT: u32, const ARRAYED: u32, + const ACCESS: u32, const COMPONENTS: u32, > HasQuerySize for Image< @@ -1666,6 +1710,7 @@ impl< { Multisampled::False as u32 }, { Sampled::Unknown as u32 }, FORMAT, + ACCESS, COMPONENTS, > { @@ -1675,6 +1720,7 @@ impl< const DEPTH: u32, const FORMAT: u32, const ARRAYED: u32, + const ACCESS: u32, const COMPONENTS: u32, > HasQuerySize for Image< @@ -1685,6 +1731,7 @@ impl< { Multisampled::False as u32 }, { Sampled::No as u32 }, FORMAT, + ACCESS, COMPONENTS, > { @@ -1695,6 +1742,7 @@ impl< const FORMAT: u32, const ARRAYED: u32, const SAMPLED: u32, + const ACCESS: u32, const COMPONENTS: u32, > HasQuerySize for Image< @@ -1705,6 +1753,7 @@ impl< { Multisampled::True as u32 }, SAMPLED, FORMAT, + ACCESS, COMPONENTS, > { @@ -1714,6 +1763,7 @@ impl< const DEPTH: u32, const FORMAT: u32, const ARRAYED: u32, + const ACCESS: u32, const COMPONENTS: u32, > HasQuerySize for Image< @@ -1724,6 +1774,7 @@ impl< { Multisampled::False as u32 }, { Sampled::Unknown as u32 }, FORMAT, + ACCESS, COMPONENTS, > { @@ -1733,6 +1784,7 @@ impl< const DEPTH: u32, const FORMAT: u32, const ARRAYED: u32, + const ACCESS: u32, const COMPONENTS: u32, > HasQuerySize for Image< @@ -1743,6 +1795,7 @@ impl< { Multisampled::False as u32 }, { Sampled::No as u32 }, FORMAT, + ACCESS, COMPONENTS, > { @@ -1753,6 +1806,7 @@ impl< const FORMAT: u32, const ARRAYED: u32, const SAMPLED: u32, + const ACCESS: u32, const COMPONENTS: u32, > HasQuerySize for Image< @@ -1763,6 +1817,7 @@ impl< { Multisampled::True as u32 }, SAMPLED, FORMAT, + ACCESS, COMPONENTS, > { @@ -1772,6 +1827,7 @@ impl< const DEPTH: u32, const FORMAT: u32, const ARRAYED: u32, + const ACCESS: u32, const COMPONENTS: u32, > HasQuerySize for Image< @@ -1782,6 +1838,7 @@ impl< { Multisampled::False as u32 }, { Sampled::Unknown as u32 }, FORMAT, + ACCESS, COMPONENTS, > { @@ -1791,6 +1848,7 @@ impl< const DEPTH: u32, const FORMAT: u32, const ARRAYED: u32, + const ACCESS: u32, const COMPONENTS: u32, > HasQuerySize for Image< @@ -1801,6 +1859,7 @@ impl< { Multisampled::False as u32 }, { Sampled::No as u32 }, FORMAT, + ACCESS, COMPONENTS, > { @@ -1812,6 +1871,7 @@ impl< const ARRAYED: u32, const MULTISAMPLED: u32, const SAMPLED: u32, + const ACCESS: u32, const COMPONENTS: u32, > HasQuerySize for Image< @@ -1822,6 +1882,7 @@ impl< MULTISAMPLED, SAMPLED, FORMAT, + ACCESS, COMPONENTS, > { @@ -1833,6 +1894,7 @@ impl< const ARRAYED: u32, const MULTISAMPLED: u32, const SAMPLED: u32, + const ACCESS: u32, const COMPONENTS: u32, > HasQuerySize for Image< @@ -1843,6 +1905,7 @@ impl< MULTISAMPLED, SAMPLED, FORMAT, + ACCESS, COMPONENTS, > { @@ -1859,6 +1922,7 @@ impl< const FORMAT: u32, const ARRAYED: u32, const SAMPLED: u32, + const ACCESS: u32, const COMPONENTS: u32, > HasQuerySizeLod for Image< @@ -1869,6 +1933,7 @@ impl< { Multisampled::False as u32 }, SAMPLED, FORMAT, + ACCESS, COMPONENTS, > { @@ -1879,6 +1944,7 @@ impl< const FORMAT: u32, const ARRAYED: u32, const SAMPLED: u32, + const ACCESS: u32, const COMPONENTS: u32, > HasQuerySizeLod for Image< @@ -1889,6 +1955,7 @@ impl< { Multisampled::False as u32 }, SAMPLED, FORMAT, + ACCESS, COMPONENTS, > { @@ -1899,6 +1966,7 @@ impl< const FORMAT: u32, const ARRAYED: u32, const SAMPLED: u32, + const ACCESS: u32, const COMPONENTS: u32, > HasQuerySizeLod for Image< @@ -1909,6 +1977,7 @@ impl< { Multisampled::False as u32 }, SAMPLED, FORMAT, + ACCESS, COMPONENTS, > { @@ -1919,6 +1988,7 @@ impl< const FORMAT: u32, const ARRAYED: u32, const SAMPLED: u32, + const ACCESS: u32, const COMPONENTS: u32, > HasQuerySizeLod for Image< @@ -1929,6 +1999,7 @@ impl< { Multisampled::False as u32 }, SAMPLED, FORMAT, + ACCESS, COMPONENTS, > {