diff --git a/crates/rustc_codegen_spirv/src/codegen_cx/entry.rs b/crates/rustc_codegen_spirv/src/codegen_cx/entry.rs index d179fba3b6..030c35f154 100644 --- a/crates/rustc_codegen_spirv/src/codegen_cx/entry.rs +++ b/crates/rustc_codegen_spirv/src/codegen_cx/entry.rs @@ -456,7 +456,14 @@ impl<'tcx> CodegenCx<'tcx> { Decoration::Location, std::iter::once(Operand::LiteralInt32(*location)), ); - *location += 1; + // Arrays take up multiple locations + *location += if let SpirvType::Array { count, .. } = self.lookup_type(value_spirv_type) { + self.builder + .lookup_const_u64(count) + .expect("Array type has invalid count value") as u32 + } else { + 1 + } } // Emit the `OpVariable` with its *Result* ID set to `variable`. diff --git a/crates/spirv-builder/src/test/basic.rs b/crates/spirv-builder/src/test/basic.rs index 4c77cba9f4..18ec05d64a 100644 --- a/crates/spirv-builder/src/test/basic.rs +++ b/crates/spirv-builder/src/test/basic.rs @@ -500,3 +500,43 @@ OpUnreachable OpFunctionEnd"#, ) } + +#[test] +fn array_locations() { + dis_globals( + r#" +#[allow(unused_variables)] +#[spirv(fragment(entry_point_name="array_locations"))] +pub fn main(one: [f32; 7], two: [f32; 3], three: f32) { } +"#, + r#"OpCapability Shader +OpCapability VulkanMemoryModel +OpCapability VariablePointers +OpExtension "SPV_KHR_vulkan_memory_model" +OpMemoryModel Logical Vulkan +OpEntryPoint Fragment %1 "array_locations" %2 %3 %4 +OpExecutionMode %1 OriginUpperLeft +OpName %2 "one" +OpName %3 "two" +OpName %4 "three" +OpDecorate %5 ArrayStride 4 +OpDecorate %6 ArrayStride 4 +OpDecorate %2 Location 0 +OpDecorate %3 Location 7 +OpDecorate %4 Location 10 +%7 = OpTypeVoid +%8 = OpTypeFloat 32 +%9 = OpTypeInt 32 0 +%10 = OpConstant %9 7 +%5 = OpTypeArray %8 %10 +%11 = OpTypePointer Input %5 +%12 = OpConstant %9 3 +%6 = OpTypeArray %8 %12 +%13 = OpTypePointer Input %6 +%14 = OpTypeFunction %7 +%2 = OpVariable %11 Input +%3 = OpVariable %13 Input +%15 = OpTypePointer Input %8 +%4 = OpVariable %15 Input"#, + ); +}