Move DXBC shader friendly naming logic into C++ side code

* This makes more sense and lets us share it between Qt and C# UIs.
This commit is contained in:
baldurk
2017-07-05 20:37:49 +01:00
parent ecf88787d7
commit 79101c7b13
8 changed files with 264 additions and 180 deletions
@@ -234,6 +234,8 @@ bool PersistantConfig::Load(const QString &filename)
SetConfigSetting(key, ConfigSettings[key]);
}
RENDERDOC_SetConfigSetting("Disassembly_FriendlyNaming", ShaderViewer_FriendlyNaming ? "1" : "0");
// localhost should always be available as a remote host
bool foundLocalhost = false;
@@ -262,6 +264,8 @@ bool PersistantConfig::Save()
for(RemoteHost *host : RemoteHosts)
RemoteHostList.push_back(*host);
RENDERDOC_SetConfigSetting("Disassembly_FriendlyNaming", ShaderViewer_FriendlyNaming ? "1" : "0");
return Serialize(m_Filename);
}
+1 -1
View File
@@ -680,7 +680,7 @@ void State::SetDst(const ASMOperand &dstoper, const ASMOperation &op, const Shad
{
RDCERR("Currently unsupported destination operand type %d!", dstoper.type);
string name = dstoper.toString();
string name = dstoper.toString(dxbc, ToString::ShowSwizzle);
for(int32_t i = 0; i < outputs.count; i++)
{
if(outputs[i].name.elems && !strcmp(name.c_str(), outputs[i].name.elems))
@@ -26,6 +26,7 @@
#include "dxbc_disassemble.h"
#include <math.h>
#include "common/common.h"
#include "core/core.h"
#include "serialise/serialiser.h"
#include "serialise/string_utils.h"
#include "dxbc_inspect.h"
@@ -347,6 +348,8 @@ void DXBCFile::DisassembleHexDump()
m_Declarations.reserve(numDecls);
const bool friendly = RenderDoc::Inst().GetConfigSetting("Disassembly_FriendlyNaming") != "0";
while(cur < end)
{
ASMOperation op;
@@ -358,9 +361,9 @@ void DXBCFile::DisassembleHexDump()
decl.offset = offset * sizeof(uint32_t);
op.offset = offset * sizeof(uint32_t);
if(!ExtractOperation(cur, op))
if(!ExtractOperation(cur, op, friendly))
{
if(!ExtractDecl(cur, decl))
if(!ExtractDecl(cur, decl, friendly))
{
RDCERR("Unexpected non-operation and non-decl in token stream at 0x%x", cur - begin);
}
@@ -733,7 +736,7 @@ bool DXBCFile::IsDeclaration(OpcodeType op)
return isDecl;
}
bool DXBCFile::ExtractOperand(uint32_t *&tokenStream, ASMOperand &retOper)
bool DXBCFile::ExtractOperand(uint32_t *&tokenStream, ToString flags, ASMOperand &retOper)
{
uint32_t OperandToken0 = tokenStream[0];
@@ -851,12 +854,12 @@ bool DXBCFile::ExtractOperand(uint32_t *&tokenStream, ASMOperand &retOper)
// relative addressing
retOper.indices[idx].relative = true;
bool ret = ExtractOperand(tokenStream, retOper.indices[idx].operand);
bool ret = ExtractOperand(tokenStream, flags, retOper.indices[idx].operand);
RDCASSERT(ret);
}
if(retOper.indices[idx].relative)
retOper.indices[idx].str = "[" + retOper.indices[idx].operand.toString() + " + ";
retOper.indices[idx].str = "[" + retOper.indices[idx].operand.toString(this, flags) + " + ";
if(retOper.indices[idx].absolute)
{
@@ -893,9 +896,43 @@ bool DXBCFile::ExtractOperand(uint32_t *&tokenStream, ASMOperand &retOper)
return true;
}
string ASMOperand::toString(bool swizzle) const
const CBufferVariable *FindCBufferVar(const uint32_t minOffset, const uint32_t maxOffset,
const std::vector<CBufferVariable> &variables,
uint32_t &byteOffset, std::string &prefix)
{
string str = "";
for(const CBufferVariable &v : variables)
{
// absolute byte offset of this variable in the cbuffer
const uint32_t voffs = byteOffset + v.descriptor.offset;
// does minOffset-maxOffset reside in this variable? We don't handle the case where the range
// crosses a variable (and I don't think FXC emits that anyway).
if(voffs <= minOffset && voffs + v.type.descriptor.bytesize > maxOffset)
{
byteOffset = voffs;
// if it is a struct with members, recurse to find a closer match
if(!v.type.members.empty())
{
prefix += v.name + ".";
return FindCBufferVar(minOffset, maxOffset, v.type.members, byteOffset, prefix);
}
// otherwise return this variable.
return &v;
}
}
return NULL;
}
string ASMOperand::toString(DXBCFile *dxbc, ToString flags) const
{
string str, regstr;
const bool decl = flags & ToString::IsDecl;
const bool swizzle = flags & ToString::ShowSwizzle;
const bool friendly = flags & ToString::FriendlyNameRegisters;
char swiz[6] = {0, 0, 0, 0, 0, 0};
@@ -940,6 +977,26 @@ string ASMOperand::toString(bool swizzle) const
str = "u";
str += indices[0].str;
if(dxbc && friendly && !dxbc->m_GuessedResources && indices[0].absolute)
{
uint32_t idx = (uint32_t)indices[0].index;
for(const ShaderInputBind &b : dxbc->m_Resources)
{
if(b.reg != idx || b.space != 0)
continue;
if((type == TYPE_RESOURCE && b.IsROResource()) || (type == TYPE_SAMPLER && b.IsSampler()) ||
(type == TYPE_UNORDERED_ACCESS_VIEW && b.IsUAV()))
{
if(decl)
regstr = str;
str = b.name;
break;
}
}
}
}
else if(indices.size() == 3)
{
@@ -1070,6 +1127,98 @@ string ASMOperand::toString(bool swizzle) const
str = "cb";
str += StringFormat::Fmt("%s[%s]", indices[0].str.c_str(), indices[1].str.c_str());
if(dxbc && friendly && !dxbc->m_GuessedResources && indices[0].absolute)
{
const CBuffer *cbuffer = NULL;
for(const CBuffer &cb : dxbc->m_CBuffers)
{
if(cb.space == 0 && cb.reg == uint32_t(indices[0].index))
{
cbuffer = &cb;
break;
}
}
if(cbuffer)
{
// if the second index is constant then this is easy enough, we just find the matching
// cbuffer variable and use its name, possibly rebasing the swizzle.
// Unfortunately for many cases it's something like cbX[r0.x + 0] then in the next
// instruction cbX[r0.x + 1] and so on, and it's obvious that it's indexing into the same
// array for subsequent entries. However without knowing r0 we have no way to look up the
// matching variable
if(indices[1].absolute && !indices[1].relative)
{
uint8_t minComp = comps[0];
uint8_t maxComp = comps[0];
for(int i = 1; i < 4; i++)
{
if(comps[i] < 4)
{
minComp = RDCMIN(minComp, comps[i]);
maxComp = RDCMAX(maxComp, comps[i]);
}
}
uint32_t minOffset = uint32_t(indices[1].index) * 16 + minComp * 4;
uint32_t maxOffset = uint32_t(indices[1].index) * 16 + maxComp * 4;
uint32_t baseOffset = 0;
std::string prefix;
const CBufferVariable *var =
FindCBufferVar(minOffset, maxOffset, cbuffer->variables, baseOffset, prefix);
if(var)
{
str = prefix + var->name;
// for indices, look at just which register is selected
minOffset &= ~0xf;
uint32_t varOffset = minOffset - baseOffset;
// if it's an array, add the index based on the relative index to the base offset
if(var->type.descriptor.elements > 1)
{
uint32_t byteSize = var->type.descriptor.bytesize;
// round up the byte size to a the nearest vec4 in case it's not quite a multiple
byteSize = AlignUp16(byteSize);
const uint32_t elementSize = byteSize / var->type.descriptor.elements;
const uint32_t elementIndex = varOffset / elementSize;
str += StringFormat::Fmt("[%u]", elementIndex);
// subtract off so that if there's any further offset, it can be processed
varOffset -= elementIndex;
}
// or if it's a matrix
if((var->type.descriptor.varClass == CLASS_MATRIX_ROWS && var->type.descriptor.cols > 1) ||
(var->type.descriptor.varClass == CLASS_MATRIX_COLUMNS &&
var->type.descriptor.rows > 1))
{
str += StringFormat::Fmt("[%u]", varOffset / 16);
}
// rebase swizzle if necessary
uint32_t vecOffset = (var->descriptor.offset & 0xf);
if(vecOffset > 0)
{
for(int i = 0; i < 4; i++)
{
if(swiz[i + 1])
swiz[i + 1] = compchars[comps[i] - uint8_t(vecOffset / 4)];
}
}
}
}
}
}
}
}
else if(type == TYPE_TEMP || type == TYPE_OUTPUT || type == TYPE_STREAM ||
@@ -1206,14 +1355,20 @@ string ASMOperand::toString(bool swizzle) const
if(modifier == OPERAND_MODIFIER_ABSNEG)
str = "-abs(" + str + ")";
if(decl && !regstr.empty())
str += StringFormat::Fmt(" (%s)", regstr.c_str());
return str;
}
bool DXBCFile::ExtractDecl(uint32_t *&tokenStream, ASMDecl &retDecl)
bool DXBCFile::ExtractDecl(uint32_t *&tokenStream, ASMDecl &retDecl, bool friendlyName)
{
uint32_t *begin = tokenStream;
uint32_t OpcodeToken0 = tokenStream[0];
ToString flags = friendlyName ? ToString::FriendlyNameRegisters : ToString::None;
flags = flags | ToString::IsDecl;
const bool sm51 = (m_Version.Major == 0x5 && m_Version.Minor == 0x1);
OpcodeType op = Opcode::Type.Get(OpcodeToken0);
@@ -1391,11 +1546,11 @@ bool DXBCFile::ExtractDecl(uint32_t *&tokenStream, ASMDecl &retDecl)
{
CBufferAccessPattern accessPattern = Declaration::AccessPattern.Get(OpcodeToken0);
bool ret = ExtractOperand(tokenStream, retDecl.operand);
bool ret = ExtractOperand(tokenStream, flags, retDecl.operand);
RDCASSERT(ret);
retDecl.str += " ";
retDecl.str += retDecl.operand.toString(false);
retDecl.str += retDecl.operand.toString(this, flags);
if(sm51)
{
uint32_t float4size = tokenStream[0];
@@ -1434,10 +1589,10 @@ bool DXBCFile::ExtractDecl(uint32_t *&tokenStream, ASMDecl &retDecl)
{
retDecl.str += " ";
bool ret = ExtractOperand(tokenStream, retDecl.operand);
bool ret = ExtractOperand(tokenStream, flags, retDecl.operand);
RDCASSERT(ret);
retDecl.str += retDecl.operand.toString();
retDecl.str += retDecl.operand.toString(this, flags | ToString::ShowSwizzle);
}
else if(op == OPCODE_DCL_TEMPS)
{
@@ -1473,10 +1628,10 @@ bool DXBCFile::ExtractDecl(uint32_t *&tokenStream, ASMDecl &retDecl)
{
retDecl.str += " ";
bool ret = ExtractOperand(tokenStream, retDecl.operand);
bool ret = ExtractOperand(tokenStream, flags, retDecl.operand);
RDCASSERT(ret);
retDecl.str += retDecl.operand.toString();
retDecl.str += retDecl.operand.toString(this, flags | ToString::ShowSwizzle);
}
else if(op == OPCODE_DCL_MAX_OUTPUT_VERTEX_COUNT)
{
@@ -1494,35 +1649,35 @@ bool DXBCFile::ExtractDecl(uint32_t *&tokenStream, ASMDecl &retDecl)
op == OPCODE_DCL_INPUT_PS_SIV || op == OPCODE_DCL_INPUT_PS_SGV ||
op == OPCODE_DCL_OUTPUT_SIV || op == OPCODE_DCL_OUTPUT_SGV)
{
bool ret = ExtractOperand(tokenStream, retDecl.operand);
bool ret = ExtractOperand(tokenStream, flags, retDecl.operand);
RDCASSERT(ret);
retDecl.systemValue = (SVSemantic)tokenStream[0];
tokenStream++;
retDecl.str += " ";
retDecl.str += retDecl.operand.toString();
retDecl.str += retDecl.operand.toString(this, flags | ToString::ShowSwizzle);
retDecl.str += ", ";
retDecl.str += SystemValueToString(retDecl.systemValue);
}
else if(op == OPCODE_DCL_STREAM)
{
bool ret = ExtractOperand(tokenStream, retDecl.operand);
bool ret = ExtractOperand(tokenStream, flags, retDecl.operand);
RDCASSERT(ret);
retDecl.str += " ";
retDecl.str += retDecl.operand.toString(false);
retDecl.str += retDecl.operand.toString(this, flags);
}
else if(op == OPCODE_DCL_SAMPLER)
{
retDecl.samplerMode = Declaration::SamplerMode.Get(OpcodeToken0);
bool ret = ExtractOperand(tokenStream, retDecl.operand);
bool ret = ExtractOperand(tokenStream, flags, retDecl.operand);
RDCASSERT(ret);
retDecl.str += " ";
retDecl.str += retDecl.operand.toString(false);
retDecl.str += retDecl.operand.toString(this, flags);
retDecl.str += ", ";
if(retDecl.samplerMode == SAMPLER_MODE_DEFAULT)
@@ -1558,7 +1713,7 @@ bool DXBCFile::ExtractDecl(uint32_t *&tokenStream, ASMDecl &retDecl)
retDecl.sampleCount = Declaration::SampleCount.Get(OpcodeToken0);
}
bool ret = ExtractOperand(tokenStream, retDecl.operand);
bool ret = ExtractOperand(tokenStream, flags, retDecl.operand);
RDCASSERT(ret);
uint32_t ResourceReturnTypeToken = tokenStream[0];
@@ -1583,7 +1738,7 @@ bool DXBCFile::ExtractDecl(uint32_t *&tokenStream, ASMDecl &retDecl)
retDecl.str += toString(retDecl.resType[3]);
retDecl.str += ")";
retDecl.str += " " + retDecl.operand.toString(false);
retDecl.str += " " + retDecl.operand.toString(this, flags);
retDecl.space = 0;
@@ -1604,22 +1759,22 @@ bool DXBCFile::ExtractDecl(uint32_t *&tokenStream, ASMDecl &retDecl)
{
retDecl.interpolation = Declaration::InterpolationMode.Get(OpcodeToken0);
bool ret = ExtractOperand(tokenStream, retDecl.operand);
bool ret = ExtractOperand(tokenStream, flags, retDecl.operand);
RDCASSERT(ret);
retDecl.str += " ";
retDecl.str += toString(retDecl.interpolation);
retDecl.str += " ";
retDecl.str += retDecl.operand.toString();
retDecl.str += retDecl.operand.toString(this, flags | ToString::ShowSwizzle);
}
else if(op == OPCODE_DCL_INDEX_RANGE)
{
bool ret = ExtractOperand(tokenStream, retDecl.operand);
bool ret = ExtractOperand(tokenStream, flags, retDecl.operand);
RDCASSERT(ret);
retDecl.str += " ";
retDecl.str += retDecl.operand.toString();
retDecl.str += retDecl.operand.toString(this, flags | ToString::ShowSwizzle);
retDecl.indexRange = tokenStream[0];
tokenStream++;
@@ -1662,13 +1817,13 @@ bool DXBCFile::ExtractDecl(uint32_t *&tokenStream, ASMDecl &retDecl)
{
retDecl.str += " ";
bool ret = ExtractOperand(tokenStream, retDecl.operand);
bool ret = ExtractOperand(tokenStream, flags, retDecl.operand);
RDCASSERT(ret);
retDecl.count = tokenStream[0];
tokenStream++;
retDecl.str += retDecl.operand.toString(false);
retDecl.str += retDecl.operand.toString(this, flags);
retDecl.str += ", ";
char buf[64] = {0};
@@ -1679,7 +1834,7 @@ bool DXBCFile::ExtractDecl(uint32_t *&tokenStream, ASMDecl &retDecl)
{
retDecl.str += " ";
bool ret = ExtractOperand(tokenStream, retDecl.operand);
bool ret = ExtractOperand(tokenStream, flags, retDecl.operand);
RDCASSERT(ret);
retDecl.stride = tokenStream[0];
@@ -1688,7 +1843,7 @@ bool DXBCFile::ExtractDecl(uint32_t *&tokenStream, ASMDecl &retDecl)
retDecl.count = tokenStream[0];
tokenStream++;
retDecl.str += retDecl.operand.toString(false);
retDecl.str += retDecl.operand.toString(this, flags);
retDecl.str += ", ";
char buf[64] = {0};
@@ -1818,10 +1973,10 @@ bool DXBCFile::ExtractDecl(uint32_t *&tokenStream, ASMDecl &retDecl)
retDecl.str += " ";
bool ret = ExtractOperand(tokenStream, retDecl.operand);
bool ret = ExtractOperand(tokenStream, flags, retDecl.operand);
RDCASSERT(ret);
retDecl.str += retDecl.operand.toString(false);
retDecl.str += retDecl.operand.toString(this, flags);
if(retDecl.globallyCoherant)
retDecl.str += ", globallyCoherant";
@@ -1857,13 +2012,13 @@ bool DXBCFile::ExtractDecl(uint32_t *&tokenStream, ASMDecl &retDecl)
retDecl.str += " ";
bool ret = ExtractOperand(tokenStream, retDecl.operand);
bool ret = ExtractOperand(tokenStream, flags, retDecl.operand);
RDCASSERT(ret);
retDecl.stride = tokenStream[0];
tokenStream++;
retDecl.str += retDecl.operand.toString(false);
retDecl.str += retDecl.operand.toString(this, flags);
retDecl.str += ", ";
char buf[64] = {0};
@@ -1908,7 +2063,7 @@ bool DXBCFile::ExtractDecl(uint32_t *&tokenStream, ASMDecl &retDecl)
if(retDecl.globallyCoherant)
retDecl.str += "_glc";
bool ret = ExtractOperand(tokenStream, retDecl.operand);
bool ret = ExtractOperand(tokenStream, flags, retDecl.operand);
RDCASSERT(ret);
uint32_t ResourceReturnTypeToken = tokenStream[0];
@@ -1933,7 +2088,7 @@ bool DXBCFile::ExtractDecl(uint32_t *&tokenStream, ASMDecl &retDecl)
retDecl.str += " ";
retDecl.str += retDecl.operand.toString(false);
retDecl.str += retDecl.operand.toString(this, flags);
if(retDecl.rov)
retDecl.str += ", rasterizerOrderedAccess";
@@ -2068,11 +2223,13 @@ bool DXBCFile::ExtractDecl(uint32_t *&tokenStream, ASMDecl &retDecl)
return true;
}
bool DXBCFile::ExtractOperation(uint32_t *&tokenStream, ASMOperation &retOp)
bool DXBCFile::ExtractOperation(uint32_t *&tokenStream, ASMOperation &retOp, bool friendlyName)
{
uint32_t *begin = tokenStream;
uint32_t OpcodeToken0 = tokenStream[0];
ToString flags = friendlyName ? ToString::FriendlyNameRegisters : ToString::None;
OpcodeType op = Opcode::Type.Get(OpcodeToken0);
RDCASSERT(op < NUM_OPCODES);
@@ -2118,7 +2275,7 @@ bool DXBCFile::ExtractOperation(uint32_t *&tokenStream, ASMOperation &retOp)
for(uint32_t i = 0; i < retOp.operands.size(); i++)
{
bool ret = ExtractOperand(tokenStream, retOp.operands[i]);
bool ret = ExtractOperand(tokenStream, flags, retOp.operands[i]);
RDCASSERT(ret);
}
@@ -2130,7 +2287,7 @@ bool DXBCFile::ExtractOperation(uint32_t *&tokenStream, ASMOperation &retOp)
for(uint32_t i = 0; i < retOp.operands.size(); i++)
{
retOp.str += ", ";
retOp.str += retOp.operands[i].toString();
retOp.str += retOp.operands[i].toString(this, flags | ToString::ShowSwizzle);
}
tokenStream = end;
@@ -2262,7 +2419,7 @@ bool DXBCFile::ExtractOperation(uint32_t *&tokenStream, ASMOperation &retOp)
for(size_t i = 0; i < retOp.operands.size(); i++)
{
bool ret = ExtractOperand(tokenStream, retOp.operands[i]);
bool ret = ExtractOperand(tokenStream, flags, retOp.operands[i]);
RDCASSERT(ret);
}
@@ -2286,7 +2443,7 @@ bool DXBCFile::ExtractOperation(uint32_t *&tokenStream, ASMOperation &retOp)
retOp.str += " ";
else
retOp.str += ", ";
retOp.str += retOp.operands[i].toString();
retOp.str += retOp.operands[i].toString(this, flags | ToString::ShowSwizzle);
}
#if ENABLED(RDOC_DEVEL)
@@ -696,9 +696,29 @@ enum ComponentType
// Main structures
/////////////////////////////////////////////////////////////////////////
class DXBCFile;
struct ASMIndex;
struct ASMDecl;
enum class ToString
{
None = 0x0,
IsDecl = 0x1,
ShowSwizzle = 0x2,
FriendlyNameRegisters = 0x4,
};
constexpr inline ToString operator|(ToString a, ToString b)
{
return ToString(int(a) | int(b));
}
constexpr inline bool operator&(ToString a, ToString b)
{
return (int(a) & int(b)) != 0;
}
struct ASMOperand
{
ASMOperand()
@@ -715,7 +735,7 @@ struct ASMOperand
bool operator==(const ASMOperand &o) const;
string toString(bool swizzle = true) const;
string toString(DXBCFile *dxbc, ToString flags) const;
///////////////////////////////////////
@@ -809,6 +809,8 @@ DXBCFile::DXBCFile(const void *ByteCode, size_t ByteCodeLength)
// get type/version that's used regularly and cheap to fetch
FetchTypeVersion();
m_GuessedResources = false;
// didn't find an rdef means reflection information was stripped.
// Attempt to reverse engineer basic info from declarations
if(!rdefFound)
@@ -817,6 +819,8 @@ DXBCFile::DXBCFile(const void *ByteCode, size_t ByteCodeLength)
DisassembleHexDump();
GuessResources();
m_GuessedResources = true;
}
for(uint32_t chunkIdx = 0; chunkIdx < header->numChunks; chunkIdx++)
+19 -5
View File
@@ -131,6 +131,20 @@ struct ShaderInputBind
TYPE_UAV_RWSTRUCTURED_WITH_COUNTER,
} type;
constexpr bool IsCBuffer() const { return type == TYPE_CBUFFER; }
constexpr bool IsSampler() const { return type == TYPE_SAMPLER; }
constexpr bool IsROResource() const
{
return type == TYPE_TBUFFER || type == TYPE_TEXTURE || type == TYPE_STRUCTURED ||
type == TYPE_BYTEADDRESS;
}
constexpr bool IsUAV() const
{
return type == TYPE_UAV_RWTYPED || type == TYPE_UAV_RWSTRUCTURED ||
type == TYPE_UAV_RWBYTEADDRESS || type == TYPE_UAV_APPEND_STRUCTURED ||
type == TYPE_UAV_CONSUME_STRUCTURED || type == TYPE_UAV_RWSTRUCTURED_WITH_COUNTER;
}
uint32_t space;
uint32_t reg;
uint32_t bindCount;
@@ -344,6 +358,7 @@ public:
vector<uint32_t> m_Immediate;
bool m_GuessedResources;
vector<ShaderInputBind> m_Resources;
vector<CBuffer> m_CBuffers;
@@ -390,11 +405,10 @@ private:
void GuessResources();
// these functions modify tokenStream pointer to point after the item
bool ExtractOperation(
uint32_t *&tokenStream,
ASMOperation &op); // returns false if not an operation (ie. it's a declaration)
bool ExtractDecl(uint32_t *&tokenStream, ASMDecl &decl); // as above
bool ExtractOperand(uint32_t *&tokenStream, ASMOperand &oper);
// ExtractOperation/ExtractDecl returns false if not an operation (ie. it's a declaration)
bool ExtractOperation(uint32_t *&tokenStream, ASMOperation &op, bool friendlyName);
bool ExtractDecl(uint32_t *&tokenStream, ASMDecl &decl, bool friendlyName);
bool ExtractOperand(uint32_t *&tokenStream, ToString flags, ASMOperand &oper);
bool IsDeclaration(OpcodeType op);
+6
View File
@@ -334,6 +334,9 @@ namespace renderdocui.Code
{
if (ReadOnly) return;
StaticExports.SetConfigSetting("Disassembly_FriendlyNaming",
ShaderViewer_FriendlyNaming ? "1" : "0");
try
{
ConfigSettingsValues.Clear();
@@ -365,6 +368,9 @@ namespace renderdocui.Code
PersistantConfig c = (PersistantConfig)xs.Deserialize(reader);
reader.Close();
StaticExports.SetConfigSetting("Disassembly_FriendlyNaming",
c.ShaderViewer_FriendlyNaming ? "1" : "0");
foreach (var kv in c.ConfigSettingsValues)
{
if (kv.Key != null && kv.Key.Length > 0 &&
+11 -132
View File
@@ -60,7 +60,6 @@ namespace renderdocui.Windows
private D3D11PipelineState.ShaderStage m_Stage = null;
private ShaderDebugTrace m_Trace = null;
private ScintillaNET.Scintilla m_DisassemblyView = null;
private string m_DefaultDisasm = "";
private DockContent m_ErrorsDock = null;
private DockContent m_ConstantsDock = null;
@@ -154,70 +153,6 @@ namespace renderdocui.Windows
}
}
private string FriendlyName(string disasm, string stem, string prefix, ShaderConstant[] vars)
{
foreach (var v in vars)
{
if (v.type.descriptor.rows == 0 && v.type.descriptor.cols == 0 && v.type.members.Length > 0)
{
string subPrefix = prefix + v.name + ".";
disasm = FriendlyName(disasm, stem, subPrefix, v.type.members);
}
else if (v.type.descriptor.rows > 0 && v.type.descriptor.cols > 0)
{
uint numRegs = v.type.descriptor.rows * Math.Max(1, v.type.descriptor.elements);
int regSize = (int)v.type.descriptor.cols;
if (!v.type.descriptor.rowMajorStorage && v.type.descriptor.rows > 1 && v.type.descriptor.cols > 1)
{
numRegs = v.type.descriptor.cols;
regSize = (int)v.type.descriptor.rows;
}
for (uint r = 0; r < numRegs; r++)
{
var reg = string.Format("{0}[{1}]", stem, v.reg.vec + r);
int compStart = r == 0 ? (int)v.reg.comp : 0;
int compEnd = compStart + regSize;
var comps = "xyzw".Substring(compStart, compEnd - compStart);
var regexp = string.Format(", (-|abs\\()?{0}\\.([{1}]*)([^xyzw])", Regex.Escape(reg), comps);
var match = Regex.Match(disasm, regexp);
while (match.Success)
{
var swizzle = match.Groups[2].Value.ToCharArray();
for (int c = 0; c < swizzle.Length; c++)
{
int val = "xyzw".IndexOf(swizzle[c]);
swizzle[c] = "xyzw"[val - compStart];
}
var name = numRegs == 1 ? v.name : string.Format("{0}[{1}]", v.name, r);
name = prefix + name;
var replacement = string.Format(", {0}{1}.{2}{3}",
match.Groups[1].Value, name, new string(swizzle), match.Groups[3].Value);
disasm = disasm.Remove(match.Index, match.Length);
disasm = disasm.Insert(match.Index, replacement);
match = Regex.Match(disasm, regexp);
}
}
}
}
return disasm;
}
private List<ScintillaNET.Scintilla> m_Scintillas = new List<ScintillaNET.Scintilla>();
private SaveMethod m_SaveCallback = null;
private CloseMethod m_CloseCallback = null;
@@ -578,56 +513,10 @@ namespace renderdocui.Windows
{
var disasm = replay.DisassembleShader(m_ShaderDetails, "");
if (m_Core.Config.ShaderViewer_FriendlyNaming && m_ShaderDetails != null &&
m_Core.APIProps.pipelineType.IsD3D())
{
for (int i = 0; i < m_ShaderDetails.ConstantBlocks.Length; i++)
{
var cbuf = m_ShaderDetails.ConstantBlocks[i];
var stem = string.Format("cb{0}", cbuf.bindPoint);
if (cbuf.variables.Length == 0)
continue;
disasm = FriendlyName(disasm, stem, "", cbuf.variables);
}
foreach (var r in m_ShaderDetails.ReadOnlyResources)
{
if (r.IsSRV)
{
var needle = string.Format(", t{0}([^0-9])", r.bindPoint);
var replacement = string.Format(", {0}$1", r.name);
Regex rgx = new Regex(needle);
disasm = rgx.Replace(disasm, replacement);
}
if (r.IsSampler)
{
var needle = string.Format(", s{0}([^0-9])", r.bindPoint);
var replacement = string.Format(", {0}$1", r.name);
Regex rgx = new Regex(needle);
disasm = rgx.Replace(disasm, replacement);
}
}
foreach (var r in m_ShaderDetails.ReadWriteResources)
{
var needle = string.Format(", u{0}([^0-9])", r.bindPoint);
var replacement = string.Format(", {0}$1", r.name);
Regex rgx = new Regex(needle);
disasm = rgx.Replace(disasm, replacement);
}
}
m_DefaultDisasm = disasm;
this.BeginInvoke((MethodInvoker)delegate
{
m_DisassemblyView.IsReadOnly = false;
m_DisassemblyView.Text = m_DefaultDisasm;
m_DisassemblyView.Text = disasm;
m_DisassemblyView.UndoRedo.EmptyUndoBuffer();
m_DisassemblyView.IsReadOnly = true;
});
@@ -775,29 +664,19 @@ namespace renderdocui.Windows
if (disasmType == null)
return;
if (disasmType.SelectedIndex == 0 || m_ShaderDetails == null)
string target = disasmType.Items[disasmType.SelectedIndex].ToString();
m_Core.Renderer.BeginInvoke((ReplayRenderer r) =>
{
m_DisassemblyView.IsReadOnly = false;
m_DisassemblyView.Text = m_DefaultDisasm;
m_DisassemblyView.UndoRedo.EmptyUndoBuffer();
m_DisassemblyView.IsReadOnly = true;
}
else
{
string target = disasmType.Items[disasmType.SelectedIndex].ToString();
m_Core.Renderer.BeginInvoke((ReplayRenderer r) =>
{
string disasm = r.DisassembleShader(m_ShaderDetails, target);
string disasm = r.DisassembleShader(m_ShaderDetails, target);
this.BeginInvoke((MethodInvoker)delegate
{
m_DisassemblyView.IsReadOnly = false;
m_DisassemblyView.Text = disasm;
m_DisassemblyView.UndoRedo.EmptyUndoBuffer();
m_DisassemblyView.IsReadOnly = true;
});
this.BeginInvoke((MethodInvoker)delegate
{
m_DisassemblyView.IsReadOnly = false;
m_DisassemblyView.Text = disasm;
m_DisassemblyView.UndoRedo.EmptyUndoBuffer();
m_DisassemblyView.IsReadOnly = true;
});
}
});
}
private ListBox m_FileList = null;