From 019bf37a9b73bf6590b83ff0feaf6a752fd52fe9 Mon Sep 17 00:00:00 2001 From: Jake Turner Date: Tue, 15 Oct 2024 15:55:32 +0100 Subject: [PATCH] Handle more scopes in DXIL Program::GetDebugScopeFilePath If the scope tree does not end at a DIFile node then use the most recent non-NULL file metadata found when walking the scope tree --- .../driver/shaders/dxil/dxil_debuginfo.cpp | 122 ++++++++++++------ 1 file changed, 86 insertions(+), 36 deletions(-) diff --git a/renderdoc/driver/shaders/dxil/dxil_debuginfo.cpp b/renderdoc/driver/shaders/dxil/dxil_debuginfo.cpp index fd4846c28..439a1e6dc 100644 --- a/renderdoc/driver/shaders/dxil/dxil_debuginfo.cpp +++ b/renderdoc/driver/shaders/dxil/dxil_debuginfo.cpp @@ -307,48 +307,98 @@ uint64_t Program::GetDebugScopeLine(const DIBase *d) const rdcstr Program::GetDebugScopeFilePath(const DIBase *d) const { - const Metadata *scope = NULL; - if(d->type == DIBase::Subprogram) - scope = d->As()->scope; - else if(d->type == DIBase::LexicalBlock) - scope = d->As()->scope; - else if(d->type == DIBase::LocalVariable) - scope = d->As()->scope; - - while(scope && scope->dwarf) + const DIBase *dwarf = d; + const Metadata *fileMD = NULL; + while(dwarf) { - if(scope->dwarf->type == DIBase::Subprogram) + const Metadata *scope = NULL; + const Metadata *newFileMD = NULL; + switch(dwarf->type) { - scope = scope->dwarf->As()->scope; - continue; + case DIBase::CompileUnit: fileMD = dwarf->As()->file; break; + case DIBase::DerivedType: + scope = dwarf->As()->scope; + newFileMD = dwarf->As()->file; + break; + case DIBase::CompositeType: + scope = dwarf->As()->scope; + newFileMD = dwarf->As()->file; + break; + case DIBase::Subprogram: + scope = dwarf->As()->scope; + newFileMD = dwarf->As()->file; + break; + case DIBase::GlobalVariable: + scope = dwarf->As()->scope; + newFileMD = dwarf->As()->file; + break; + case DIBase::LocalVariable: + scope = dwarf->As()->scope; + newFileMD = dwarf->As()->file; + break; + case DIBase::LexicalBlock: + scope = dwarf->As()->scope; + newFileMD = dwarf->As()->file; + break; + case DIBase::Namespace: + scope = dwarf->As()->scope; + newFileMD = dwarf->As()->file; + break; + case DIBase::ImportedEntity: scope = dwarf->As()->scope; break; + case DIBase::BasicType: break; + case DIBase::TemplateTypeParameter: break; + case DIBase::TemplateValueParameter: break; + case DIBase::SubroutineType: break; + case DIBase::Expression: break; + case DIBase::Subrange: break; + case DIBase::Enum: break; + case DIBase::File: break; } - else if(scope->dwarf->type == DIBase::LexicalBlock) - { - scope = scope->dwarf->As()->scope; - continue; - } - else if(scope->dwarf->type == DIBase::CompositeType) - { - scope = scope->dwarf->As()->file; - continue; - } - break; - } - if(d->type != DIBase::File) - { - if(!scope || !scope->dwarf) - return "???"; - } + if(newFileMD) + fileMD = newFileMD; - const DXIL::DIBase *dwarf = (d->type != DIBase::File) ? scope->dwarf : d; - RDCASSERT(dwarf->type == DIBase::File); - const DIFile *f = dwarf->As(); + if(!scope) + break; + dwarf = scope->dwarf; + }; + if(!dwarf) + return "???"; + + rdcstr file; + rdcstr dir; + if(dwarf->type == DIBase::File) + { + const DIFile *f = dwarf->As(); + if(f->dir) + dir = f->dir->str; + file = f->file->str; + } + else if(fileMD) + { + if(fileMD->children.size() > 0) + { + if(fileMD->children[0]) + file = fileMD->children[0]->str; + else + file = "???"; + + if((fileMD->children.size() > 1) && fileMD->children[1]) + dir = fileMD->children[1]->str; + } + else + { + file = "???"; + } + } + else + { + file = "???"; + } rdcstr filePath; - if(f->dir) - filePath = f->dir->str + "/"; - - filePath += f->file->str; + if(!dir.empty()) + filePath = dir + "/"; + filePath += file; return filePath; }