Reduce runtime of array layout checks (#2534)
Fixes #2533
* Stop checking layouts once the offset gets back to a 16 byte alignment
diff --git a/source/val/validate_decorations.cpp b/source/val/validate_decorations.cpp
index 193b170..1eef64d 100644
--- a/source/val/validate_decorations.cpp
+++ b/source/val/validate_decorations.cpp
@@ -548,6 +548,9 @@
typeId, storage_class_str, decoration_str,
blockRules, next_offset, constraints, vstate)))
return recursive_status;
+ // If offsets accumulate up to a 16-byte multiple stop checking since
+ // it will just repeat.
+ if (i > 0 && (next_offset % 16 == 0)) break;
}
// Proceed to the element in case it is an array.
diff --git a/test/val/val_decoration_test.cpp b/test/val/val_decoration_test.cpp
index 635afad..764ee08 100644
--- a/test/val/val_decoration_test.cpp
+++ b/test/val/val_decoration_test.cpp
@@ -5719,6 +5719,41 @@
"improperly straddling vector at offset 28"));
}
+TEST_F(ValidateDecorations, LargeArray) {
+ const std::string spirv = R"(
+OpCapability Shader
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+OpExecutionMode %main LocalSize 1 1 1
+OpDecorate %struct Block
+OpMemberDecorate %struct 0 Offset 0
+OpDecorate %array ArrayStride 24
+OpMemberDecorate %inner 0 Offset 0
+OpMemberDecorate %inner 1 Offset 8
+OpMemberDecorate %inner 2 Offset 16
+OpMemberDecorate %inner 3 Offset 20
+OpDecorate %var DescriptorSet 0
+OpDecorate %var Binding 0
+%void = OpTypeVoid
+%int = OpTypeInt 32 0
+%int_2000000 = OpConstant %int 2000000
+%int2 = OpTypeVector %int 2
+%inner = OpTypeStruct %int %int2 %int %int
+%array = OpTypeArray %inner %int_2000000
+%struct = OpTypeStruct %array
+%ptr_struct = OpTypePointer StorageBuffer %struct
+%var = OpVariable %ptr_struct StorageBuffer
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
+ EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
+}
+
// NonWritable
// Returns a SPIR-V shader module with variables in various storage classes,