From 905e6dbefdcc61e7825ed40161f55bbcf89a1f97 Mon Sep 17 00:00:00 2001 From: dav Date: Mon, 11 Nov 2024 16:08:35 -0800 Subject: [PATCH] Fix Issue 4857 Case One --- naga/src/back/mod.rs | 1 + naga/src/front/spv/image.rs | 9 ++++++++ naga/src/lib.rs | 4 ---- naga/src/proc/typifier.rs | 42 ++++++++++++++++++++---------------- naga/src/valid/analyzer.rs | 1 + naga/src/valid/expression.rs | 9 ++++++++ naga/src/valid/type.rs | 6 ++++-- 7 files changed, 47 insertions(+), 25 deletions(-) diff --git a/naga/src/back/mod.rs b/naga/src/back/mod.rs index 58c7fa02c..736d840cc 100644 --- a/naga/src/back/mod.rs +++ b/naga/src/back/mod.rs @@ -264,6 +264,7 @@ impl crate::TypeInner { crate::TypeInner::Image { .. } | crate::TypeInner::Sampler { .. } | crate::TypeInner::AccelerationStructure { .. } => true, + crate::TypeInner::BindingArray { .. } => true, _ => false, } } diff --git a/naga/src/front/spv/image.rs b/naga/src/front/spv/image.rs index 71ba79e1e..4630a7b9a 100644 --- a/naga/src/front/spv/image.rs +++ b/naga/src/front/spv/image.rs @@ -592,6 +592,12 @@ impl> super::Frontend { } } + crate::Expression::FunctionArgument(i) => { + match ctx.type_arena[ctx.arguments[i as usize].ty].inner { + crate::TypeInner::BindingArray { base, .. } => base, + _ => return Err(Error::InvalidGlobalVar(ctx.expressions[base].clone())), + } + } ref other => return Err(Error::InvalidGlobalVar(other.clone())), }, @@ -611,6 +617,9 @@ impl> super::Frontend { crate::Expression::GlobalVariable(handle) => { *self.handle_sampling.get_mut(&handle).unwrap() |= sampling_bit; } + crate::Expression::FunctionArgument(i) => { + ctx.parameter_sampling[i as usize] |= sampling_bit; + } ref other => return Err(Error::InvalidGlobalVar(other.clone())), }, diff --git a/naga/src/lib.rs b/naga/src/lib.rs index 912ca4f42..fcc084653 100644 --- a/naga/src/lib.rs +++ b/naga/src/lib.rs @@ -844,9 +844,6 @@ pub enum TypeInner { /// a binding array of samplers yields a [`Sampler`], indexing a pointer to the /// binding array of storage buffers produces a pointer to the storage struct. /// - /// Unlike textures and samplers, binding arrays are not [`ARGUMENT`], so - /// they cannot be passed as arguments to functions. - /// /// Naga's WGSL front end supports binding arrays with the type syntax /// `binding_array`. /// @@ -858,7 +855,6 @@ pub enum TypeInner { /// [`SamplerArray`]: https://docs.rs/wgpu/latest/wgpu/enum.BindingResource.html#variant.SamplerArray /// [`BufferArray`]: https://docs.rs/wgpu/latest/wgpu/enum.BindingResource.html#variant.BufferArray /// [`DATA`]: crate::valid::TypeFlags::DATA - /// [`ARGUMENT`]: crate::valid::TypeFlags::ARGUMENT /// [naga#1864]: https://github.com/gfx-rs/naga/issues/1864 BindingArray { base: Handle, size: ArraySize }, } diff --git a/naga/src/proc/typifier.rs b/naga/src/proc/typifier.rs index a94546fbc..068588c53 100644 --- a/naga/src/proc/typifier.rs +++ b/naga/src/proc/typifier.rs @@ -444,27 +444,31 @@ impl<'a> ResolveContext<'a> { space: crate::AddressSpace::Function, }) } - crate::Expression::Load { pointer } => match *past(pointer)?.inner_with(types) { - Ti::Pointer { base, space: _ } => { - if let Ti::Atomic(scalar) = types[base].inner { - TypeResolution::Value(Ti::Scalar(scalar)) - } else { - TypeResolution::Handle(base) + crate::Expression::Load { pointer } => { + let past_pointer = past(pointer)?; + match *past_pointer.inner_with(types) { + Ti::Pointer { base, space: _ } => { + if let Ti::Atomic(scalar) = types[base].inner { + TypeResolution::Value(Ti::Scalar(scalar)) + } else { + TypeResolution::Handle(base) + } + } + Ti::ValuePointer { + size, + scalar, + space: _, + } => TypeResolution::Value(match size { + Some(size) => Ti::Vector { size, scalar }, + None => Ti::Scalar(scalar), + }), + Ti::BindingArray { .. } => past_pointer.clone(), + ref other => { + log::error!("Pointer type {:?}", other); + return Err(ResolveError::InvalidPointer(pointer)); } } - Ti::ValuePointer { - size, - scalar, - space: _, - } => TypeResolution::Value(match size { - Some(size) => Ti::Vector { size, scalar }, - None => Ti::Scalar(scalar), - }), - ref other => { - log::error!("Pointer type {:?}", other); - return Err(ResolveError::InvalidPointer(pointer)); - } - }, + } crate::Expression::ImageSample { image, gather: Some(_), diff --git a/naga/src/valid/analyzer.rs b/naga/src/valid/analyzer.rs index 6b4679632..924612233 100644 --- a/naga/src/valid/analyzer.rs +++ b/naga/src/valid/analyzer.rs @@ -212,6 +212,7 @@ impl GlobalOrArgument { crate::Expression::Access { base, .. } | crate::Expression::AccessIndex { base, .. } => match expression_arena[base] { crate::Expression::GlobalVariable(var) => GlobalOrArgument::Global(var), + crate::Expression::FunctionArgument(i) => GlobalOrArgument::Argument(i), _ => return Err(ExpressionError::ExpectedGlobalOrArgument), }, _ => return Err(ExpressionError::ExpectedGlobalOrArgument), diff --git a/naga/src/valid/expression.rs b/naga/src/valid/expression.rs index ccdc501a5..bc851bc7b 100644 --- a/naga/src/valid/expression.rs +++ b/naga/src/valid/expression.rs @@ -373,6 +373,7 @@ impl super::Validator { .flags .contains(TypeFlags::SIZED | TypeFlags::DATA) => {} Ti::ValuePointer { .. } => {} + Ti::BindingArray { .. } => {} ref other => { log::error!("Loading {:?}", other); return Err(ExpressionError::InvalidPointerType(pointer)); @@ -1677,6 +1678,14 @@ impl super::Validator { _ => Err(ExpressionError::ExpectedBindingArrayType(array_ty)), } } + Ex::FunctionArgument(i) => { + let array_ty = function.arguments[i as usize].ty; + + match module.types[array_ty].inner { + crate::TypeInner::BindingArray { base, .. } => Ok(base), + _ => Err(ExpressionError::ExpectedBindingArrayType(array_ty)), + } + } _ => Err(ExpressionError::ExpectedGlobalVariable), } } diff --git a/naga/src/valid/type.rs b/naga/src/valid/type.rs index c0c25dab7..ff75e112e 100644 --- a/naga/src/valid/type.rs +++ b/naga/src/valid/type.rs @@ -665,10 +665,12 @@ impl super::Validator { } Ti::BindingArray { base, size } => { let type_info_mask = match size { - crate::ArraySize::Constant(_) => TypeFlags::SIZED | TypeFlags::HOST_SHAREABLE, + crate::ArraySize::Constant(_) => { + TypeFlags::SIZED | TypeFlags::HOST_SHAREABLE | TypeFlags::ARGUMENT + } crate::ArraySize::Dynamic => { // Final type is non-sized - TypeFlags::HOST_SHAREABLE + TypeFlags::HOST_SHAREABLE | TypeFlags::ARGUMENT } }; let base_info = &self.types[base.index()];