Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions source/val/validate_interfaces.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@ spv_result_t GetLocationsForVariable(
// validator allows duplicate decorations if the location/component/index are
// equal. Also track Patch and PerTaskNV decorations.
bool has_location = false;
bool has_component = false;
uint32_t location = 0;
uint32_t component = 0;
bool has_index = false;
Expand All @@ -304,6 +305,7 @@ spv_result_t GetLocationsForVariable(
location = dec.params()[0];
} else if (dec.dec_type() == spv::Decoration::Component) {
component = dec.params()[0];
has_component = true;
} else if (dec.dec_type() == spv::Decoration::Index) {
if (!is_output || !is_fragment) {
return _.diag(SPV_ERROR_INVALID_DATA, variable)
Expand Down Expand Up @@ -376,6 +378,16 @@ spv_result_t GetLocationsForVariable(
type = _.FindDef(type_id);
}

if (has_component && type->opcode() == spv::Op::OpTypeArray &&
_.GetIdOpcode(type->GetOperandAs<uint32_t>(1)) == spv::Op::OpTypeArray) {
return _.diag(SPV_ERROR_INVALID_DATA, variable)
<< _.VkErrorID(is_output ? 10585 : 10584)
<< "Entry-point interface variable in the "
<< (is_output ? "Output" : "Input")
<< " storage class is decorated with Component and is an array of "
"arrays of scalars or vectors";
}

if (type->opcode() == spv::Op::OpTypeStruct) {
// Don't check built-ins.
if (_.HasDecoration(type_id, spv::Decoration::BuiltIn)) return SPV_SUCCESS;
Expand Down
4 changes: 4 additions & 0 deletions source/val/validation_state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3652,6 +3652,10 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
return VUID_WRAP(VUID-StandaloneSpirv-OpTypeFloat-10370);
case 10583:
return VUID_WRAP(VUID-StandaloneSpirv-Component-10583);
case 10584:
return VUID_WRAP(VUID-StandaloneSpirv-Execution-10584);
case 10585:
return VUID_WRAP(VUID-StandaloneSpirv-Execution-10585);
case 10589:
return VUID_WRAP(VUID-CullPrimitiveEXT-CullPrimitiveEXT-10589);
case 10590:
Expand Down
66 changes: 66 additions & 0 deletions test/val/val_interfaces_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2310,6 +2310,72 @@ OpFunctionEnd
ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_3));
}

TEST_F(ValidateInterfacesTest, VulkanComponentArrayOfArraysInput) {
const std::string text = R"(
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main" %var
OpExecutionMode %main OriginUpperLeft
OpDecorate %var Location 0
OpDecorate %var Component 0
%void = OpTypeVoid
%void_fn = OpTypeFunction %void
%float = OpTypeFloat 32
%uint = OpTypeInt 32 0
%uint_2 = OpConstant %uint 2
%arr_float = OpTypeArray %float %uint_2
%arr_arr_float = OpTypeArray %arr_float %uint_2
%ptr_input_arr_arr = OpTypePointer Input %arr_arr_float
%var = OpVariable %ptr_input_arr_arr Input
%main = OpFunction %void None %void_fn
%entry = OpLabel
OpReturn
OpFunctionEnd
)";

CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
EXPECT_THAT(getDiagnosticString(),
AnyVUID("VUID-StandaloneSpirv-Execution-10584"));
EXPECT_THAT(getDiagnosticString(),
HasSubstr("Entry-point interface variable in the Input storage "
"class is decorated with Component and is an array of "
"arrays of scalars or vectors"));
}

TEST_F(ValidateInterfacesTest, VulkanComponentArrayOfArraysOutput) {
const std::string text = R"(
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main" %var
OpExecutionMode %main OriginUpperLeft
OpDecorate %var Location 0
OpDecorate %var Component 0
%void = OpTypeVoid
%void_fn = OpTypeFunction %void
%float = OpTypeFloat 32
%uint = OpTypeInt 32 0
%uint_2 = OpConstant %uint 2
%arr_float = OpTypeArray %float %uint_2
%arr_arr_float = OpTypeArray %arr_float %uint_2
%ptr_output_arr_arr = OpTypePointer Output %arr_arr_float
%var = OpVariable %ptr_output_arr_arr Output
%main = OpFunction %void None %void_fn
%entry = OpLabel
OpReturn
OpFunctionEnd
)";

CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
EXPECT_THAT(getDiagnosticString(),
AnyVUID("VUID-StandaloneSpirv-Execution-10585"));
EXPECT_THAT(getDiagnosticString(),
HasSubstr("Entry-point interface variable in the Output storage "
"class is decorated with Component and is an array of "
"arrays of scalars or vectors"));
}

} // namespace
} // namespace val
} // namespace spvtools
Loading