@@ -2191,7 +2191,10 @@ std::string ValidationState_t::InspectShaderDebugInfo(const Instruction& inst) {
21912191 if (func != nullptr ) {
21922192 if (inst.opcode () == spv::Op::OpVariable) {
21932193 InspectDebugLocalVariable (ss, *func, inst);
2194+ } else if (inst.opcode () == spv::Op::OpFunctionCall) {
2195+ InspectDebugFunctionDefinition (ss, inst);
21942196 } else {
2197+ // Currently a fall back for anything in a function
21952198 InspectDebugLine (ss, inst);
21962199 }
21972200 } else if (inst.opcode () == spv::Op::OpVariable) {
@@ -2203,6 +2206,88 @@ std::string ValidationState_t::InspectShaderDebugInfo(const Instruction& inst) {
22032206 return ss.str ();
22042207}
22052208
2209+ ValidationState_t::DebugSourceInfo ValidationState_t::GetDebugSourceInfo (
2210+ const Instruction& inst) {
2211+ assert (inst.opcode () == spv::Op::OpExtInst);
2212+ assert (inst.word (3 ) == ShaderDebugInfoSet ());
2213+
2214+ uint32_t line_start_id = 0 , line_end_id = 0 , column_start_id = 0 ,
2215+ column_end_id = 0 ;
2216+
2217+ switch (inst.word (4 )) {
2218+ case NonSemanticShaderDebugInfoDebugLine:
2219+ line_start_id = 6 ;
2220+ line_end_id = 7 ;
2221+ column_start_id = 8 ;
2222+ column_end_id = 9 ;
2223+ break ;
2224+ case NonSemanticShaderDebugInfoDebugTypeTemplateParameterPack:
2225+ line_start_id = 7 ;
2226+ column_start_id = 8 ;
2227+ break ;
2228+ case NonSemanticShaderDebugInfoDebugLexicalBlock:
2229+ line_start_id = 6 ;
2230+ column_start_id = 7 ;
2231+ break ;
2232+ case NonSemanticShaderDebugInfoDebugLocalVariable:
2233+ case NonSemanticShaderDebugInfoDebugGlobalVariable:
2234+ case NonSemanticShaderDebugInfoDebugTypedef:
2235+ case NonSemanticShaderDebugInfoDebugTypeEnum:
2236+ case NonSemanticShaderDebugInfoDebugTypeComposite:
2237+ case NonSemanticShaderDebugInfoDebugTypeMember:
2238+ case NonSemanticShaderDebugInfoDebugTypeTemplateTemplateParameter:
2239+ case NonSemanticShaderDebugInfoDebugFunctionDeclaration:
2240+ case NonSemanticShaderDebugInfoDebugFunction:
2241+ line_start_id = 8 ;
2242+ column_start_id = 9 ;
2243+ break ;
2244+ case NonSemanticShaderDebugInfoDebugTypeTemplateParameter:
2245+ case NonSemanticShaderDebugInfoDebugImportedEntity:
2246+ line_start_id = 9 ;
2247+ column_start_id = 10 ;
2248+ break ;
2249+ case NonSemanticShaderDebugInfoDebugMacroDef:
2250+ case NonSemanticShaderDebugInfoDebugMacroUndef:
2251+ line_start_id = 6 ;
2252+ break ;
2253+ default :
2254+ return {0 , 0 , 0 , 0 };
2255+ }
2256+
2257+ // spirv-val enforces these are int32 constants
2258+ bool is_int32 = false , is_const_int32 = false ;
2259+ uint32_t line_start = 0 ;
2260+ uint32_t line_end = 0 ;
2261+ uint32_t column_start = 0 ;
2262+ uint32_t column_end = 0 ;
2263+
2264+ std::tie (is_int32, is_const_int32, line_start) =
2265+ EvalInt32IfConst (inst.word (line_start_id));
2266+
2267+ // Some instructions only provide a line and column, so set the "end" to be
2268+ // same as "start"
2269+ if (line_end_id != 0 ) {
2270+ std::tie (is_int32, is_const_int32, line_end) =
2271+ EvalInt32IfConst (inst.word (line_end_id));
2272+ } else {
2273+ line_end = line_start;
2274+ }
2275+
2276+ if (column_start_id != 0 ) {
2277+ std::tie (is_int32, is_const_int32, column_start) =
2278+ EvalInt32IfConst (inst.word (column_start_id));
2279+ }
2280+
2281+ if (column_end_id != 0 ) {
2282+ std::tie (is_int32, is_const_int32, column_end) =
2283+ EvalInt32IfConst (inst.word (column_end_id));
2284+ } else {
2285+ column_end = column_start;
2286+ }
2287+
2288+ return {line_start, line_end, column_start, column_end};
2289+ }
2290+
22062291void ValidationState_t::InspectDebugLine (std::ostringstream& ss,
22072292 const Instruction& inst) {
22082293 const uint32_t set_id = ShaderDebugInfoSet ();
@@ -2233,22 +2318,8 @@ void ValidationState_t::InspectDebugLine(std::ostringstream& ss,
22332318 return ;
22342319 }
22352320
2236- bool is_int32 = false , is_const_int32 = false ;
2237- uint32_t line_start = 0 ;
2238- uint32_t line_end = 0 ;
2239- uint32_t column_start = 0 ;
2240- uint32_t column_end = 0 ;
2241- std::tie (is_int32, is_const_int32, line_start) =
2242- EvalInt32IfConst (debug_line_inst->word (6 ));
2243- std::tie (is_int32, is_const_int32, line_end) =
2244- EvalInt32IfConst (debug_line_inst->word (7 ));
2245- std::tie (is_int32, is_const_int32, column_start) =
2246- EvalInt32IfConst (debug_line_inst->word (8 ));
2247- std::tie (is_int32, is_const_int32, column_end) =
2248- EvalInt32IfConst (debug_line_inst->word (9 ));
2249-
2250- PrintShaderDebugInfoSource (ss, *debug_source, line_start, line_end,
2251- column_start);
2321+ auto source_info = GetDebugSourceInfo (*debug_line_inst);
2322+ PrintShaderDebugInfoSource (ss, *debug_source, source_info);
22522323}
22532324
22542325void ValidationState_t::InspectDebugGlobalVariable (
@@ -2279,16 +2350,8 @@ void ValidationState_t::InspectDebugGlobalVariable(
22792350 return ;
22802351 }
22812352
2282- bool is_int32 = false , is_const_int32 = false ;
2283- uint32_t line_start = 0 ;
2284- uint32_t column_start = 0 ;
2285- std::tie (is_int32, is_const_int32, line_start) =
2286- EvalInt32IfConst (debug_gloabl_var_inst->word (8 ));
2287- std::tie (is_int32, is_const_int32, column_start) =
2288- EvalInt32IfConst (debug_gloabl_var_inst->word (9 ));
2289-
2290- PrintShaderDebugInfoSource (ss, *debug_source, line_start, line_start,
2291- column_start);
2353+ auto source_info = GetDebugSourceInfo (*debug_gloabl_var_inst);
2354+ PrintShaderDebugInfoSource (ss, *debug_source, source_info);
22922355}
22932356
22942357void ValidationState_t::InspectDebugLocalVariable (
@@ -2333,24 +2396,68 @@ void ValidationState_t::InspectDebugLocalVariable(
23332396 return ;
23342397 }
23352398
2336- bool is_int32 = false , is_const_int32 = false ;
2337- uint32_t line_start = 0 ;
2338- uint32_t column_start = 0 ;
2339- std::tie (is_int32, is_const_int32, line_start) =
2340- EvalInt32IfConst (debug_local_variable->word (8 ));
2341- std::tie (is_int32, is_const_int32, column_start) =
2342- EvalInt32IfConst (debug_local_variable->word (9 ));
2399+ auto source_info = GetDebugSourceInfo (*debug_local_variable);
2400+ PrintShaderDebugInfoSource (ss, *debug_source, source_info);
2401+ }
2402+
2403+ void ValidationState_t::InspectDebugFunctionDefinition (
2404+ std::ostringstream& ss, const Instruction& function_call_inst) {
2405+ // First print the caller, then print the callee if also found
2406+ InspectDebugLine (ss, function_call_inst);
2407+
2408+ const uint32_t set_id = ShaderDebugInfoSet ();
2409+ const Instruction* debug_func_def = nullptr ;
2410+
2411+ const uint32_t callee_function_id =
2412+ function_call_inst.GetOperandAs <uint32_t >(2 );
2413+ const Instruction* function_inst = FindDef (callee_function_id);
2414+ if (!function_inst) return ;
2415+
2416+ // Loop through the Function block as the DebugFunctionDefinition needs to be
2417+ // inside it
2418+ size_t first_inst_id = (function_inst - &ordered_instructions ()[0 ]) + 1 ;
2419+ for (size_t i = first_inst_id + 1 ; i < ordered_instructions ().size (); ++i) {
2420+ const Instruction& current_inst = ordered_instructions ()[i];
2421+ if (current_inst.opcode () == spv::Op::OpFunctionEnd) {
2422+ break ; // we hit the next Funciton block
2423+ }
2424+
2425+ if (current_inst.opcode () == spv::Op::OpExtInst &&
2426+ current_inst.GetOperandAs <uint32_t >(2 ) == set_id &&
2427+ current_inst.GetOperandAs <uint32_t >(3 ) ==
2428+ NonSemanticShaderDebugInfoDebugFunctionDefinition &&
2429+ current_inst.GetOperandAs <uint32_t >(5 ) == callee_function_id) {
2430+ debug_func_def = ¤t_inst;
2431+ break ;
2432+ }
2433+ }
2434+ if (!debug_func_def) return ;
2435+
2436+ const Instruction* debug_function =
2437+ FindDef (debug_func_def->GetOperandAs <uint32_t >(4 ));
2438+ if (!debug_function || debug_function->GetOperandAs <uint32_t >(3 ) !=
2439+ NonSemanticShaderDebugInfoDebugFunction) {
2440+ return ;
2441+ }
2442+
2443+ const Instruction* debug_source =
2444+ FindDef (debug_function->GetOperandAs <uint32_t >(6 ));
2445+ if (!debug_source || debug_source->GetOperandAs <uint32_t >(3 ) !=
2446+ NonSemanticShaderDebugInfoDebugSource) {
2447+ return ;
2448+ }
23432449
2344- PrintShaderDebugInfoSource (ss, *debug_source, line_start, line_start,
2345- column_start );
2450+ auto source_info = GetDebugSourceInfo (*debug_function);
2451+ PrintShaderDebugInfoSource (ss, *debug_source, source_info );
23462452}
23472453
23482454void ValidationState_t::PrintShaderDebugInfoSource (
23492455 std::ostringstream& ss, const Instruction& debug_source,
2350- uint32_t line_start, uint32_t line_end, uint32_t column_start ) {
2456+ const DebugSourceInfo& source_info ) {
23512457 // The left hand side line number, need to make sure if going from line number
23522458 // 99 to 100 that all lines have the same padding
2353- const size_t vertical_line_padding = std::to_string (line_end).length ();
2459+ const size_t vertical_line_padding =
2460+ std::to_string (source_info.line_end ).length ();
23542461 auto add_vertical_line = [&](uint32_t line_number) {
23552462 size_t padding = 1 ;
23562463 if (line_number != 0 ) {
@@ -2373,9 +2480,10 @@ void ValidationState_t::PrintShaderDebugInfoSource(
23732480 auto stream_text = [&](const Instruction* op_string) {
23742481 const std::string text = op_string->GetOperandAs <std::string>(1 );
23752482 for (const char c : text) {
2376- if (current_line_num >= line_start && current_line_num <= line_end) {
2483+ if (current_line_num >= source_info.line_start &&
2484+ current_line_num <= source_info.line_end ) {
23772485 ss << c;
2378- if (c == ' \n ' && current_line_num < line_end) {
2486+ if (c == ' \n ' && current_line_num < source_info. line_end ) {
23792487 add_vertical_line (current_line_num + 1 );
23802488 }
23812489 }
@@ -2389,14 +2497,14 @@ void ValidationState_t::PrintShaderDebugInfoSource(
23892497 const Instruction* file_string =
23902498 FindDef (debug_source.GetOperandAs <uint32_t >(4 ));
23912499 ss << " \n --> " << file_string->GetOperandAs <std::string>(1 ) << " :"
2392- << line_start << " :" << column_start << ' \n ' ;
2500+ << source_info. line_start << " :" << source_info. column_start << ' \n ' ;
23932501
23942502 add_vertical_line (0 );
23952503 ss << ' \n ' ;
23962504
23972505 const Instruction* source_string =
23982506 FindDef (debug_source.GetOperandAs <uint32_t >(5 ));
2399- add_vertical_line (line_start);
2507+ add_vertical_line (source_info. line_start );
24002508 stream_text (source_string);
24012509
24022510 const uint32_t set_id = ShaderDebugInfoSet ();
@@ -2418,10 +2526,9 @@ void ValidationState_t::PrintShaderDebugInfoSource(
24182526 }
24192527
24202528 // This happens if the error is the last line of source
2421- if (current_line_num == line_end) ss << " \n " ;
2529+ if (current_line_num == source_info. line_end ) ss << " \n " ;
24222530
24232531 add_vertical_line (0 );
2424- ss << " \n " ;
24252532}
24262533
24272534bool ValidationState_t::IsValidStorageClass (
0 commit comments