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.
This commit is contained in:
baldurk
2018-04-09 17:11:25 +01:00
parent 6c35697edc
commit ba2280c5c7
2 changed files with 29 additions and 48 deletions
@@ -24,6 +24,7 @@
******************************************************************************/
#include "dxbc_inspect.h"
#include <algorithm>
#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<std::string, std::string> &a,
const std::pair<std::string, std::string> &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;
}
+2 -48
View File
@@ -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;