MCPcopy Create free account
hub / github.com/KhronosGroup/Vulkan-ValidationLayers / Validate

Method Validate

layers/gpuav/spirv/debug_printf_pass.cpp:623–904  ·  view source on GitHub ↗

Strictly speaking - the format given in GLSL_EXT_debug_printf is a client side implementation of SPIR-V NonSemantic.DebugPrintf There is nothing stopping someone from creating a debug printf implementation that goes `printf("Use this &q to print int", myInt)` but this requires both having a different HLL and Tool consuming it. Currently RenderDoc and the Validation Layers both follow the same synt

Source from the content-addressed store, hash-verified

621// Currently RenderDoc and the Validation Layers both follow the same syntax, but that also could possibly change.
622// Therefore, we validate these here based on the VVL implementation only
623bool DebugPrintfPass::Validate(const Function& current_function, const InstructionMeta& meta) {
624 static const char* tag = "DEBUG-PRINTF-FORMATTING";
625
626 struct ParamInfo {
627 bool is_float = false; // else int (don't attempt to validate unsigned vs signed here)
628 bool is_64_bit = false;
629 bool is_pointer = false;
630 uint32_t vector_size = 0; // zero == scalar
631 char modifier[32];
632 };
633
634 // where we find the first arugment in OpExtInst instruction
635 const uint32_t first_argument_offset = 6;
636
637 if (meta.target_instruction->Length() < first_argument_offset) {
638 module_.InternalError(tag, "OpExtInst in a invalid SPIR-V format and should have been caught in spirv-val");
639 return false;
640 }
641
642 uint32_t string_id = meta.target_instruction->Word(5);
643 const char* op_string = nullptr;
644 for (const auto& inst : module_.debug_source_) {
645 if (inst->Opcode() == spv::OpString && inst->ResultId() == string_id) {
646 op_string = inst->GetAsString(2);
647 break;
648 }
649 }
650 if (!op_string) {
651 module_.InternalError(tag, "OpExtInst points to an empty/invalid OpString, this should have been caught in spirv-val");
652 return false;
653 }
654
655 const size_t op_string_len = strlen(op_string);
656 if (op_string_len == 0) {
657 module_.InternalError(tag, "OpString is empty (string was found, but is empty)");
658 return false;
659 }
660
661 // If we are going to print the OpString to the user for an error/warning, we need to process it first
662 auto print_op_string = [&op_string]() {
663 // If there is a '\n' we want to print it like we see in the shader, so need to escape the backslash
664 std::string result;
665 for (const char* p = op_string; *p != '\0'; ++p) {
666 if (*p == '\n') {
667 result += "\\n";
668 } else if (*p == '\t') {
669 result += "\\t";
670 } else {
671 result += *p;
672 }
673 }
674 return result;
675 };
676
677 bool valid = true;
678 std::vector<ParamInfo> param_infos;
679
680 // No reason to start checking at the last character, since always need % and something following it

Callers

nothing calls this directly

Calls 12

LengthMethod · 0.80
WordMethod · 0.80
OpcodeMethod · 0.80
ResultIdMethod · 0.80
GetAsStringMethod · 0.80
FindTypeGlobalMethod · 0.80
FindTypeByIdMethod · 0.80
InternalErrorMethod · 0.45
push_backMethod · 0.45
sizeMethod · 0.45
InternalWarningMethod · 0.45
StorageClassMethod · 0.45

Tested by

no test coverage detected