From ba2280c5c705fceb31443a57bb6bed96c3e5be7e Mon Sep 17 00:00:00 2001 From: baldurk Date: Mon, 9 Apr 2018 11:58:53 +0100 Subject: [PATCH] Apply extra sort to SPDB file list to put entry file first. Closes #950 * This isn't 100% reliable but it seems reasonably consistent that while the first file in the streams isn't always the entry file, the first name of a file in the list of names which map to files is. So we re-sort by the list of names. --- .../driver/shaders/dxbc/dxbc_inspect.cpp | 27 ++++++++++ .../driver/shaders/dxbc/dxbc_reflect.cpp | 50 +------------------ 2 files changed, 29 insertions(+), 48 deletions(-) diff --git a/renderdoc/driver/shaders/dxbc/dxbc_inspect.cpp b/renderdoc/driver/shaders/dxbc/dxbc_inspect.cpp index 8a9a72da1..2a4caec7f 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_inspect.cpp +++ b/renderdoc/driver/shaders/dxbc/dxbc_inspect.cpp @@ -24,6 +24,7 @@ ******************************************************************************/ #include "dxbc_inspect.h" +#include #include "api/app/renderdoc_app.h" #include "common/common.h" #include "serialise/serialiser.h" @@ -2527,6 +2528,32 @@ SPDBChunk::SPDBChunk(void *chunk) delete[] pages; + // Sort files according to the order they come in the Names array, this seems to be more reliable + // about placing the main file first. + std::sort(Files.begin(), Files.end(), [&Names](const std::pair &a, + const std::pair &b) { + // any entries that aren't found in Names at all (like @cmdline that we add) will be sorted to + // the end. + size_t aIdx = ~0U, bIdx = ~0U; + + size_t i = 0; + for(auto it = Names.begin(); it != Names.end(); ++it) + { + if(it->second == a.first) + aIdx = i; + if(it->second == b.first) + bIdx = i; + + i++; + } + + // if neither were found, sort by filename + if(aIdx == bIdx) + return a.first < b.first; + + return aIdx < bIdx; + }); + m_HasDebugInfo = true; } diff --git a/renderdoc/driver/shaders/dxbc/dxbc_reflect.cpp b/renderdoc/driver/shaders/dxbc/dxbc_reflect.cpp index 29df72929..8eb483d6d 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_reflect.cpp +++ b/renderdoc/driver/shaders/dxbc/dxbc_reflect.cpp @@ -239,54 +239,8 @@ void MakeShaderReflection(DXBC::DXBCFile *dxbc, ShaderReflection *refl, if(entry.empty()) entry = "main"; - // sort the file with the entry point to the start. We don't have to do anything if there's only - // one file. - // This isn't a perfect search - it will match entry_point() anywhere in the file, even if it's - // in a comment or disabled preprocessor definition. This is just best-effort - if(refl->debugInfo.files.count() > 1) - { - // search from 0 up. If we find a match, we swap it into [0]. If we don't find a match then - // we can't rearrange anything. This is a no-op for 0 since it's already in first place, but - // since our search isn't perfect we might have multiple matches with some being false - // positives, and so we want to bias towards leaving [0] in place. - for(size_t i = 0; i < refl->debugInfo.files.size(); i++) - { - const char *c = strstr(refl->debugInfo.files[i].contents.c_str(), entry.c_str()); - const char *end = refl->debugInfo.files[i].contents.end(); - - // no substring match? continue - if(c == NULL) - continue; - - // if we did get a substring match, ensure there's whitespace preceeding it. - if(c == entry.c_str() || !isspace((int)*(c - 1))) - continue; - - // skip past the entry point. Then skip any whitespace - c += entry.size(); - - // check for EOF. - if(c >= end) - continue; - - while(c < end && isspace(*c)) - c++; - - if(c >= end) - continue; - - // if there's an open bracket next, we found a entry_point( which we count as the - // declaration. - if(*c == '(') - { - // only do anything if we're looking at a later file - if(i > 0) - std::swap(refl->debugInfo.files[0], refl->debugInfo.files[i]); - - break; - } - } - } + // assume the debug info put the file with the entry point at the start. SDBG seems to do this + // by default, and SPDB has an extra sorting step that probably maybe possibly does this. } refl->encoding = ShaderEncoding::DXBC;