Skip to content

Commit a6cb960

Browse files
authored
Check that layouts match runtime array requirement (KhronosGroup#6048)
Fixes KhronosGroup#6039 * Layouts can be out of order so ensure that runtime arrays are both the last member of the structure (already checked), but also largest offset (new check)
1 parent 2b3df1e commit a6cb960

File tree

2 files changed

+76
-0
lines changed

2 files changed

+76
-0
lines changed

source/val/validate_decorations.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,15 @@ spv_result_t checkLayout(uint32_t struct_id, const char* storage_class_str,
509509
// Check offset.
510510
if (offset == 0xffffffff)
511511
return fail(memberIdx) << "is missing an Offset decoration";
512+
513+
if (opcode == spv::Op::OpTypeRuntimeArray &&
514+
ordered_member_idx != member_offsets.size() - 1) {
515+
return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(struct_id))
516+
<< vstate.VkErrorID(4680) << "Structure id " << struct_id
517+
<< " has a runtime array at offset " << offset
518+
<< ", but other members at larger offsets";
519+
}
520+
512521
if (!scalar_block_layout && relaxed_block_layout &&
513522
opcode == spv::Op::OpTypeVector) {
514523
// In relaxed block layout, the vector offset must be aligned to the

test/val/val_decoration_test.cpp

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10998,6 +10998,73 @@ OpFunctionEnd
1099810998
EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
1099910999
}
1100011000

11001+
TEST_F(ValidateDecorations, RuntimeArrayNotLargestOffsetInBlock) {
11002+
const std::string spirv = R"(
11003+
OpCapability Shader
11004+
OpExtension "SPV_KHR_storage_buffer_storage_class"
11005+
OpMemoryModel Logical GLSL450
11006+
OpEntryPoint GLCompute %main "main"
11007+
OpExecutionMode %main LocalSize 1 1 1
11008+
OpDecorate %var DescriptorSet 0
11009+
OpDecorate %var Binding 0
11010+
OpDecorate %block Block
11011+
OpMemberDecorate %block 0 Offset 16
11012+
OpMemberDecorate %block 1 Offset 0
11013+
%void = OpTypeVoid
11014+
%void_fn = OpTypeFunction %void
11015+
%int = OpTypeInt 32 0
11016+
%array = OpTypeRuntimeArray %int
11017+
%block = OpTypeStruct %int %array
11018+
%ptr = OpTypePointer StorageBuffer %block
11019+
%var = OpVariable %ptr StorageBuffer
11020+
%main = OpFunction %void None %void_fn
11021+
%entry = OpLabel
11022+
OpReturn
11023+
OpFunctionEnd
11024+
)";
11025+
11026+
CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
11027+
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
11028+
EXPECT_THAT(getDiagnosticString(),
11029+
HasSubstr("has a runtime array at offset 0, but other members at "
11030+
"larger offsets"));
11031+
EXPECT_THAT(getDiagnosticString(),
11032+
AnyVUID("VUID-StandaloneSpirv-OpTypeRuntimeArray-04680"));
11033+
}
11034+
11035+
TEST_F(ValidateDecorations, RuntimeArrayNotLargestOffsetInBufferBlock) {
11036+
const std::string spirv = R"(
11037+
OpCapability Shader
11038+
OpMemoryModel Logical GLSL450
11039+
OpEntryPoint GLCompute %main "main"
11040+
OpExecutionMode %main LocalSize 1 1 1
11041+
OpDecorate %var DescriptorSet 0
11042+
OpDecorate %var Binding 0
11043+
OpDecorate %block BufferBlock
11044+
OpMemberDecorate %block 0 Offset 16
11045+
OpMemberDecorate %block 1 Offset 0
11046+
%void = OpTypeVoid
11047+
%void_fn = OpTypeFunction %void
11048+
%int = OpTypeInt 32 0
11049+
%array = OpTypeRuntimeArray %int
11050+
%block = OpTypeStruct %int %array
11051+
%ptr = OpTypePointer Uniform %block
11052+
%var = OpVariable %ptr Uniform
11053+
%main = OpFunction %void None %void_fn
11054+
%entry = OpLabel
11055+
OpReturn
11056+
OpFunctionEnd
11057+
)";
11058+
11059+
CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
11060+
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
11061+
EXPECT_THAT(getDiagnosticString(),
11062+
HasSubstr("has a runtime array at offset 0, but other members at "
11063+
"larger offsets"));
11064+
EXPECT_THAT(getDiagnosticString(),
11065+
AnyVUID("VUID-StandaloneSpirv-OpTypeRuntimeArray-04680"));
11066+
}
11067+
1100111068
} // namespace
1100211069
} // namespace val
1100311070
} // namespace spvtools

0 commit comments

Comments
 (0)