mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-01 20:31:01 +00:00
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:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user