diff --git a/src/front/spv/error.rs b/src/front/spv/error.rs index 6817106906..54109dd852 100644 --- a/src/front/spv/error.rs +++ b/src/front/spv/error.rs @@ -41,6 +41,8 @@ pub enum Error { UnsupportedControlFlow(spirv::Word), #[error("unsupported binary operator %{0}")] UnsupportedBinaryOperator(spirv::Word), + #[error("Naga supports OpTypeRuntimeArray in the StorageBuffer storage class only")] + UnsupportedRuntimeArrayStorageClass, #[error("unknown binary operator {0:?}")] UnknownBinaryOperator(spirv::Op), #[error("unknown relational function {0:?}")] diff --git a/src/front/spv/mod.rs b/src/front/spv/mod.rs index 26f849bd2f..fc5d2096b7 100644 --- a/src/front/spv/mod.rs +++ b/src/front/spv/mod.rs @@ -3881,7 +3881,8 @@ impl> Parser { let decor = self.future_decor.remove(&id); let base_lookup_ty = self.lookup_type.lookup(type_id)?; - let class = if let Some(class) = module.types[base_lookup_ty.handle].inner.pointer_class() { + let base_inner = &module.types[base_lookup_ty.handle].inner; + let class = if let Some(class) = base_inner.pointer_class() { class } else if self .lookup_storage_buffer_types @@ -3897,6 +3898,22 @@ impl> Parser { } }; + // We don't support pointers to runtime-sized arrays in the `Uniform` + // storage class with the `BufferBlock` decoration. Runtime-sized arrays + // should be in the StorageBuffer class. + if let crate::TypeInner::Array { + size: crate::ArraySize::Dynamic, + .. + } = *base_inner + { + match class { + crate::StorageClass::Storage { .. } => {} + _ => { + return Err(Error::UnsupportedRuntimeArrayStorageClass); + } + } + } + // Don't bother with pointer stuff for `Handle` types. let lookup_ty = if class == crate::StorageClass::Handle { base_lookup_ty.clone() diff --git a/tests/in/spv/shadow.spv b/tests/in/spv/shadow.spv index 265cf65fc0..b4dff9df6d 100644 Binary files a/tests/in/spv/shadow.spv and b/tests/in/spv/shadow.spv differ diff --git a/tests/out/ir/shadow.ron b/tests/out/ir/shadow.ron index 572ffe39f6..13220b7aea 100644 --- a/tests/out/ir/shadow.ron +++ b/tests/out/ir/shadow.ron @@ -200,21 +200,33 @@ name: None, inner: Pointer( base: 19, - class: Uniform, + class: Storage( + access: ( + bits: 3, + ), + ), ), ), ( name: None, inner: Pointer( base: 18, - class: Uniform, + class: Storage( + access: ( + bits: 3, + ), + ), ), ), ( name: None, inner: Pointer( base: 17, - class: Uniform, + class: Storage( + access: ( + bits: 3, + ), + ), ), ), ( @@ -235,14 +247,22 @@ name: None, inner: Pointer( base: 4, - class: Uniform, + class: Storage( + access: ( + bits: 3, + ), + ), ), ), ( name: None, inner: Pointer( base: 1, - class: Uniform, + class: Storage( + access: ( + bits: 3, + ), + ), ), ), (