Fix Issue 4857 Case One

This commit is contained in:
dav 2024-11-11 16:08:35 -08:00
parent b89a57f8ca
commit 905e6dbefd
7 changed files with 47 additions and 25 deletions

View File

@ -264,6 +264,7 @@ impl crate::TypeInner {
crate::TypeInner::Image { .. }
| crate::TypeInner::Sampler { .. }
| crate::TypeInner::AccelerationStructure { .. } => true,
crate::TypeInner::BindingArray { .. } => true,
_ => false,
}
}

View File

@ -592,6 +592,12 @@ impl<I: Iterator<Item = u32>> super::Frontend<I> {
}
}
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<I: Iterator<Item = u32>> super::Frontend<I> {
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())),
},

View File

@ -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<T, N>`.
///
@ -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<Type>, size: ArraySize },
}

View File

@ -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(_),

View File

@ -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),

View File

@ -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),
}
}

View File

@ -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()];