spirv-val: Validate DebugTypeMatrix (#4732)

This commit is contained in:
Jeremy Hayes 2022-03-04 06:54:05 -07:00 committed by GitHub
parent f56726a323
commit 598bc6744a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 282 additions and 0 deletions

View File

@ -147,6 +147,24 @@ bool DoesDebugInfoOperandMatchExpectation(
return true;
}
// Overload for NonSemanticShaderDebugInfo100Instructions.
bool DoesDebugInfoOperandMatchExpectation(
const ValidationState_t& _,
const std::function<bool(NonSemanticShaderDebugInfo100Instructions)>&
expectation,
const Instruction* inst, uint32_t word_index) {
if (inst->words().size() <= word_index) return false;
auto* debug_inst = _.FindDef(inst->word(word_index));
if (debug_inst->opcode() != SpvOpExtInst ||
(debug_inst->ext_inst_type() !=
SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100) ||
!expectation(
NonSemanticShaderDebugInfo100Instructions(debug_inst->word(4)))) {
return false;
}
return true;
}
// Check that the operand of a debug info instruction |inst| at |word_index|
// is a result id of an debug info instruction whose debug instruction type
// is |expected_debug_inst|.
@ -223,6 +241,18 @@ spv_result_t ValidateOperandDebugType(
const Instruction* inst, uint32_t word_index,
const std::function<std::string()>& ext_inst_name,
bool allow_template_param) {
// Check for NonSemanticShaderDebugInfo100 specific types.
if (inst->ext_inst_type() ==
SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100) {
std::function<bool(NonSemanticShaderDebugInfo100Instructions)> expectation =
[](NonSemanticShaderDebugInfo100Instructions dbg_inst) {
return dbg_inst == NonSemanticShaderDebugInfo100DebugTypeMatrix;
};
if (DoesDebugInfoOperandMatchExpectation(_, expectation, inst, word_index))
return SPV_SUCCESS;
}
// Check for common types.
std::function<bool(CommonDebugInfoInstructions)> expectation =
[&allow_template_param](CommonDebugInfoInstructions dbg_inst) {
if (allow_template_param &&
@ -2719,6 +2749,86 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) {
auto num_words = inst->words().size();
// Handle any non-common NonSemanticShaderDebugInfo instructions.
if (vulkanDebugInfo) {
const NonSemanticShaderDebugInfo100Instructions ext_inst_key =
NonSemanticShaderDebugInfo100Instructions(ext_inst_index);
switch (ext_inst_key) {
// The following block of instructions will be handled by the common
// validation.
case NonSemanticShaderDebugInfo100DebugInfoNone:
case NonSemanticShaderDebugInfo100DebugCompilationUnit:
case NonSemanticShaderDebugInfo100DebugTypeBasic:
case NonSemanticShaderDebugInfo100DebugTypePointer:
case NonSemanticShaderDebugInfo100DebugTypeQualifier:
case NonSemanticShaderDebugInfo100DebugTypeArray:
case NonSemanticShaderDebugInfo100DebugTypeVector:
case NonSemanticShaderDebugInfo100DebugTypedef:
case NonSemanticShaderDebugInfo100DebugTypeFunction:
case NonSemanticShaderDebugInfo100DebugTypeEnum:
case NonSemanticShaderDebugInfo100DebugTypeComposite:
case NonSemanticShaderDebugInfo100DebugTypeMember:
case NonSemanticShaderDebugInfo100DebugTypeInheritance:
case NonSemanticShaderDebugInfo100DebugTypePtrToMember:
case NonSemanticShaderDebugInfo100DebugTypeTemplate:
case NonSemanticShaderDebugInfo100DebugTypeTemplateParameter:
case NonSemanticShaderDebugInfo100DebugTypeTemplateTemplateParameter:
case NonSemanticShaderDebugInfo100DebugTypeTemplateParameterPack:
case NonSemanticShaderDebugInfo100DebugGlobalVariable:
case NonSemanticShaderDebugInfo100DebugFunctionDeclaration:
case NonSemanticShaderDebugInfo100DebugFunction:
case NonSemanticShaderDebugInfo100DebugLexicalBlock:
case NonSemanticShaderDebugInfo100DebugLexicalBlockDiscriminator:
case NonSemanticShaderDebugInfo100DebugScope:
case NonSemanticShaderDebugInfo100DebugNoScope:
case NonSemanticShaderDebugInfo100DebugInlinedAt:
case NonSemanticShaderDebugInfo100DebugLocalVariable:
case NonSemanticShaderDebugInfo100DebugInlinedVariable:
case NonSemanticShaderDebugInfo100DebugDeclare:
case NonSemanticShaderDebugInfo100DebugValue:
case NonSemanticShaderDebugInfo100DebugOperation:
case NonSemanticShaderDebugInfo100DebugExpression:
case NonSemanticShaderDebugInfo100DebugMacroDef:
case NonSemanticShaderDebugInfo100DebugMacroUndef:
case NonSemanticShaderDebugInfo100DebugImportedEntity:
case NonSemanticShaderDebugInfo100DebugSource:
break;
case NonSemanticShaderDebugInfo100DebugTypeMatrix: {
CHECK_DEBUG_OPERAND("Vector Type", CommonDebugInfoDebugTypeVector, 5);
CHECK_CONST_UINT_OPERAND("Vector Count", 6);
uint32_t vector_count = inst->word(6);
uint64_t const_val;
if (!_.GetConstantValUint64(vector_count, &const_val)) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< ext_inst_name()
<< ": Vector Count must be 32-bit integer OpConstant";
}
vector_count = const_val & 0xffffffff;
if (!vector_count || vector_count > 4) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< ext_inst_name() << ": Vector Count must be positive "
<< "integer less than or equal to 4";
}
break;
}
// TODO: Add validation rules for remaining cases as well.
case NonSemanticShaderDebugInfo100DebugFunctionDefinition:
case NonSemanticShaderDebugInfo100DebugSourceContinued:
case NonSemanticShaderDebugInfo100DebugLine:
case NonSemanticShaderDebugInfo100DebugNoLine:
case NonSemanticShaderDebugInfo100DebugBuildIdentifier:
case NonSemanticShaderDebugInfo100DebugStoragePath:
case NonSemanticShaderDebugInfo100DebugEntryPoint:
break;
case NonSemanticShaderDebugInfo100InstructionsMax:
assert(0);
break;
}
}
// Handle any non-common OpenCL insts, then common
if (ext_inst_type != SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100 ||
OpenCLDebugInfo100Instructions(ext_inst_index) !=

View File

@ -1864,6 +1864,178 @@ OpExtension "SPV_KHR_non_semantic_info"
"integer less than or equal to 4"));
}
TEST_F(ValidateVulkan100DebugInfo, DebugTypeMatrix) {
const std::string src = R"(
%src = OpString "simple.hlsl"
%code = OpString "main() {}"
%float_name = OpString "float"
)";
const std::string constants = R"(
%u32_4 = OpConstant %u32 4
%u32_5 = OpConstant %u32 5
%u32_32 = OpConstant %u32 32
%true = OpConstantTrue %bool
)";
const std::string dbg_inst_header = R"(
%dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
%comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit %u32_2 %u32_4 %dbg_src %u32_5
%float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %u32_32 %u32_3 %u32_0
%vfloat_info = OpExtInst %void %DbgExt DebugTypeVector %float_info %u32_4
%mfloat_info = OpExtInst %void %DbgExt DebugTypeMatrix %vfloat_info %u32_4 %true
)";
const std::string extension = R"(
OpExtension "SPV_KHR_non_semantic_info"
%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
)";
CompileSuccessfully(GenerateShaderCodeForDebugInfo(
src, constants, dbg_inst_header, "", extension, "Vertex"));
ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
}
TEST_F(ValidateVulkan100DebugInfo, DebugTypeMatrixFailVectorTypeType) {
const std::string src = R"(
%src = OpString "simple.hlsl"
%code = OpString "main() {}"
%float_name = OpString "float"
)";
const std::string constants = R"(
%u32_4 = OpConstant %u32 4
%u32_5 = OpConstant %u32 5
%u32_32 = OpConstant %u32 32
%true = OpConstantTrue %bool
)";
const std::string dbg_inst_header = R"(
%dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
%comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit %u32_2 %u32_4 %dbg_src %u32_5
%float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %u32_32 %u32_3 %u32_0
%vfloat_info = OpExtInst %void %DbgExt DebugTypeVector %float_info %u32_4
%mfloat_info = OpExtInst %void %DbgExt DebugTypeMatrix %dbg_src %u32_4 %true
)";
const std::string extension = R"(
OpExtension "SPV_KHR_non_semantic_info"
%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
)";
CompileSuccessfully(GenerateShaderCodeForDebugInfo(
src, constants, dbg_inst_header, "", extension, "Vertex"));
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
EXPECT_THAT(getDiagnosticString(),
HasSubstr("expected operand Vector Type must be a result id of "
"DebugTypeVector"));
}
TEST_F(ValidateVulkan100DebugInfo, DebugTypeMatrixFailVectorCountType) {
const std::string src = R"(
%src = OpString "simple.hlsl"
%code = OpString "main() {}"
%float_name = OpString "float"
)";
const std::string constants = R"(
%u32_4 = OpConstant %u32 4
%u32_5 = OpConstant %u32 5
%u32_32 = OpConstant %u32 32
%true = OpConstantTrue %bool
)";
const std::string dbg_inst_header = R"(
%dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
%comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit %u32_2 %u32_4 %dbg_src %u32_5
%float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %u32_32 %u32_3 %u32_0
%vfloat_info = OpExtInst %void %DbgExt DebugTypeVector %float_info %u32_4
%mfloat_info = OpExtInst %void %DbgExt DebugTypeMatrix %vfloat_info %dbg_src %true
)";
const std::string extension = R"(
OpExtension "SPV_KHR_non_semantic_info"
%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
)";
CompileSuccessfully(GenerateShaderCodeForDebugInfo(
src, constants, dbg_inst_header, "", extension, "Vertex"));
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
EXPECT_THAT(getDiagnosticString(),
HasSubstr("expected operand Vector Count must be a result id of "
"32-bit unsigned OpConstant"));
}
TEST_F(ValidateVulkan100DebugInfo, DebugTypeMatrixFailVectorCountZero) {
const std::string src = R"(
%src = OpString "simple.hlsl"
%code = OpString "main() {}"
%float_name = OpString "float"
)";
const std::string constants = R"(
%u32_4 = OpConstant %u32 4
%u32_5 = OpConstant %u32 5
%u32_32 = OpConstant %u32 32
%true = OpConstantTrue %bool
)";
const std::string dbg_inst_header = R"(
%dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
%comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit %u32_2 %u32_4 %dbg_src %u32_5
%float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %u32_32 %u32_3 %u32_0
%vfloat_info = OpExtInst %void %DbgExt DebugTypeVector %float_info %u32_4
%mfloat_info = OpExtInst %void %DbgExt DebugTypeMatrix %vfloat_info %u32_0 %true
)";
const std::string extension = R"(
OpExtension "SPV_KHR_non_semantic_info"
%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
)";
CompileSuccessfully(GenerateShaderCodeForDebugInfo(
src, constants, dbg_inst_header, "", extension, "Vertex"));
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
EXPECT_THAT(getDiagnosticString(),
HasSubstr("Vector Count must be positive "
"integer less than or equal to 4"));
}
TEST_F(ValidateVulkan100DebugInfo, DebugTypeMatrixFailVectorCountFive) {
const std::string src = R"(
%src = OpString "simple.hlsl"
%code = OpString "main() {}"
%float_name = OpString "float"
)";
const std::string constants = R"(
%u32_4 = OpConstant %u32 4
%u32_5 = OpConstant %u32 5
%u32_32 = OpConstant %u32 32
%true = OpConstantTrue %bool
)";
const std::string dbg_inst_header = R"(
%dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
%comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit %u32_2 %u32_4 %dbg_src %u32_5
%float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %u32_32 %u32_3 %u32_0
%vfloat_info = OpExtInst %void %DbgExt DebugTypeVector %float_info %u32_4
%mfloat_info = OpExtInst %void %DbgExt DebugTypeMatrix %vfloat_info %u32_5 %true
)";
const std::string extension = R"(
OpExtension "SPV_KHR_non_semantic_info"
%DbgExt = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
)";
CompileSuccessfully(GenerateShaderCodeForDebugInfo(
src, constants, dbg_inst_header, "", extension, "Vertex"));
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
EXPECT_THAT(getDiagnosticString(),
HasSubstr("Vector Count must be positive "
"integer less than or equal to 4"));
}
TEST_F(ValidateOpenCL100DebugInfo, DebugTypedef) {
const std::string src = R"(
%src = OpString "simple.hlsl"