Add shader's ID and entry point to the shader reflection struct

* This allows better identification of a shader from its reflection
  bundle. The entry point was already 'optionally' in the debug info
  struct which is no longer a great location for it.
* For APIs where the entry point isn't contractual and it might not be
  listed, instead we just fall back to 'main'. This means that the UI
  or anyone fetching the info can be guaranteed that some sensible entry
  point will be listed.
* Also for the debug info, remove the 'entryFile' index and instead just
  guarantee that as much as possible the entry point will be in the
  first file in the list.
This commit is contained in:
baldurk
2017-07-05 16:27:17 +01:00
parent c2b0c2d7d8
commit bdf2a68c71
26 changed files with 298 additions and 256 deletions
@@ -872,19 +872,11 @@ void D3D11PipelineStateViewer::setShaderState(const D3D11Pipe::Shader &stage, QL
else
shader->setText(ToQStr(stage.name));
if(shaderDetails && !shaderDetails->DebugInfo.entryFunc.empty() &&
!shaderDetails->DebugInfo.files.empty())
if(shaderDetails && !shaderDetails->DebugInfo.files.empty())
{
QString shaderfn;
int entryFile = shaderDetails->DebugInfo.entryFile;
if(entryFile < 0 || entryFile >= shaderDetails->DebugInfo.files.count)
entryFile = 0;
shaderfn = QFileInfo(ToQStr(shaderDetails->DebugInfo.files[entryFile].first)).fileName();
shader->setText(
QFormatStr("%1() - %2").arg(ToQStr(shaderDetails->DebugInfo.entryFunc)).arg(shaderfn));
shader->setText(QFormatStr("%1() - %2")
.arg(ToQStr(shaderDetails->EntryPoint))
.arg(QFileInfo(ToQStr(shaderDetails->DebugInfo.files[0].first)).fileName()));
}
int vs = 0;
@@ -1141,8 +1133,8 @@ void D3D11PipelineStateViewer::setState()
{
QString layout = ToQStr(state.m_IA.name);
if(state.m_IA.Bytecode && !state.m_IA.Bytecode->DebugInfo.entryFunc.empty())
layout += QFormatStr(" (%1)").arg(ToQStr(state.m_IA.Bytecode->DebugInfo.entryFunc));
if(state.m_IA.Bytecode && !state.m_IA.Bytecode->DebugInfo.files.empty())
layout += QFormatStr(" (%1)").arg(ToQStr(state.m_IA.Bytecode->EntryPoint));
ui->iaBytecode->setText(layout);
}
@@ -2533,19 +2525,11 @@ void D3D11PipelineStateViewer::exportHTML(QXmlStreamWriter &xml, D3D11Pipe::Shad
else
shadername = ToQStr(sh.name);
if(shaderDetails && shaderDetails->DebugInfo.entryFunc.count > 0 &&
shaderDetails->DebugInfo.files.count > 0)
if(shaderDetails && shaderDetails->DebugInfo.files.count > 0)
{
QString shaderfn;
int entryFile = shaderDetails->DebugInfo.entryFile;
if(entryFile < 0 || entryFile >= shaderDetails->DebugInfo.files.count)
entryFile = 0;
shaderfn = QFileInfo(ToQStr(shaderDetails->DebugInfo.files[entryFile].first)).fileName();
shadername =
QFormatStr("%1() - %2").arg(ToQStr(shaderDetails->DebugInfo.entryFunc)).arg(shaderfn);
shadername = QFormatStr("%1() - %2")
.arg(ToQStr(shaderDetails->EntryPoint))
.arg(QFileInfo(ToQStr(shaderDetails->DebugInfo.files[0].first)).fileName());
}
xml.writeStartElement(lit("p"));
@@ -961,19 +961,11 @@ void D3D12PipelineStateViewer::setShaderState(const D3D12Pipe::Shader &stage, QL
shader->setText(
tr("%1 - %2 Shader").arg(ToQStr(state.name)).arg(ToQStr(stage.stage, GraphicsAPI::D3D12)));
if(shaderDetails && !shaderDetails->DebugInfo.entryFunc.empty() &&
!shaderDetails->DebugInfo.files.empty())
if(shaderDetails && !shaderDetails->DebugInfo.files.empty())
{
QString shaderfn;
int entryFile = shaderDetails->DebugInfo.entryFile;
if(entryFile < 0 || entryFile >= shaderDetails->DebugInfo.files.count)
entryFile = 0;
shaderfn = QFileInfo(ToQStr(shaderDetails->DebugInfo.files[entryFile].first)).fileName();
shader->setText(
QFormatStr("%1() - %2").arg(ToQStr(shaderDetails->DebugInfo.entryFunc)).arg(shaderfn));
shader->setText(QFormatStr("%1() - %2")
.arg(ToQStr(shaderDetails->EntryPoint))
.arg(QFileInfo(ToQStr(shaderDetails->DebugInfo.files[0].first)).fileName()));
}
int vs = 0;
@@ -2429,19 +2421,11 @@ void D3D12PipelineStateViewer::exportHTML(QXmlStreamWriter &xml, D3D12Pipe::Shad
shadername =
tr("%1 - %2 Shader").arg(ToQStr(state.name)).arg(ToQStr(sh.stage, GraphicsAPI::D3D12));
if(shaderDetails && !shaderDetails->DebugInfo.entryFunc.empty() &&
!shaderDetails->DebugInfo.files.empty())
if(shaderDetails && !shaderDetails->DebugInfo.files.empty())
{
QString shaderfn;
int entryFile = shaderDetails->DebugInfo.entryFile;
if(entryFile < 0 || entryFile >= shaderDetails->DebugInfo.files.count)
entryFile = 0;
shaderfn = QFileInfo(ToQStr(shaderDetails->DebugInfo.files[entryFile].first)).fileName();
shadername =
QFormatStr("%1() - %2").arg(ToQStr(shaderDetails->DebugInfo.entryFunc)).arg(shaderfn);
shadername = QFormatStr("%1() - %2")
.arg(ToQStr(shaderDetails->EntryPoint))
.arg(QFileInfo(ToQStr(shaderDetails->DebugInfo.files[0].first)).fileName());
}
xml.writeStartElement(lit("p"));
@@ -531,9 +531,9 @@ bool PipelineStateViewer::PrepareShaderEditing(const ShaderReflection *shaderDet
QString &entryFunc, QStringMap &files,
QString &mainfile)
{
if(!shaderDetails->DebugInfo.entryFunc.empty() && !shaderDetails->DebugInfo.files.empty())
if(!shaderDetails->DebugInfo.files.empty())
{
entryFunc = ToQStr(shaderDetails->DebugInfo.entryFunc);
entryFunc = ToQStr(shaderDetails->EntryPoint);
QStringList uniqueFiles;
@@ -550,11 +550,7 @@ bool PipelineStateViewer::PrepareShaderEditing(const ShaderReflection *shaderDet
files[filename] = ToQStr(s.second);
}
int entryFile = shaderDetails->DebugInfo.entryFile;
if(entryFile < 0 || entryFile >= shaderDetails->DebugInfo.files.count)
entryFile = 0;
mainfile = ToQStr(shaderDetails->DebugInfo.files[entryFile].first);
mainfile = ToQStr(shaderDetails->DebugInfo.files[0].first);
return true;
}
@@ -1251,24 +1251,15 @@ void VulkanPipelineStateViewer::setShaderState(const VKPipe::Shader &stage,
else
shader->setText(ToQStr(stage.name));
if(shaderDetails != NULL && shaderDetails->DebugInfo.entryFunc.count > 0)
if(shaderDetails != NULL)
{
QString entryFunc = ToQStr(shaderDetails->DebugInfo.entryFunc);
QString entryFunc = ToQStr(shaderDetails->EntryPoint);
if(shaderDetails->DebugInfo.files.count > 0 || entryFunc != lit("main"))
shader->setText(entryFunc + lit("()"));
if(shaderDetails->DebugInfo.files.count > 0)
{
QString shaderfn = QString();
int entryFile = shaderDetails->DebugInfo.entryFile;
if(entryFile < 0 || entryFile >= shaderDetails->DebugInfo.files.count)
entryFile = 0;
shaderfn = QFileInfo(ToQStr(shaderDetails->DebugInfo.files[entryFile].first)).fileName();
shader->setText(entryFunc + lit("() - ") + shaderfn);
}
shader->setText(entryFunc + lit("() - ") +
QFileInfo(ToQStr(shaderDetails->DebugInfo.files[0].first)).fileName());
}
int vs = 0;
@@ -2554,24 +2545,15 @@ void VulkanPipelineStateViewer::exportHTML(QXmlStreamWriter &xml, VKPipe::Shader
else
shadername = ToQStr(sh.name);
if(shaderDetails && shaderDetails->DebugInfo.entryFunc.count > 0)
if(shaderDetails)
{
QString entryFunc = ToQStr(shaderDetails->DebugInfo.entryFunc);
if(shaderDetails->DebugInfo.files.count > 0 || entryFunc != lit("main"))
QString entryFunc = ToQStr(shaderDetails->EntryPoint);
if(entryFunc != lit("main"))
shadername = QFormatStr("%1()").arg(entryFunc);
if(shaderDetails->DebugInfo.files.count > 0)
{
QString shaderfn = QString();
int entryFile = shaderDetails->DebugInfo.entryFile;
if(entryFile < 0 || entryFile >= shaderDetails->DebugInfo.files.count)
entryFile = 0;
shaderfn = QFileInfo(ToQStr(shaderDetails->DebugInfo.files[entryFile].first)).fileName();
shadername = QFormatStr("%1() - %2").arg(entryFunc).arg(shaderfn);
}
else if(shaderDetails->DebugInfo.files.count > 0)
shadername = QFormatStr("%1() - %2")
.arg(entryFunc)
.arg(QFileInfo(ToQStr(shaderDetails->DebugInfo.files[0].first)).fileName());
}
xml.writeStartElement(lit("p"));
+6 -15
View File
@@ -307,17 +307,16 @@ void ShaderViewer::debugShader(const ShaderBindpointMapping *bind, const ShaderR
&ShaderViewer::disasm_tooltipHide);
}
if(shader && shader->DebugInfo.entryFunc.count > 0 && shader->DebugInfo.files.count > 0)
if(shader && shader->DebugInfo.files.count > 0)
{
if(trace)
setWindowTitle(
QFormatStr("Debug %1() - %2").arg(ToQStr(shader->DebugInfo.entryFunc)).arg(debugContext));
setWindowTitle(QFormatStr("Debug %1() - %2").arg(ToQStr(shader->EntryPoint)).arg(debugContext));
else
setWindowTitle(ToQStr(shader->DebugInfo.entryFunc));
setWindowTitle(ToQStr(shader->EntryPoint));
int fileIdx = 0;
QWidget *sel = m_DisassemblyView;
QWidget *sel = NULL;
for(auto &f : shader->DebugInfo.files)
{
QString name = QFileInfo(ToQStr(f.first)).fileName();
@@ -325,21 +324,13 @@ void ShaderViewer::debugShader(const ShaderBindpointMapping *bind, const ShaderR
ScintillaEdit *scintilla = AddFileScintilla(name, text);
if(shader->DebugInfo.entryFile >= 0 &&
shader->DebugInfo.entryFile < shader->DebugInfo.files.count)
{
if(fileIdx == shader->DebugInfo.entryFile)
sel = scintilla;
}
else if(text.contains(ToQStr(shader->DebugInfo.entryFunc)))
{
if(sel == NULL)
sel = scintilla;
}
fileIdx++;
}
if(trace)
if(trace || sel == NULL)
sel = m_DisassemblyView;
if(shader->DebugInfo.files.count > 2)
+11 -8
View File
@@ -449,18 +449,15 @@ Primarily this means the embedded original source files.
)");
struct ShaderDebugChunk
{
ShaderDebugChunk() : compileFlags(0), entryFile(0) {}
DOCUMENT("The name of the entry point function for this shader.");
rdctype::str entryFunc;
ShaderDebugChunk() : compileFlags(0) {}
DOCUMENT("An API or compiler specific set of flags used to compile this shader originally.");
uint32_t compileFlags;
DOCUMENT("A list of tuples, where each tuple is a pair of filename, source code.");
rdctype::array<rdctype::pair<rdctype::str, rdctype::str> > files;
DOCUMENT(R"(A list of tuples, where each tuple is a pair of filename, source code.
DOCUMENT("The index in :data:`files` where the entry point exists, or ``-1`` if it's not found.");
int32_t entryFile;
The first entry in the list is always the file where the entry point is.
)");
rdctype::array<rdctype::pair<rdctype::str, rdctype::str> > files;
};
DECLARE_REFLECTION_STRUCT(ShaderDebugChunk);
@@ -473,6 +470,12 @@ and resource binding scheme.
)");
struct ShaderReflection
{
DOCUMENT("The :class:`ResourceId` of this shader.");
ResourceId ID;
DOCUMENT("The entry point in the shader for this reflection, if multiple entry points exist.");
rdctype::str EntryPoint;
DOCUMENT(
"A :class:`ShaderDebugChunk` containing any embedded debugging information in this shader.");
ShaderDebugChunk DebugInfo;
+3 -1
View File
@@ -212,8 +212,10 @@ void Serialiser::Serialise(const char *name, ShaderResource &el)
template <>
void Serialiser::Serialise(const char *name, ShaderReflection &el)
{
Serialise("", el.ID);
Serialise("", el.EntryPoint);
Serialise("", el.DebugInfo.compileFlags);
Serialise("", el.DebugInfo.entryFunc);
Serialise("", el.DebugInfo.files);
SerialisePODArray<3>("", el.DispatchThreadsDimension);
+50 -6
View File
@@ -414,21 +414,65 @@ ShaderReflection *MakeShaderReflection(DXBC::DXBCFile *dxbc)
if(dxbc->m_DebugInfo)
{
ret->DebugInfo.entryFunc = dxbc->m_DebugInfo->GetEntryFunction();
ret->DebugInfo.compileFlags = dxbc->m_DebugInfo->GetShaderCompileFlags();
ret->DebugInfo.entryFile = -1;
create_array_uninit(ret->DebugInfo.files, dxbc->m_DebugInfo->Files.size());
for(size_t i = 0; i < dxbc->m_DebugInfo->Files.size(); i++)
{
ret->DebugInfo.files[i].first = dxbc->m_DebugInfo->Files[i].first;
ret->DebugInfo.files[i].second = dxbc->m_DebugInfo->Files[i].second;
}
if(ret->DebugInfo.entryFile == -1 &&
strstr(ret->DebugInfo.files[i].second.elems, ret->DebugInfo.entryFunc.elems))
string entry = dxbc->m_DebugInfo->GetEntryFunction();
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(ret->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(int32_t i = 0; i < ret->DebugInfo.files.count; i++)
{
ret->DebugInfo.entryFile = (int32_t)i;
char *c = strstr(ret->DebugInfo.files[i].first.elems, entry.c_str());
char *end = ret->DebugInfo.files[i].first.elems + ret->DebugInfo.files[i].first.count;
// 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(ret->DebugInfo.files[0], ret->DebugInfo.files[i]);
break;
}
}
}
}
+29 -28
View File
@@ -1101,7 +1101,7 @@ bool WrappedID3D11Device::Serialise_CreateInputLayout(
m_LayoutDescs[ret] = descvec;
if(BytecodeLen > 0 && ShaderBytecode)
m_LayoutShaders[ret] =
new WrappedShader(this, GetIDForResource(ret), ShaderBytecode, BytecodeLen);
new WrappedShader(this, pLayout, GetIDForResource(ret), ShaderBytecode, BytecodeLen);
SAFE_DELETE_ARRAY(ShaderBytecode);
}
@@ -1182,8 +1182,8 @@ bool WrappedID3D11Device::Serialise_CreateVertexShader(const void *pShaderByteco
}
else
{
ret = new WrappedID3D11Shader<ID3D11VertexShader>(ret, ShaderBytecode, (size_t)BytecodeLen,
this);
ret = new WrappedID3D11Shader<ID3D11VertexShader>(ret, pShader, ShaderBytecode,
(size_t)BytecodeLen, this);
GetResourceManager()->AddLiveResource(pShader, ret);
}
@@ -1212,8 +1212,8 @@ HRESULT WrappedID3D11Device::CreateVertexShader(const void *pShaderBytecode, SIZ
{
SCOPED_LOCK(m_D3DLock);
wrapped = new WrappedID3D11Shader<ID3D11VertexShader>(real, (const byte *)pShaderBytecode,
BytecodeLength, this);
wrapped = new WrappedID3D11Shader<ID3D11VertexShader>(
real, ResourceId(), (const byte *)pShaderBytecode, BytecodeLength, this);
if(m_State >= WRITING)
{
@@ -1270,8 +1270,8 @@ bool WrappedID3D11Device::Serialise_CreateGeometryShader(const void *pShaderByte
}
else
{
ret = new WrappedID3D11Shader<ID3D11GeometryShader>(ret, ShaderBytecode, (size_t)BytecodeLen,
this);
ret = new WrappedID3D11Shader<ID3D11GeometryShader>(ret, pShader, ShaderBytecode,
(size_t)BytecodeLen, this);
GetResourceManager()->AddLiveResource(pShader, ret);
}
@@ -1300,8 +1300,8 @@ HRESULT WrappedID3D11Device::CreateGeometryShader(const void *pShaderBytecode, S
{
SCOPED_LOCK(m_D3DLock);
wrapped = new WrappedID3D11Shader<ID3D11GeometryShader>(real, (const byte *)pShaderBytecode,
BytecodeLength, this);
wrapped = new WrappedID3D11Shader<ID3D11GeometryShader>(
real, ResourceId(), (const byte *)pShaderBytecode, BytecodeLength, this);
if(m_State >= WRITING)
{
@@ -1371,8 +1371,8 @@ bool WrappedID3D11Device::Serialise_CreateGeometryShaderWithStreamOutput(
}
else
{
ret = new WrappedID3D11Shader<ID3D11GeometryShader>(ret, ShaderBytecode, (size_t)BytecodeLen,
this);
ret = new WrappedID3D11Shader<ID3D11GeometryShader>(ret, pShader, ShaderBytecode,
(size_t)BytecodeLen, this);
GetResourceManager()->AddLiveResource(pShader, ret);
}
@@ -1408,8 +1408,8 @@ HRESULT WrappedID3D11Device::CreateGeometryShaderWithStreamOutput(
{
SCOPED_LOCK(m_D3DLock);
wrapped = new WrappedID3D11Shader<ID3D11GeometryShader>(real, (const byte *)pShaderBytecode,
BytecodeLength, this);
wrapped = new WrappedID3D11Shader<ID3D11GeometryShader>(
real, ResourceId(), (const byte *)pShaderBytecode, BytecodeLength, this);
if(m_State >= WRITING)
{
@@ -1469,8 +1469,8 @@ bool WrappedID3D11Device::Serialise_CreatePixelShader(const void *pShaderBytecod
}
else
{
ret =
new WrappedID3D11Shader<ID3D11PixelShader>(ret, ShaderBytecode, (size_t)BytecodeLen, this);
ret = new WrappedID3D11Shader<ID3D11PixelShader>(ret, pShader, ShaderBytecode,
(size_t)BytecodeLen, this);
GetResourceManager()->AddLiveResource(pShader, ret);
}
@@ -1499,8 +1499,8 @@ HRESULT WrappedID3D11Device::CreatePixelShader(const void *pShaderBytecode, SIZE
{
SCOPED_LOCK(m_D3DLock);
wrapped = new WrappedID3D11Shader<ID3D11PixelShader>(real, (const byte *)pShaderBytecode,
BytecodeLength, this);
wrapped = new WrappedID3D11Shader<ID3D11PixelShader>(
real, ResourceId(), (const byte *)pShaderBytecode, BytecodeLength, this);
if(m_State >= WRITING)
{
@@ -1556,7 +1556,8 @@ bool WrappedID3D11Device::Serialise_CreateHullShader(const void *pShaderBytecode
}
else
{
ret = new WrappedID3D11Shader<ID3D11HullShader>(ret, ShaderBytecode, (size_t)BytecodeLen, this);
ret = new WrappedID3D11Shader<ID3D11HullShader>(ret, pShader, ShaderBytecode,
(size_t)BytecodeLen, this);
GetResourceManager()->AddLiveResource(pShader, ret);
}
@@ -1585,8 +1586,8 @@ HRESULT WrappedID3D11Device::CreateHullShader(const void *pShaderBytecode, SIZE_
{
SCOPED_LOCK(m_D3DLock);
wrapped = new WrappedID3D11Shader<ID3D11HullShader>(real, (const byte *)pShaderBytecode,
BytecodeLength, this);
wrapped = new WrappedID3D11Shader<ID3D11HullShader>(
real, ResourceId(), (const byte *)pShaderBytecode, BytecodeLength, this);
if(m_State >= WRITING)
{
@@ -1642,8 +1643,8 @@ bool WrappedID3D11Device::Serialise_CreateDomainShader(const void *pShaderByteco
}
else
{
ret = new WrappedID3D11Shader<ID3D11DomainShader>(ret, ShaderBytecode, (size_t)BytecodeLen,
this);
ret = new WrappedID3D11Shader<ID3D11DomainShader>(ret, pShader, ShaderBytecode,
(size_t)BytecodeLen, this);
GetResourceManager()->AddLiveResource(pShader, ret);
}
@@ -1672,8 +1673,8 @@ HRESULT WrappedID3D11Device::CreateDomainShader(const void *pShaderBytecode, SIZ
{
SCOPED_LOCK(m_D3DLock);
wrapped = new WrappedID3D11Shader<ID3D11DomainShader>(real, (const byte *)pShaderBytecode,
BytecodeLength, this);
wrapped = new WrappedID3D11Shader<ID3D11DomainShader>(
real, ResourceId(), (const byte *)pShaderBytecode, BytecodeLength, this);
if(m_State >= WRITING)
{
@@ -1730,8 +1731,8 @@ bool WrappedID3D11Device::Serialise_CreateComputeShader(const void *pShaderBytec
}
else
{
ret = new WrappedID3D11Shader<ID3D11ComputeShader>(ret, ShaderBytecode, (size_t)BytecodeLen,
this);
ret = new WrappedID3D11Shader<ID3D11ComputeShader>(ret, pShader, ShaderBytecode,
(size_t)BytecodeLen, this);
GetResourceManager()->AddLiveResource(pShader, ret);
}
@@ -1760,8 +1761,8 @@ HRESULT WrappedID3D11Device::CreateComputeShader(const void *pShaderBytecode, SI
{
SCOPED_LOCK(m_D3DLock);
wrapped = new WrappedID3D11Shader<ID3D11ComputeShader>(real, (const byte *)pShaderBytecode,
BytecodeLength, this);
wrapped = new WrappedID3D11Shader<ID3D11ComputeShader>(
real, ResourceId(), (const byte *)pShaderBytecode, BytecodeLength, this);
if(m_State >= WRITING)
{
+18 -6
View File
@@ -896,8 +896,9 @@ public:
{
public:
ShaderEntry() : m_DebugInfoSearchPaths(NULL), m_DXBCFile(NULL), m_Details(NULL) {}
ShaderEntry(WrappedID3D11Device *device, const byte *code, size_t codeLen)
ShaderEntry(WrappedID3D11Device *device, ResourceId id, const byte *code, size_t codeLen)
{
m_ID = id;
m_Bytecode.assign(code, code + codeLen);
m_DebugInfoSearchPaths = device->GetShaderDebugInfoSearchPaths();
m_DXBCFile = NULL;
@@ -923,7 +924,14 @@ public:
ShaderReflection *GetDetails()
{
if(m_Details == NULL && GetDXBC() != NULL)
{
m_Details = MakeShaderReflection(m_DXBCFile);
m_Details->ID = m_ID;
m_Details->EntryPoint =
m_DXBCFile->m_DebugInfo ? m_DXBCFile->m_DebugInfo->GetEntryFunction() : "";
if(m_Details->EntryPoint.empty())
m_Details->EntryPoint = "main";
}
return m_Details;
}
@@ -932,6 +940,8 @@ public:
void TryReplaceOriginalByteCode();
ShaderEntry &operator=(const ShaderEntry &e);
ResourceId m_ID;
std::string m_DebugInfoPath;
vector<std::string> *m_DebugInfoSearchPaths;
@@ -944,13 +954,15 @@ public:
static map<ResourceId, ShaderEntry *> m_ShaderList;
static Threading::CriticalSection m_ShaderListLock;
WrappedShader(WrappedID3D11Device *device, ResourceId id, const byte *code, size_t codeLen)
: m_ID(id)
WrappedShader(WrappedID3D11Device *device, ResourceId origId, ResourceId liveId, const byte *code,
size_t codeLen)
: m_ID(liveId)
{
SCOPED_LOCK(m_ShaderListLock);
RDCASSERT(m_ShaderList.find(m_ID) == m_ShaderList.end());
m_ShaderList[m_ID] = new ShaderEntry(device, code, codeLen);
m_ShaderList[m_ID] =
new ShaderEntry(device, origId != ResourceId() ? origId : liveId, code, codeLen);
}
virtual ~WrappedShader()
{
@@ -988,10 +1000,10 @@ public:
ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11Shader<RealShaderType>, AllocPoolCount,
AllocPoolMaxByteSize);
WrappedID3D11Shader(RealShaderType *real, const byte *code, size_t codeLen,
WrappedID3D11Shader(RealShaderType *real, ResourceId origId, const byte *code, size_t codeLen,
WrappedID3D11Device *device)
: WrappedDeviceChild11<RealShaderType>(real, device),
WrappedShader(device, GetResourceID(), code, codeLen)
WrappedShader(device, origId, GetResourceID(), code, codeLen)
{
}
virtual ~WrappedID3D11Shader() { Shutdown(); }
+50 -6
View File
@@ -401,21 +401,65 @@ void MakeShaderReflection(DXBC::DXBCFile *dxbc, ShaderReflection *refl,
if(dxbc->m_DebugInfo)
{
refl->DebugInfo.entryFunc = dxbc->m_DebugInfo->GetEntryFunction();
refl->DebugInfo.compileFlags = dxbc->m_DebugInfo->GetShaderCompileFlags();
refl->DebugInfo.entryFile = -1;
create_array_uninit(refl->DebugInfo.files, dxbc->m_DebugInfo->Files.size());
for(size_t i = 0; i < dxbc->m_DebugInfo->Files.size(); i++)
{
refl->DebugInfo.files[i].first = dxbc->m_DebugInfo->Files[i].first;
refl->DebugInfo.files[i].second = dxbc->m_DebugInfo->Files[i].second;
}
if(refl->DebugInfo.entryFile == -1 &&
strstr(refl->DebugInfo.files[i].second.elems, refl->DebugInfo.entryFunc.elems))
string entry = dxbc->m_DebugInfo->GetEntryFunction();
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(int32_t i = 0; i < refl->DebugInfo.files.count; i++)
{
refl->DebugInfo.entryFile = (int32_t)i;
char *c = strstr(refl->DebugInfo.files[i].first.elems, entry.c_str());
char *end = refl->DebugInfo.files[i].first.elems + refl->DebugInfo.files[i].first.count;
// 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;
}
}
}
}
+13 -2
View File
@@ -590,14 +590,15 @@ public:
ShaderReflection &GetDetails()
{
if(!m_Built && GetDXBC() != NULL)
MakeShaderReflection(m_DXBCFile, &m_Details, &m_Mapping);
BuildReflection();
m_Built = true;
return m_Details;
}
const ShaderBindpointMapping &GetMapping()
{
if(!m_Built && GetDXBC() != NULL)
MakeShaderReflection(m_DXBCFile, &m_Details, &m_Mapping);
BuildReflection();
m_Built = true;
return m_Mapping;
}
@@ -609,6 +610,16 @@ public:
void TryReplaceOriginalByteCode();
ShaderEntry &operator=(const ShaderEntry &e);
void BuildReflection()
{
MakeShaderReflection(m_DXBCFile, &m_Details, &m_Mapping);
m_Details.ID = GetResourceID();
m_Details.EntryPoint =
m_DXBCFile->m_DebugInfo ? m_DXBCFile->m_DebugInfo->GetEntryFunction() : "";
if(m_Details.EntryPoint.empty())
m_Details.EntryPoint = "main";
}
DXBCKey m_Key;
std::string m_DebugInfoPath;
+1 -1
View File
@@ -299,7 +299,7 @@ private:
ShaderReflection reflection;
GLuint prog;
void Compile(WrappedOpenGL &gl);
void Compile(WrappedOpenGL &gl, ResourceId id);
};
struct ProgramData
-3
View File
@@ -894,11 +894,8 @@ void ReconstructVarTree(const GLHookSet &gl, GLenum query, GLuint sepProg, GLuin
void MakeShaderReflection(const GLHookSet &gl, GLenum shadType, GLuint sepProg,
ShaderReflection &refl, bool pointSizeUsed, bool clipDistanceUsed)
{
refl.DebugInfo.entryFunc = "main";
refl.DebugInfo.compileFlags = 0;
refl.DebugInfo.entryFile = 0;
refl.Disassembly = "";
if(shadType == eGL_COMPUTE_SHADER)
@@ -29,7 +29,7 @@
#include "driver/shaders/spirv/spirv_common.h"
#include "serialise/string_utils.h"
void WrappedOpenGL::ShaderData::Compile(WrappedOpenGL &gl)
void WrappedOpenGL::ShaderData::Compile(WrappedOpenGL &gl, ResourceId id)
{
bool pointSizeUsed = false, clipDistanceUsed = false;
if(type == eGL_VERTEX_SHADER)
@@ -80,9 +80,12 @@ void WrappedOpenGL::ShaderData::Compile(WrappedOpenGL &gl)
if(!spirvwords.empty())
ParseSPIRV(&spirvwords.front(), spirvwords.size(), spirv);
reflection.ID = id;
reflection.EntryPoint = "main";
// for classic GL, entry point is always main
reflection.Disassembly = spirv.Disassemble("main");
// TODO sort these so that the first file contains the entry point
create_array_uninit(reflection.DebugInfo.files, sources.size());
for(size_t i = 0; i < sources.size(); i++)
{
@@ -244,7 +247,7 @@ bool WrappedOpenGL::Serialise_glCompileShader(GLuint shader)
{
ResourceId liveId = GetResourceManager()->GetLiveID(id);
m_Shaders[liveId].Compile(*this);
m_Shaders[liveId].Compile(*this, id);
m_Real.glCompileShader(GetResourceManager()->GetLiveResource(id).name);
}
@@ -271,7 +274,8 @@ void WrappedOpenGL::glCompileShader(GLuint shader)
}
else
{
m_Shaders[GetResourceManager()->GetID(ShaderRes(GetCtx(), shader))].Compile(*this);
ResourceId id = GetResourceManager()->GetID(ShaderRes(GetCtx(), shader));
m_Shaders[id].Compile(*this, id);
}
}
@@ -467,7 +471,7 @@ bool WrappedOpenGL::Serialise_glCreateShaderProgramv(GLuint program, GLenum type
shadDetails.sources.swap(src);
shadDetails.prog = sepprog;
shadDetails.Compile(*this);
shadDetails.Compile(*this, id);
GetResourceManager()->AddLiveResource(id, res);
}
@@ -527,7 +531,7 @@ GLuint WrappedOpenGL::glCreateShaderProgramv(GLenum type, GLsizei count, const G
shadDetails.sources.swap(src);
shadDetails.prog = sepprog;
shadDetails.Compile(*this);
shadDetails.Compile(*this, id);
}
return real;
@@ -1470,7 +1474,7 @@ bool WrappedOpenGL::Serialise_glCompileShaderIncludeARB(GLuint shader, GLsizei c
for(int32_t i = 0; i < Count; i++)
shadDetails.includepaths.push_back(pathstrings[i]);
shadDetails.Compile(*this);
shadDetails.Compile(*this, id);
m_Real.glCompileShaderIncludeARB(GetResourceManager()->GetLiveResource(id).name, Count,
pathstrings, NULL);
@@ -1511,7 +1515,7 @@ void WrappedOpenGL::glCompileShaderIncludeARB(GLuint shader, GLsizei count,
for(int32_t i = 0; i < count; i++)
shadDetails.includepaths.push_back(path[i]);
shadDetails.Compile(*this);
shadDetails.Compile(*this, id);
}
}
+15 -3
View File
@@ -148,11 +148,21 @@ void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan, Vulk
if(reflData.entryPoint.empty())
{
SPVModule &spv = info.m_ShaderModule[id].spirv;
spv.MakeReflection(ShaderStage(reflData.stage), reflData.entryPoint, reflData.refl,
reflData.mapping, reflData.patchData);
reflData.entryPoint = shad.entryPoint;
reflData.stage = stageIndex;
info.m_ShaderModule[id].spirv.MakeReflection(ShaderStage(reflData.stage), reflData.entryPoint,
reflData.refl, reflData.mapping,
reflData.patchData);
reflData.refl.ID = resourceMan->GetOriginalID(id);
reflData.refl.EntryPoint = shad.entryPoint;
if(!spv.spirv.empty())
{
rdctype::array<byte> &bytes = reflData.refl.RawBytes;
const vector<uint32_t> &spirv = spv.spirv;
create_array_init(bytes, spirv.size() * sizeof(uint32_t), (byte *)&spirv[0]);
}
}
if(pCreateInfo->pStages[i].pSpecializationInfo)
@@ -369,6 +379,8 @@ void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan, Vulk
info.m_ShaderModule[id].spirv.MakeReflection(ShaderStage::Compute, reflData.entryPoint,
reflData.refl, reflData.mapping,
reflData.patchData);
reflData.refl.ID = resourceMan->GetOriginalID(id);
reflData.refl.EntryPoint = shad.entryPoint;
}
if(pCreateInfo->stage.pSpecializationInfo)
-8
View File
@@ -919,14 +919,6 @@ ShaderReflection *VulkanReplay::GetShader(ResourceId shader, string entryPoint)
shad->second.m_Reflections[entryPoint].refl.Disassembly =
shad->second.spirv.Disassemble(entryPoint);
if(shad->second.m_Reflections[entryPoint].refl.RawBytes.count == 0 &&
!shad->second.spirv.spirv.empty())
{
rdctype::array<byte> &bytes = shad->second.m_Reflections[entryPoint].refl.RawBytes;
const vector<uint32_t> &spirv = shad->second.spirv.spirv;
create_array_init(bytes, spirv.size() * sizeof(uint32_t), (byte *)&spirv[0]);
}
return &shad->second.m_Reflections[entryPoint].refl;
}
+10
View File
@@ -37,9 +37,14 @@ namespace renderdoc
private void PostMarshal()
{
if (_ptr_Bytecode != IntPtr.Zero)
{
Bytecode = (ShaderReflection)CustomMarshal.PtrToStructure(_ptr_Bytecode, typeof(ShaderReflection), false);
Bytecode.origPtr = _ptr_Bytecode;
}
else
{
Bytecode = null;
}
_ptr_Bytecode = IntPtr.Zero;
}
@@ -95,9 +100,14 @@ namespace renderdoc
private void PostMarshal()
{
if (_ptr_ShaderDetails != IntPtr.Zero)
{
ShaderDetails = (ShaderReflection)CustomMarshal.PtrToStructure(_ptr_ShaderDetails, typeof(ShaderReflection), false);
ShaderDetails.origPtr = _ptr_ShaderDetails;
}
else
{
ShaderDetails = null;
}
_ptr_ShaderDetails = IntPtr.Zero;
}
@@ -166,9 +166,14 @@ namespace renderdoc
private void PostMarshal()
{
if (_ptr_ShaderDetails != IntPtr.Zero)
{
ShaderDetails = (ShaderReflection)CustomMarshal.PtrToStructure(_ptr_ShaderDetails, typeof(ShaderReflection), false);
ShaderDetails.origPtr = _ptr_ShaderDetails;
}
else
{
ShaderDetails = null;
}
_ptr_ShaderDetails = IntPtr.Zero;
}
+5
View File
@@ -89,9 +89,14 @@ namespace renderdoc
private void PostMarshal()
{
if (_ptr_ShaderDetails != IntPtr.Zero)
{
ShaderDetails = (ShaderReflection)CustomMarshal.PtrToStructure(_ptr_ShaderDetails, typeof(ShaderReflection), false);
ShaderDetails.origPtr = _ptr_ShaderDetails;
}
else
{
ShaderDetails = null;
}
_ptr_ShaderDetails = IntPtr.Zero;
}
+8 -5
View File
@@ -377,9 +377,6 @@ namespace renderdoc
[StructLayout(LayoutKind.Sequential)]
public class ShaderDebugChunk
{
[CustomMarshalAs(CustomUnmanagedType.UTF8TemplatedString)]
public string entryFunc;
public UInt32 compileFlags;
public struct DebugFile
@@ -413,13 +410,19 @@ namespace renderdoc
[CustomMarshalAs(CustomUnmanagedType.TemplatedArray)]
public DebugFile[] files;
public Int32 entryFile;
};
[StructLayout(LayoutKind.Sequential)]
public class ShaderReflection
{
public ResourceId ID;
[CustomMarshalAs(CustomUnmanagedType.UTF8TemplatedString)]
public string EntryPoint;
[CustomMarshalAs(CustomUnmanagedType.Skip)]
public IntPtr origPtr;
[CustomMarshalAs(CustomUnmanagedType.CustomClass)]
public ShaderDebugChunk DebugInfo;
@@ -171,9 +171,14 @@ namespace renderdoc
private void PostMarshal()
{
if (_ptr_ShaderDetails != IntPtr.Zero)
{
ShaderDetails = (ShaderReflection)CustomMarshal.PtrToStructure(_ptr_ShaderDetails, typeof(ShaderReflection), false);
ShaderDetails.origPtr = _ptr_ShaderDetails;
}
else
{
ShaderDetails = null;
}
_ptr_ShaderDetails = IntPtr.Zero;
}
@@ -310,18 +310,8 @@ namespace renderdocui.Windows.PipelineState
else
shader.Text = stage.ShaderName;
if (shaderDetails != null && shaderDetails.DebugInfo.entryFunc.Length > 0 && shaderDetails.DebugInfo.files.Length > 0)
{
string shaderfn = "";
int entryFile = shaderDetails.DebugInfo.entryFile;
if (entryFile < 0 || entryFile >= shaderDetails.DebugInfo.files.Length)
entryFile = 0;
shaderfn = shaderDetails.DebugInfo.files[entryFile].BaseFilename;
shader.Text = shaderDetails.DebugInfo.entryFunc + "()" + " - " + shaderfn;
}
if (shaderDetails != null && shaderDetails.DebugInfo.files.Length > 0)
shader.Text = shaderDetails.EntryPoint + "()" + " - " + shaderDetails.DebugInfo.files[0].BaseFilename;
int vs = 0;
@@ -768,8 +758,8 @@ namespace renderdocui.Windows.PipelineState
else
iaBytecode.Text = state.m_IA.LayoutName;
if (state.m_IA.Bytecode != null && state.m_IA.Bytecode.DebugInfo != null && state.m_IA.Bytecode.DebugInfo.entryFunc.Length > 0)
iaBytecode.Text += " (" + state.m_IA.Bytecode.DebugInfo.entryFunc + ")";
if (state.m_IA.Bytecode != null && state.m_IA.Bytecode.DebugInfo != null)
iaBytecode.Text += " (" + state.m_IA.Bytecode.EntryPoint + ")";
iaBytecodeMismatch.Text = "";
iaBytecodeMismatch.Visible = false;
@@ -2420,9 +2410,9 @@ namespace renderdocui.Windows.PipelineState
string mainfile = "";
var files = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
if (shaderDetails.DebugInfo.entryFunc.Length > 0 && shaderDetails.DebugInfo.files.Length > 0)
if (shaderDetails.DebugInfo.files.Length > 0)
{
entryFunc = shaderDetails.DebugInfo.entryFunc;
entryFunc = shaderDetails.EntryPoint;
foreach (var s in shaderDetails.DebugInfo.files)
{
@@ -2432,11 +2422,7 @@ namespace renderdocui.Windows.PipelineState
files.Add(s.FullFilename, s.filetext);
}
int entryFile = shaderDetails.DebugInfo.entryFile;
if (entryFile < 0 || entryFile >= shaderDetails.DebugInfo.files.Length)
entryFile = 0;
mainfile = shaderDetails.DebugInfo.files[entryFile].FullFilename;
mainfile = shaderDetails.DebugInfo.files[0].FullFilename;
}
else
{
@@ -3334,8 +3320,8 @@ namespace renderdocui.Windows.PipelineState
else
shadername = sh.ShaderName;
if (shaderDetails != null && shaderDetails.DebugInfo.entryFunc.Length > 0 && shaderDetails.DebugInfo.files.Length > 0)
shadername = shaderDetails.DebugInfo.entryFunc + "()" + " - " +
if (shaderDetails != null && shaderDetails.DebugInfo.files.Length > 0)
shadername = shaderDetails.EntryPoint + "()" + " - " +
shaderDetails.DebugInfo.files[0].BaseFilename;
writer.WriteStartElement("p");
@@ -512,18 +512,8 @@ namespace renderdocui.Windows.PipelineState
else
shader.Text = state.PipelineName + " - " + stage.stage.Str(GraphicsAPI.D3D12) + " Shader";
if (shaderDetails != null && shaderDetails.DebugInfo.entryFunc.Length > 0 && shaderDetails.DebugInfo.files.Length > 0)
{
string shaderfn = "";
int entryFile = shaderDetails.DebugInfo.entryFile;
if (entryFile < 0 || entryFile >= shaderDetails.DebugInfo.files.Length)
entryFile = 0;
shaderfn = shaderDetails.DebugInfo.files[entryFile].BaseFilename;
shader.Text = shaderDetails.DebugInfo.entryFunc + "()" + " - " + shaderfn;
}
if (shaderDetails != null && shaderDetails.DebugInfo.files.Length > 0)
shader.Text = shaderDetails.EntryPoint + "()" + " - " + shaderDetails.DebugInfo.files[0].BaseFilename;
int vs = 0;
@@ -2047,9 +2037,9 @@ namespace renderdocui.Windows.PipelineState
string mainfile = "";
var files = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
if (shaderDetails.DebugInfo.entryFunc.Length > 0 && shaderDetails.DebugInfo.files.Length > 0)
if (shaderDetails.DebugInfo.files.Length > 0)
{
entryFunc = shaderDetails.DebugInfo.entryFunc;
entryFunc = shaderDetails.EntryPoint;
foreach (var s in shaderDetails.DebugInfo.files)
{
@@ -2059,11 +2049,7 @@ namespace renderdocui.Windows.PipelineState
files.Add(s.FullFilename, s.filetext);
}
int entryFile = shaderDetails.DebugInfo.entryFile;
if (entryFile < 0 || entryFile >= shaderDetails.DebugInfo.files.Length)
entryFile = 0;
mainfile = shaderDetails.DebugInfo.files[entryFile].FullFilename;
mainfile = shaderDetails.DebugInfo.files[0].FullFilename;
}
else
{
@@ -2927,8 +2913,8 @@ namespace renderdocui.Windows.PipelineState
else
shadername = sh.stage.Str(GraphicsAPI.D3D12);
if (shaderDetails != null && shaderDetails.DebugInfo.entryFunc.Length > 0 && shaderDetails.DebugInfo.files.Length > 0)
shadername = shaderDetails.DebugInfo.entryFunc + "()" + " - " +
if (shaderDetails != null && shaderDetails.DebugInfo.files.Length > 0)
shadername = shaderDetails.EntryPoint + "()" + " - " +
shaderDetails.DebugInfo.files[0].BaseFilename;
writer.WriteStartElement("p");
@@ -953,23 +953,13 @@ namespace renderdocui.Windows.PipelineState
else
shader.Text = stage.ShaderName;
if (shaderDetails != null && shaderDetails.DebugInfo.entryFunc.Length > 0)
if (shaderDetails != null)
{
if (shaderDetails.DebugInfo.files.Length > 0 || shaderDetails.DebugInfo.entryFunc != "main")
shader.Text = shaderDetails.DebugInfo.entryFunc + "()";
if (shaderDetails.DebugInfo.files.Length > 0 || shaderDetails.EntryPoint != "main")
shader.Text = shaderDetails.EntryPoint + "()";
if (shaderDetails.DebugInfo.files.Length > 0)
{
string shaderfn = "";
int entryFile = shaderDetails.DebugInfo.entryFile;
if (entryFile < 0 || entryFile >= shaderDetails.DebugInfo.files.Length)
entryFile = 0;
shaderfn = shaderDetails.DebugInfo.files[entryFile].BaseFilename;
shader.Text += " - " + shaderfn;
}
shader.Text += " - " + shaderDetails.DebugInfo.files[0].BaseFilename;
}
int vs = 0;
@@ -2844,8 +2834,8 @@ namespace renderdocui.Windows.PipelineState
else
shadername = sh.ShaderName;
if (shaderDetails != null && shaderDetails.DebugInfo.entryFunc.Length > 0 && shaderDetails.DebugInfo.files.Length > 0)
shadername = shaderDetails.DebugInfo.entryFunc + "()" + " - " +
if (shaderDetails != null && shaderDetails.DebugInfo.files.Length > 0)
shadername = shaderDetails.EntryPoint + "()" + " - " +
shaderDetails.DebugInfo.files[0].BaseFilename;
writer.WriteStartElement("p");
+4 -11
View File
@@ -578,12 +578,12 @@ namespace renderdocui.Windows
w.CloseButtonVisible = false;
}
if (shader != null && shader.DebugInfo.entryFunc.Length > 0 && shader.DebugInfo.files.Length > 0)
if (shader != null && shader.DebugInfo.files.Length > 0)
{
if(trace != null)
Text = String.Format("Debug {0}() - {1}", shader.DebugInfo.entryFunc, debugContext);
Text = String.Format("Debug {0}() - {1}", shader.EntryPoint, debugContext);
else
Text = String.Format("{0}()", shader.DebugInfo.entryFunc);
Text = String.Format("{0}()", shader.EntryPoint);
int fileIdx = 0;
@@ -606,15 +606,8 @@ namespace renderdocui.Windows
m_Scintillas.Add(scintilla1);
if (shader.DebugInfo.entryFile >= 0 && shader.DebugInfo.entryFile < shader.DebugInfo.files.Length)
{
if (fileIdx == shader.DebugInfo.entryFile)
sel = w;
}
else if (f.filetext.Contains(shader.DebugInfo.entryFunc))
{
if (sel == null)
sel = w;
}
fileIdx++;
}