From 07c4dd4b9ecb13f3a6d3bea1f51be6c9563c45ec Mon Sep 17 00:00:00 2001 From: alan-baker <33432579+alan-baker@users.noreply.github.com> Date: Tue, 23 Apr 2019 10:33:00 -0400 Subject: [PATCH] Reduce runtime of array layout checks (#2534) Fixes #2533 * Stop checking layouts once the offset gets back to a 16 byte alignment --- source/val/validate_decorations.cpp | 3 +++ test/val/val_decoration_test.cpp | 35 +++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/source/val/validate_decorations.cpp b/source/val/validate_decorations.cpp index 193b170e..1eef64d5 100644 --- a/source/val/validate_decorations.cpp +++ b/source/val/validate_decorations.cpp @@ -548,6 +548,9 @@ spv_result_t checkLayout(uint32_t struct_id, const char* storage_class_str, 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 635afad2..764ee08b 100644 --- a/test/val/val_decoration_test.cpp +++ b/test/val/val_decoration_test.cpp @@ -5719,6 +5719,41 @@ OpFunctionEnd "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,