Add support for SM5.1 bytecode changes - primarily resource arrays

This commit is contained in:
baldurk
2016-10-21 21:44:24 +02:00
parent 7434077718
commit 1c3b4dfc94
7 changed files with 556 additions and 119 deletions
+4 -4
View File
@@ -158,9 +158,9 @@ void MakeShaderReflection(DXBC::DXBCFile *dxbc, ShaderReflection *refl,
create_array_uninit(mapping->ConstantBlocks, numCbuffers);
create_array_uninit(refl->ConstantBlocks, numCbuffers);
for(size_t i = 0, c = 0; i < dxbc->m_CBuffers.size(); i++)
for(size_t i = 0; i < dxbc->m_CBuffers.size(); i++)
{
ConstantBlock &cb = refl->ConstantBlocks[c];
ConstantBlock &cb = refl->ConstantBlocks[i];
if(dxbc->m_CBuffers[i].descriptor.type != DXBC::CBuffer::Descriptor::TYPE_CBUFFER)
continue;
@@ -176,7 +176,7 @@ void MakeShaderReflection(DXBC::DXBCFile *dxbc, ShaderReflection *refl,
map.bind = dxbc->m_CBuffers[i].reg;
map.used = true;
mapping->ConstantBlocks[c] = map;
mapping->ConstantBlocks[i] = map;
create_array_uninit(cb.variables, dxbc->m_CBuffers[i].variables.size());
for(size_t v = 0; v < dxbc->m_CBuffers[i].variables.size(); v++)
@@ -307,7 +307,7 @@ void MakeShaderReflection(DXBC::DXBCFile *dxbc, ShaderReflection *refl,
res.bindPoint = IsReadWrite ? rwidx : roidx;
BindpointMap map;
map.arraySize = 1;
map.arraySize = r.bindCount == 0 ? ~0U : r.bindCount;
map.bindset = r.space;
map.bind = r.reg;
map.used = true;
+2
View File
@@ -93,6 +93,8 @@ D3D12DebugManager::D3D12DebugManager(WrappedID3D12Device *wrapper)
m_WrappedDevice = wrapper;
m_WrappedDevice->InternalRef();
m_TexResource = NULL;
m_width = m_height = 1;
m_BBFmtIdx = BGRA8_BACKBUFFER;
@@ -25,7 +25,8 @@
#include "dxbc_disassemble.h"
#include <math.h>
#include "common/common.h" // only dependencies are RDCASSERT, so this code is easy to detach from RenderDoc
#include "common/common.h"
#include "serialise/serialiser.h"
#include "serialise/string_utils.h"
#include "dxbc_inspect.h"
@@ -136,6 +137,7 @@ static MaskedElement<bool, 0x00008000> SkipOptimisation;
static MaskedElement<bool, 0x00010000> EnableMinPrecision;
static MaskedElement<bool, 0x00020000> EnableD3D11_1DoubleExtensions;
static MaskedElement<bool, 0x00040000> EnableD3D11_1ShaderExtensions;
static MaskedElement<bool, 0x00080000> EnableD3D12AllResourcesBound;
// OPCODE_DCL_CONSTANT_BUFFER
static MaskedElement<CBufferAccessPattern, 0x00000800> AccessPattern;
@@ -175,7 +177,8 @@ static MaskedElement<PrimitiveTopology, 0x0001F800> OutputPrimitiveTopology;
static MaskedElement<TessellatorOutputPrimitive, 0x00003800> OutputPrimitive;
// OPCODE_DCL_UNORDERED_ACCESS_VIEW_TYPED
static MaskedElement<bool, 0x00010000> GloballyCoherant;
static MaskedElement<bool, 0x00010000> GloballyCoherent;
static MaskedElement<bool, 0x00020000> RasterizerOrderedAccess;
// OPCODE_DCL_INTERFACE
static MaskedElement<uint32_t, 0x0000FFFF> TableLength;
@@ -241,6 +244,7 @@ static MaskedElement<bool, 0x80000000> Extended;
// EXTENDED_OPERAND_MODIFIER
static MaskedElement<OperandModifier, 0x00003FC0> Modifier;
static MaskedElement<MinimumPrecision, 0x0001C000> MinPrecision;
static MaskedElement<bool, 0x00020000> NonUniform;
};
string toString(const uint32_t values[], uint32_t numComps);
@@ -304,7 +308,8 @@ void DXBCFile::DisassembleHexDump()
uint32_t *end = &m_HexDump.back();
// check supported types
if(!(m_Version.Major == 0x5 && m_Version.Minor == 0x0) &&
if(!(m_Version.Major == 0x5 && m_Version.Minor == 0x1) &&
!(m_Version.Major == 0x5 && m_Version.Minor == 0x0) &&
!(m_Version.Major == 0x4 && m_Version.Minor == 0x1) &&
!(m_Version.Major == 0x4 && m_Version.Minor == 0x0))
{
@@ -316,6 +321,24 @@ void DXBCFile::DisassembleHexDump()
cur += 2;
// count how many declarations are so we can get the vector statically sized
size_t numDecls = 0;
uint32_t *tmp = cur;
while(tmp < end)
{
uint32_t OpcodeToken0 = tmp[0];
OpcodeType op = Opcode::Type.Get(OpcodeToken0);
if(IsDeclaration(op))
numDecls++;
tmp += Opcode::Length.Get(OpcodeToken0);
}
m_Declarations.reserve(numDecls);
while(cur < end)
{
ASMOperation op;
@@ -344,6 +367,8 @@ void DXBCFile::DisassembleHexDump()
}
}
RDCASSERT(m_Declarations.size() <= numDecls);
ASMOperation implicitRet;
implicitRet.length = 1;
implicitRet.offset = (end - begin) * sizeof(uint32_t);
@@ -840,6 +865,23 @@ bool DXBCFile::ExtractOperand(uint32_t *&tokenStream, ASMOperand &retOper)
RDCASSERT(retOper.indices[idx].relative || retOper.indices[idx].absolute);
}
if(retOper.type == TYPE_RESOURCE || retOper.type == TYPE_SAMPLER ||
retOper.type == TYPE_UNORDERED_ACCESS_VIEW || retOper.type == TYPE_CONSTANT_BUFFER)
{
// try and find a declaration with a matching ID
RDCASSERT(retOper.indices.size() > 0 && retOper.indices[0].absolute);
for(size_t i = 0; i < m_Declarations.size(); i++)
{
// does the ID match, if so, it's our declaration
if(m_Declarations[i].operand.type == retOper.type &&
m_Declarations[i].operand.indices[0] == retOper.indices[0])
{
retOper.declaration = &m_Declarations[i];
break;
}
}
}
return true;
}
@@ -877,40 +919,176 @@ string ASMOperand::toString(bool swizzle) const
StringFormat::snprintf(buf, 63, "[%u]", funcNum);
str += buf;
}
else if(type == TYPE_TEMP || type == TYPE_RESOURCE || type == TYPE_SAMPLER ||
type == TYPE_OUTPUT || type == TYPE_STREAM || type == TYPE_THREAD_GROUP_SHARED_MEMORY ||
type == TYPE_UNORDERED_ACCESS_VIEW || type == TYPE_FUNCTION_BODY)
else if(type == TYPE_RESOURCE || type == TYPE_SAMPLER || type == TYPE_UNORDERED_ACCESS_VIEW)
{
// pre-DX11, just an index
if(indices.size() == 1)
{
if(type == TYPE_RESOURCE)
str = "t";
if(type == TYPE_SAMPLER)
str = "s";
if(type == TYPE_UNORDERED_ACCESS_VIEW)
str = "u";
str += indices[0].str;
}
else if(indices.size() == 3)
{
if(type == TYPE_RESOURCE)
str = "T";
if(type == TYPE_SAMPLER)
str = "S";
if(type == TYPE_UNORDERED_ACCESS_VIEW)
str = "U";
// DX12 declaration
// if declaration pointer is NULL we're printing inside the declaration itself.
// Upper/lower bounds are printed with the space too, but print them here as
// operand indices refer relative to those bounds.
// detect common case of non-arrayed resources and simplify
RDCASSERT(indices[1].absolute && indices[2].absolute);
if(indices[1].index == indices[2].index)
{
str += indices[0].str;
}
else
{
if(indices[2].index == 0xffffffff)
str += StringFormat::Fmt("%s[%s:unbound]", indices[0].str.c_str(), indices[1].str.c_str());
else
str += StringFormat::Fmt("%s[%s:%s]", indices[0].str.c_str(), indices[1].str.c_str(),
indices[2].str.c_str());
}
}
else if(indices.size() == 2)
{
if(type == TYPE_RESOURCE)
str = "T";
if(type == TYPE_SAMPLER)
str = "S";
if(type == TYPE_UNORDERED_ACCESS_VIEW)
str = "U";
// DX12 lookup
// if we have a declaration, see if it's non-arrayed
if(declaration && declaration->operand.indices[1].index == declaration->operand.indices[2].index)
{
// resource index should be equal to the bound
RDCASSERT(indices[1].absolute && indices[1].index == declaration->operand.indices[1].index);
// just include ID
str += indices[0].str;
}
else
{
if(indices[1].relative)
str += StringFormat::Fmt("%s%s", indices[0].str.c_str(), indices[1].str.c_str());
else
str += StringFormat::Fmt("%s[%s]", indices[0].str.c_str(), indices[1].str.c_str());
}
}
else
{
RDCERR("Unexpected dimensions for resource-type operand: %x, %u", type,
(uint32_t)indices.size());
}
}
else if(type == TYPE_CONSTANT_BUFFER)
{
if(indices.size() == 3)
{
str = "CB";
if(declaration)
{
// see if the declaration was non-arrayed
if(declaration->operand.indices[1].index == declaration->operand.indices[2].index)
{
// resource index should be equal to the bound
RDCASSERT(indices[1].absolute && indices[1].index == declaration->operand.indices[1].index);
// just include ID and vector index
if(indices[2].relative)
str += StringFormat::Fmt("%s%s", indices[0].str.c_str(), indices[2].str.c_str());
else
str += StringFormat::Fmt("%s[%s]", indices[0].str.c_str(), indices[2].str.c_str());
}
else
{
str += indices[0].str;
if(indices[1].relative)
str += indices[1].str;
else
str += "[" + indices[1].str + "]";
if(indices[2].relative)
str += indices[1].str;
else
str += "[" + indices[2].str + "]";
}
}
else
{
// if declaration pointer is NULL we're printing inside the declaration itself.
// Because of the operand format, the size of the constant buffer is also in a
// separate DWORD printed elsewhere.
// Upper/lower bounds are printed with the space too, but print them here as
// operand indices refer relative to those bounds.
// detect common case of non-arrayed resources and simplify
RDCASSERT(indices[1].absolute && indices[2].absolute);
if(indices[1].index == indices[2].index)
{
str += indices[0].str;
}
else
{
if(indices[2].index == 0xffffffff)
str +=
StringFormat::Fmt("%s[%s:unbound]", indices[0].str.c_str(), indices[1].str.c_str());
else
str += StringFormat::Fmt("%s[%s:%s]", indices[0].str.c_str(), indices[1].str.c_str(),
indices[2].str.c_str());
}
}
}
else
{
str = "cb";
str += StringFormat::Fmt("%s[%s]", indices[0].str.c_str(), indices[1].str.c_str());
}
}
else if(type == TYPE_TEMP || type == TYPE_OUTPUT || type == TYPE_STREAM ||
type == TYPE_THREAD_GROUP_SHARED_MEMORY || type == TYPE_FUNCTION_BODY)
{
if(type == TYPE_TEMP)
str = "r";
if(type == TYPE_RESOURCE)
str = "t";
if(type == TYPE_SAMPLER)
str = "s";
if(type == TYPE_OUTPUT)
str = "o";
if(type == TYPE_STREAM)
str = "m";
if(type == TYPE_THREAD_GROUP_SHARED_MEMORY)
str = "g";
if(type == TYPE_UNORDERED_ACCESS_VIEW)
str = "u";
if(type == TYPE_FUNCTION_BODY)
str = "fb";
RDCASSERT(indices.size() == 1);
RDCASSERTEQUAL(indices.size(), 1);
str += indices[0].str;
}
else if(type == TYPE_CONSTANT_BUFFER || type == TYPE_IMMEDIATE_CONSTANT_BUFFER ||
type == TYPE_INDEXABLE_TEMP || type == TYPE_INPUT || type == TYPE_INPUT_CONTROL_POINT ||
else if(type == TYPE_IMMEDIATE_CONSTANT_BUFFER || type == TYPE_INDEXABLE_TEMP ||
type == TYPE_INPUT || type == TYPE_INPUT_CONTROL_POINT ||
type == TYPE_INPUT_PATCH_CONSTANT || type == TYPE_THIS_POINTER ||
type == TYPE_OUTPUT_CONTROL_POINT)
{
if(type == TYPE_IMMEDIATE_CONSTANT_BUFFER)
str = "icb";
if(type == TYPE_CONSTANT_BUFFER)
str = "cb";
if(type == TYPE_INDEXABLE_TEMP)
str = "x";
if(type == TYPE_INPUT)
@@ -1028,6 +1206,8 @@ bool DXBCFile::ExtractDecl(uint32_t *&tokenStream, ASMDecl &retDecl)
uint32_t *begin = tokenStream;
uint32_t OpcodeToken0 = tokenStream[0];
const bool sm51 = (m_Version.Major == 0x5 && m_Version.Minor == 0x1);
OpcodeType op = Opcode::Type.Get(OpcodeToken0);
RDCASSERT(op < NUM_OPCODES);
@@ -1130,6 +1310,8 @@ bool DXBCFile::ExtractDecl(uint32_t *&tokenStream, ASMDecl &retDecl)
Declaration::EnableD3D11_1DoubleExtensions.Get(OpcodeToken0);
retDecl.enableD3D11_1ShaderExtensions =
Declaration::EnableD3D11_1ShaderExtensions.Get(OpcodeToken0);
retDecl.enableD3D12AllResourcesBound =
Declaration::EnableD3D12AllResourcesBound.Get(OpcodeToken0);
retDecl.str += " ";
@@ -1161,6 +1343,41 @@ bool DXBCFile::ExtractDecl(uint32_t *&tokenStream, ASMDecl &retDecl)
retDecl.str += "enableRawAndStructuredBuffers";
added = true;
}
if(retDecl.skipOptimisation)
{
if(added)
retDecl.str += ", ";
retDecl.str += "skipOptimisation";
added = true;
}
if(retDecl.enableMinPrecision)
{
if(added)
retDecl.str += ", ";
retDecl.str += "enableMinPrecision";
added = true;
}
if(retDecl.enableD3D11_1DoubleExtensions)
{
if(added)
retDecl.str += ", ";
retDecl.str += "doubleExtensions";
added = true;
}
if(retDecl.enableD3D11_1ShaderExtensions)
{
if(added)
retDecl.str += ", ";
retDecl.str += "shaderExtensions";
added = true;
}
if(retDecl.enableD3D12AllResourcesBound)
{
if(added)
retDecl.str += ", ";
retDecl.str += "d3d12AllResourcesBound";
added = true;
}
}
else if(op == OPCODE_DCL_CONSTANT_BUFFER)
{
@@ -1171,6 +1388,14 @@ bool DXBCFile::ExtractDecl(uint32_t *&tokenStream, ASMDecl &retDecl)
retDecl.str += " ";
retDecl.str += retDecl.operand.toString(false);
if(sm51)
{
uint32_t float4size = tokenStream[0];
tokenStream++;
retDecl.str += StringFormat::Fmt("[%u]", float4size);
}
retDecl.str += ", ";
if(accessPattern == ACCESS_IMMEDIATE_INDEXED)
@@ -1179,6 +1404,23 @@ bool DXBCFile::ExtractDecl(uint32_t *&tokenStream, ASMDecl &retDecl)
retDecl.str += "dynamicIndexed";
else
RDCERR("Unexpected cbuffer access pattern");
retDecl.space = 0;
if(sm51)
{
retDecl.space = tokenStream[0];
tokenStream++;
retDecl.str += StringFormat::Fmt(" space=%u", retDecl.space);
if(retDecl.operand.indices[1].index == retDecl.operand.indices[2].index)
retDecl.str += StringFormat::Fmt(",reg=%u", retDecl.operand.indices[1].index);
else if(retDecl.operand.indices[2].index == 0xffffffff)
retDecl.str += StringFormat::Fmt(",regs=%u:unbound", retDecl.operand.indices[1].index);
else
retDecl.str += StringFormat::Fmt(",regs=%u:%u", retDecl.operand.indices[1].index,
retDecl.operand.indices[2].index);
}
}
else if(op == OPCODE_DCL_INPUT)
{
@@ -1281,6 +1523,21 @@ bool DXBCFile::ExtractDecl(uint32_t *&tokenStream, ASMDecl &retDecl)
retDecl.str += "mode_comparison";
if(retDecl.samplerMode == SAMPLER_MODE_MONO)
retDecl.str += "mode_mono";
retDecl.space = 0;
if(sm51)
{
retDecl.space = tokenStream[0];
tokenStream++;
retDecl.str += StringFormat::Fmt(" space=%u", retDecl.space);
if(retDecl.operand.indices[1].index == retDecl.operand.indices[2].index)
retDecl.str += StringFormat::Fmt(",reg=%u", retDecl.operand.indices[1].index);
else
retDecl.str += StringFormat::Fmt(",regs=%u:%u", retDecl.operand.indices[1].index,
retDecl.operand.indices[2].index);
}
}
else if(op == OPCODE_DCL_RESOURCE)
{
@@ -1319,6 +1576,21 @@ bool DXBCFile::ExtractDecl(uint32_t *&tokenStream, ASMDecl &retDecl)
retDecl.str += ")";
retDecl.str += " " + retDecl.operand.toString(false);
retDecl.space = 0;
if(sm51)
{
retDecl.space = tokenStream[0];
tokenStream++;
retDecl.str += StringFormat::Fmt(" space=%u", retDecl.space);
if(retDecl.operand.indices[1].index == retDecl.operand.indices[2].index)
retDecl.str += StringFormat::Fmt(",reg=%u", retDecl.operand.indices[1].index);
else
retDecl.str += StringFormat::Fmt(",regs=%u:%u", retDecl.operand.indices[1].index,
retDecl.operand.indices[2].index);
}
}
else if(op == OPCODE_DCL_INPUT_PS)
{
@@ -1530,18 +1802,51 @@ bool DXBCFile::ExtractDecl(uint32_t *&tokenStream, ASMDecl &retDecl)
}
else if(op == OPCODE_DCL_UNORDERED_ACCESS_VIEW_RAW || op == OPCODE_DCL_RESOURCE_RAW)
{
retDecl.rov = (op == OPCODE_DCL_UNORDERED_ACCESS_VIEW_RAW) &&
Declaration::RasterizerOrderedAccess.Get(OpcodeToken0);
retDecl.globallyCoherant = (op == OPCODE_DCL_UNORDERED_ACCESS_VIEW_RAW) &
Declaration::GloballyCoherent.Get(OpcodeToken0);
retDecl.str += " ";
bool ret = ExtractOperand(tokenStream, retDecl.operand);
RDCASSERT(ret);
retDecl.str += retDecl.operand.toString(false);
if(retDecl.globallyCoherant)
retDecl.str += ", globallyCoherant";
if(retDecl.rov)
retDecl.str += ", rasterizerOrderedAccess";
retDecl.space = 0;
if(sm51)
{
retDecl.space = tokenStream[0];
tokenStream++;
retDecl.str += StringFormat::Fmt(" space=%u", retDecl.space);
if(retDecl.operand.indices[1].index == retDecl.operand.indices[2].index)
retDecl.str += StringFormat::Fmt(",reg=%u", retDecl.operand.indices[1].index);
else
retDecl.str += StringFormat::Fmt(",regs=%u:%u", retDecl.operand.indices[1].index,
retDecl.operand.indices[2].index);
}
}
else if(op == OPCODE_DCL_UNORDERED_ACCESS_VIEW_STRUCTURED || op == OPCODE_DCL_RESOURCE_STRUCTURED)
{
retDecl.hasCounter = (op == OPCODE_DCL_UNORDERED_ACCESS_VIEW_STRUCTURED) &&
Opcode::HasOrderPreservingCounter.Get(OpcodeToken0);
retDecl.rov = (op == OPCODE_DCL_UNORDERED_ACCESS_VIEW_STRUCTURED) &&
Declaration::RasterizerOrderedAccess.Get(OpcodeToken0);
retDecl.globallyCoherant = (op == OPCODE_DCL_UNORDERED_ACCESS_VIEW_STRUCTURED) &
Declaration::GloballyCoherent.Get(OpcodeToken0);
retDecl.str += " ";
bool ret = ExtractOperand(tokenStream, retDecl.operand);
@@ -1559,12 +1864,35 @@ bool DXBCFile::ExtractDecl(uint32_t *&tokenStream, ASMDecl &retDecl)
if(retDecl.hasCounter)
retDecl.str += ", hasOrderPreservingCounter";
if(retDecl.globallyCoherant)
retDecl.str += ", globallyCoherant";
if(retDecl.rov)
retDecl.str += ", rasterizerOrderedAccess";
retDecl.space = 0;
if(sm51)
{
retDecl.space = tokenStream[0];
tokenStream++;
retDecl.str += StringFormat::Fmt(" space=%u", retDecl.space);
if(retDecl.operand.indices[1].index == retDecl.operand.indices[2].index)
retDecl.str += StringFormat::Fmt(",reg=%u", retDecl.operand.indices[1].index);
else
retDecl.str += StringFormat::Fmt(",regs=%u:%u", retDecl.operand.indices[1].index,
retDecl.operand.indices[2].index);
}
}
else if(op == OPCODE_DCL_UNORDERED_ACCESS_VIEW_TYPED)
{
retDecl.dim = Declaration::ResourceDim.Get(OpcodeToken0);
retDecl.globallyCoherant = Declaration::GloballyCoherant.Get(OpcodeToken0);
retDecl.globallyCoherant = Declaration::GloballyCoherent.Get(OpcodeToken0);
retDecl.rov = Declaration::RasterizerOrderedAccess.Get(OpcodeToken0);
retDecl.str += "_";
retDecl.str += toString(retDecl.dim);
@@ -1598,6 +1926,24 @@ bool DXBCFile::ExtractDecl(uint32_t *&tokenStream, ASMDecl &retDecl)
retDecl.str += " ";
retDecl.str += retDecl.operand.toString(false);
if(retDecl.rov)
retDecl.str += ", rasterizerOrderedAccess";
retDecl.space = 0;
if(sm51)
{
retDecl.space = tokenStream[0];
tokenStream++;
retDecl.str += StringFormat::Fmt(" space=%u", retDecl.space);
if(retDecl.operand.indices[1].index == retDecl.operand.indices[2].index)
retDecl.str += StringFormat::Fmt(",reg=%u", retDecl.operand.indices[1].index);
else
retDecl.str += StringFormat::Fmt(",regs=%u:%u", retDecl.operand.indices[1].index,
retDecl.operand.indices[2].index);
}
}
else if(op == OPCODE_DCL_HS_FORK_PHASE_INSTANCE_COUNT ||
op == OPCODE_DCL_HS_JOIN_PHASE_INSTANCE_COUNT || op == OPCODE_DCL_GS_INSTANCE_COUNT)
@@ -407,6 +407,8 @@ enum OperandType
TYPE_OUTPUT_DEPTH_GREATER_EQUAL,
TYPE_OUTPUT_DEPTH_LESS_EQUAL,
TYPE_CYCLE_COUNTER,
TYPE_OUTPUT_STENCIL_REF,
TYPE_INNER_COVERAGE,
NUM_OPERAND_TYPES,
};
@@ -652,6 +654,7 @@ enum ComponentType
/////////////////////////////////////////////////////////////////////////
struct ASMIndex;
struct ASMDecl;
struct ASMOperand
{
@@ -664,6 +667,7 @@ struct ASMOperand
modifier = OPERAND_MODIFIER_NONE;
precision = PRECISION_DEFAULT;
funcNum = 0;
declaration = NULL;
}
bool operator==(const ASMOperand &o) const;
@@ -691,6 +695,9 @@ struct ASMOperand
// cbuffer member
// 3 is rare but follows the above pattern
// the declaration of the resource in this operand (not always present)
ASMDecl *declaration;
uint32_t values[4]; // if this operand is immediate, the values are here
OperandModifier modifier; // modifier, neg, abs(), -abs() etc. Could potentially be multiple
@@ -808,10 +815,12 @@ struct ASMDecl
bool enableMinPrecision;
bool enableD3D11_1DoubleExtensions;
bool enableD3D11_1ShaderExtensions;
bool enableD3D12AllResourcesBound;
// OPCODE_DCL_UNORDERED_ACCESS_VIEW_STRUCTURED
uint32_t stride;
bool hasCounter;
bool rov;
// OPCODE_DCL_TEMPS, OPCODE_DCL_INDEXABLE_TEMP
uint32_t numTemps;
@@ -827,6 +836,7 @@ struct ASMDecl
uint32_t groupSize[3];
// OPCODE_DCL_RESOURCE
uint32_t space;
ResourceRetType resType[4];
ResourceDimension dim;
uint32_t sampleCount;
+137 -78
View File
@@ -601,7 +601,12 @@ DXBCFile::DXBCFile(const void *ByteCode, size_t ByteCodeLength)
m_Resources.reserve(h->resources.count);
map<string, pair<uint32_t, uint32_t> > cbufferslots;
struct CBufferBind
{
uint32_t reg, space, bindCount;
};
map<string, CBufferBind> cbufferbinds;
uint32_t resourceStride = sizeof(RDEFResource);
@@ -643,10 +648,14 @@ DXBCFile::DXBCFile(const void *ByteCode, size_t ByteCodeLength)
{
string cname = desc.name;
while(cbufferslots.find(cname) != cbufferslots.end())
while(cbufferbinds.find(cname) != cbufferbinds.end())
cname += "_";
cbufferslots[cname] = std::make_pair(desc.space, desc.reg);
CBufferBind cb;
cb.space = desc.space;
cb.reg = desc.reg;
cb.bindCount = desc.bindCount;
cbufferbinds[cname] = cb;
}
m_Resources.push_back(desc);
@@ -658,31 +667,36 @@ DXBCFile::DXBCFile(const void *ByteCode, size_t ByteCodeLength)
// The reason for this is that an array element could refer to an un-used alias in a bind
// point, and an individual non-array resoruce will always refer to the used alias (an
// un-used individual resource will be omitted entirely from the reflection
for(size_t i = 0; i < m_Resources.size();)
//
// Note we preserve the arrays in SM5.1
if(h->targetVersion < 0x501)
{
if(m_Resources[i].bindCount > 1)
for(size_t i = 0; i < m_Resources.size();)
{
ShaderInputBind desc = m_Resources[i];
m_Resources.erase(m_Resources.begin() + i);
string rname = desc.name;
uint32_t arraySize = desc.bindCount;
desc.bindCount = 1;
for(uint32_t a = 0; a < arraySize; a++)
if(m_Resources[i].bindCount > 1)
{
desc.name = StringFormat::Fmt("%s[%u]", rname.c_str(), a);
m_Resources.push_back(desc);
desc.reg++;
ShaderInputBind desc = m_Resources[i];
m_Resources.erase(m_Resources.begin() + i);
string rname = desc.name;
uint32_t arraySize = desc.bindCount;
desc.bindCount = 1;
for(uint32_t a = 0; a < arraySize; a++)
{
desc.name = StringFormat::Fmt("%s[%u]", rname.c_str(), a);
m_Resources.push_back(desc);
desc.reg++;
}
// continue from the i'th element again since
// we just removed it.
continue;
}
// continue from the i'th element again since
// we just removed it.
continue;
i++;
}
i++;
}
set<string> cbuffernames;
@@ -773,8 +787,9 @@ DXBCFile::DXBCFile(const void *ByteCode, size_t ByteCodeLength)
cbuffernames.insert(cname);
cb.space = cbufferslots[cname].first;
cb.reg = cbufferslots[cname].second;
cb.space = cbufferbinds[cname].space;
cb.reg = cbufferbinds[cname].reg;
cb.bindCount = cbufferbinds[cname].bindCount;
if(cb.descriptor.type == CBuffer::Descriptor::TYPE_CBUFFER)
{
@@ -1021,7 +1036,7 @@ void DXBCFile::GuessResources()
ShaderInputBind desc;
RDCASSERT(dcl.operand.type == TYPE_SAMPLER);
RDCASSERT(dcl.operand.indices.size() == 1);
RDCASSERT(dcl.operand.indices.size() == 1 || dcl.operand.indices.size() == 3);
RDCASSERT(dcl.operand.indices[0].absolute);
uint32_t idx = (uint32_t)dcl.operand.indices[0].index;
@@ -1030,7 +1045,7 @@ void DXBCFile::GuessResources()
desc.name = buf;
desc.type = ShaderInputBind::TYPE_SAMPLER;
desc.space = 0;
desc.space = dcl.space;
desc.reg = idx;
desc.bindCount = 1;
desc.flags = dcl.samplerMode == SAMPLER_MODE_COMPARISON ? 2 : 0;
@@ -1038,6 +1053,13 @@ void DXBCFile::GuessResources()
desc.dimension = ShaderInputBind::DIM_UNKNOWN;
desc.numSamples = 0;
if(dcl.operand.indices.size() == 3)
{
desc.bindCount = uint32_t(dcl.operand.indices[2].index - dcl.operand.indices[1].index);
if(dcl.operand.indices[2].index == 0xffffffff)
desc.bindCount = 0;
}
m_Resources.push_back(desc);
break;
@@ -1056,39 +1078,41 @@ void DXBCFile::GuessResources()
desc.name = buf;
desc.type = ShaderInputBind::TYPE_TEXTURE;
desc.space = 0;
desc.space = dcl.space;
desc.reg = idx;
desc.bindCount = 1;
desc.flags = 0;
desc.retType = (ShaderInputBind::RetType)dcl.resType[0];
desc.dimension =
dcl.dim == RESOURCE_DIMENSION_BUFFER
? ShaderInputBind::DIM_BUFFER
: dcl.dim == RESOURCE_DIMENSION_TEXTURE1D
? ShaderInputBind::DIM_TEXTURE1D
: dcl.dim == RESOURCE_DIMENSION_TEXTURE2D
? ShaderInputBind::DIM_TEXTURE2D
: dcl.dim == RESOURCE_DIMENSION_TEXTURE3D
? ShaderInputBind::DIM_TEXTURE3D
: dcl.dim == RESOURCE_DIMENSION_TEXTURECUBE
? ShaderInputBind::DIM_TEXTURECUBE
: dcl.dim == RESOURCE_DIMENSION_TEXTURE1DARRAY
? ShaderInputBind::DIM_TEXTURE1DARRAY
: dcl.dim == RESOURCE_DIMENSION_TEXTURE2DARRAY
? ShaderInputBind::DIM_TEXTURE2DARRAY
: dcl.dim == RESOURCE_DIMENSION_TEXTURECUBEARRAY
? ShaderInputBind::DIM_TEXTURECUBEARRAY
: dcl.dim == RESOURCE_DIMENSION_TEXTURE2DMS
? ShaderInputBind::DIM_TEXTURE2DMS
: dcl.dim == RESOURCE_DIMENSION_TEXTURE2DARRAY
? ShaderInputBind::DIM_TEXTURE2DARRAY
: dcl.dim == RESOURCE_DIMENSION_TEXTURE2DMSARRAY
? ShaderInputBind::DIM_TEXTURE2DMSARRAY
: ShaderInputBind::DIM_UNKNOWN;
switch(dcl.dim)
{
case RESOURCE_DIMENSION_BUFFER: desc.dimension = ShaderInputBind::DIM_BUFFER;
case RESOURCE_DIMENSION_TEXTURE1D: desc.dimension = ShaderInputBind::DIM_TEXTURE1D;
case RESOURCE_DIMENSION_TEXTURE2D: desc.dimension = ShaderInputBind::DIM_TEXTURE2D;
case RESOURCE_DIMENSION_TEXTURE3D: desc.dimension = ShaderInputBind::DIM_TEXTURE3D;
case RESOURCE_DIMENSION_TEXTURECUBE: desc.dimension = ShaderInputBind::DIM_TEXTURECUBE;
case RESOURCE_DIMENSION_TEXTURE1DARRAY:
desc.dimension = ShaderInputBind::DIM_TEXTURE1DARRAY;
case RESOURCE_DIMENSION_TEXTURE2DARRAY:
desc.dimension = ShaderInputBind::DIM_TEXTURE2DARRAY;
case RESOURCE_DIMENSION_TEXTURECUBEARRAY:
desc.dimension = ShaderInputBind::DIM_TEXTURECUBEARRAY;
case RESOURCE_DIMENSION_TEXTURE2DMS: desc.dimension = ShaderInputBind::DIM_TEXTURE2DMS;
case RESOURCE_DIMENSION_TEXTURE2DMSARRAY:
desc.dimension = ShaderInputBind::DIM_TEXTURE2DMSARRAY;
default: desc.dimension = ShaderInputBind::DIM_UNKNOWN; break;
}
desc.numSamples = dcl.sampleCount;
RDCASSERT(desc.dimension != ShaderInputBind::DIM_UNKNOWN);
if(dcl.operand.indices.size() == 3)
{
desc.bindCount = uint32_t(dcl.operand.indices[2].index - dcl.operand.indices[1].index);
if(dcl.operand.indices[2].index == 0xffffffff)
desc.bindCount = 0;
}
m_Resources.push_back(desc);
break;
@@ -1111,7 +1135,7 @@ void DXBCFile::GuessResources()
desc.name = buf;
desc.type = dcl.operand.type == TYPE_RESOURCE ? ShaderInputBind::TYPE_BYTEADDRESS
: ShaderInputBind::TYPE_UAV_RWBYTEADDRESS;
desc.space = 0;
desc.space = dcl.space;
desc.reg = idx;
desc.bindCount = 1;
desc.flags = 0;
@@ -1119,6 +1143,13 @@ void DXBCFile::GuessResources()
desc.dimension = ShaderInputBind::DIM_BUFFER;
desc.numSamples = 0;
if(dcl.operand.indices.size() == 3)
{
desc.bindCount = uint32_t(dcl.operand.indices[2].index - dcl.operand.indices[1].index);
if(dcl.operand.indices[2].index == 0xffffffff)
desc.bindCount = 0;
}
m_Resources.push_back(desc);
break;
@@ -1137,7 +1168,7 @@ void DXBCFile::GuessResources()
desc.name = buf;
desc.type = ShaderInputBind::TYPE_STRUCTURED;
desc.space = 0;
desc.space = dcl.space;
desc.reg = idx;
desc.bindCount = 1;
desc.flags = 0;
@@ -1145,6 +1176,13 @@ void DXBCFile::GuessResources()
desc.dimension = ShaderInputBind::DIM_BUFFER;
desc.numSamples = dcl.stride;
if(dcl.operand.indices.size() == 3)
{
desc.bindCount = uint32_t(dcl.operand.indices[2].index - dcl.operand.indices[1].index);
if(dcl.operand.indices[2].index == 0xffffffff)
desc.bindCount = 0;
}
m_Resources.push_back(desc);
break;
@@ -1167,7 +1205,7 @@ void DXBCFile::GuessResources()
// rwstructured
if(dcl.hasCounter)
desc.type = ShaderInputBind::TYPE_UAV_RWSTRUCTURED_WITH_COUNTER;
desc.space = 0;
desc.space = dcl.space;
desc.reg = idx;
desc.bindCount = 1;
desc.flags = 0;
@@ -1175,6 +1213,13 @@ void DXBCFile::GuessResources()
desc.dimension = ShaderInputBind::DIM_BUFFER;
desc.numSamples = dcl.stride;
if(dcl.operand.indices.size() == 3)
{
desc.bindCount = uint32_t(dcl.operand.indices[2].index - dcl.operand.indices[1].index);
if(dcl.operand.indices[2].index == 0xffffffff)
desc.bindCount = 0;
}
m_Resources.push_back(desc);
break;
@@ -1193,33 +1238,39 @@ void DXBCFile::GuessResources()
desc.name = buf;
desc.type = ShaderInputBind::TYPE_UAV_RWTYPED;
desc.space = 0;
desc.space = dcl.space;
desc.reg = idx;
desc.bindCount = 1;
desc.flags = 0;
desc.retType = (ShaderInputBind::RetType) int(dcl.resType[0]); // enums match
desc.dimension =
dcl.dim == RESOURCE_DIMENSION_TEXTURE1D
? ShaderInputBind::DIM_TEXTURE1D
: dcl.dim == RESOURCE_DIMENSION_TEXTURE2D
? ShaderInputBind::DIM_TEXTURE2D
: dcl.dim == RESOURCE_DIMENSION_TEXTURE3D
? ShaderInputBind::DIM_TEXTURE3D
: dcl.dim == RESOURCE_DIMENSION_TEXTURECUBE
? ShaderInputBind::DIM_TEXTURECUBE
: dcl.dim == RESOURCE_DIMENSION_TEXTURE1DARRAY
? ShaderInputBind::DIM_TEXTURE1DARRAY
: dcl.dim == RESOURCE_DIMENSION_TEXTURE2DARRAY
? ShaderInputBind::DIM_TEXTURE2DARRAY
: dcl.dim == RESOURCE_DIMENSION_TEXTURECUBEARRAY
? ShaderInputBind::DIM_TEXTURECUBEARRAY
: dcl.dim == RESOURCE_DIMENSION_TEXTURE2DMS
? ShaderInputBind::DIM_TEXTURE2DMS
: dcl.dim == RESOURCE_DIMENSION_TEXTURE2DARRAY
? ShaderInputBind::DIM_TEXTURE2DARRAY
: ShaderInputBind::DIM_UNKNOWN;
switch(dcl.dim)
{
case RESOURCE_DIMENSION_BUFFER: desc.dimension = ShaderInputBind::DIM_BUFFER;
case RESOURCE_DIMENSION_TEXTURE1D: desc.dimension = ShaderInputBind::DIM_TEXTURE1D;
case RESOURCE_DIMENSION_TEXTURE2D: desc.dimension = ShaderInputBind::DIM_TEXTURE2D;
case RESOURCE_DIMENSION_TEXTURE3D: desc.dimension = ShaderInputBind::DIM_TEXTURE3D;
case RESOURCE_DIMENSION_TEXTURECUBE: desc.dimension = ShaderInputBind::DIM_TEXTURECUBE;
case RESOURCE_DIMENSION_TEXTURE1DARRAY:
desc.dimension = ShaderInputBind::DIM_TEXTURE1DARRAY;
case RESOURCE_DIMENSION_TEXTURE2DARRAY:
desc.dimension = ShaderInputBind::DIM_TEXTURE2DARRAY;
case RESOURCE_DIMENSION_TEXTURECUBEARRAY:
desc.dimension = ShaderInputBind::DIM_TEXTURECUBEARRAY;
case RESOURCE_DIMENSION_TEXTURE2DMS: desc.dimension = ShaderInputBind::DIM_TEXTURE2DMS;
case RESOURCE_DIMENSION_TEXTURE2DMSARRAY:
desc.dimension = ShaderInputBind::DIM_TEXTURE2DMSARRAY;
default: desc.dimension = ShaderInputBind::DIM_UNKNOWN; break;
}
desc.numSamples = (uint32_t)-1;
if(dcl.operand.indices.size() == 3)
{
desc.bindCount = uint32_t(dcl.operand.indices[2].index - dcl.operand.indices[1].index);
if(dcl.operand.indices[2].index == 0xffffffff)
desc.bindCount = 0;
}
m_Resources.push_back(desc);
break;
@@ -1239,7 +1290,7 @@ void DXBCFile::GuessResources()
desc.name = buf;
desc.type = ShaderInputBind::TYPE_CBUFFER;
desc.space = 0;
desc.space = dcl.space;
desc.reg = idx;
desc.bindCount = 1;
desc.flags = 1;
@@ -1247,14 +1298,22 @@ void DXBCFile::GuessResources()
desc.dimension = ShaderInputBind::DIM_UNKNOWN;
desc.numSamples = 0;
m_Resources.push_back(desc);
if(dcl.operand.indices.size() == 3)
{
desc.bindCount = uint32_t(dcl.operand.indices[2].index - dcl.operand.indices[1].index);
if(dcl.operand.indices[2].index == 0xffffffff)
desc.bindCount = 0;
}
CBuffer cb;
m_Resources.push_back(desc);
cb.name = desc.name;
cb.space = 0;
cb.space = dcl.space;
cb.reg = idx;
cb.bindCount = desc.bindCount;
cb.descriptor.name = cb.name;
cb.descriptor.byteSize = numVecs * 4 * sizeof(float);
@@ -286,6 +286,7 @@ struct CBuffer
uint32_t space;
uint32_t reg;
uint32_t bindCount;
struct Descriptor
{
@@ -342,7 +342,14 @@ namespace renderdocui.Windows.PipelineState
var b = binds[i];
var res = resources[i];
if (b.bindset == space && b.bind == reg && !res.IsSampler)
bool regMatch = b.bind == reg;
// handle unbounded arrays specially. It's illegal to have an unbounded array with
// anything after it
if (b.bind <= reg)
regMatch = (b.arraySize == UInt32.MaxValue) || (b.bind + b.arraySize > reg);
if (b.bindset == space && regMatch && !res.IsSampler)
{
bind = b;
shaderInput = res;
@@ -351,6 +358,8 @@ namespace renderdocui.Windows.PipelineState
}
}
TreelistView.NodeCollection parent = list.Nodes;
string rootel = r.Immediate ? String.Format("#{0} Direct", r.RootElement) : rootel = String.Format("#{0} Table[{1}]", r.RootElement, r.TableIndex);
bool filledSlot = r.Resource != ResourceId.Null;
@@ -426,21 +435,22 @@ namespace renderdocui.Windows.PipelineState
if (bufs[t].ID == r.Resource)
{
w = bufs[t].length;
h = 0;
d = 0;
a = 0;
h = 1;
d = 1;
a = 1;
format = "";
name = bufs[t].name;
typename = "RWBuffer";
typename = uav ? "RWBuffer" : "Buffer";
if (r.BufferFlags.HasFlag(D3DBufferViewFlags.Raw))
{
typename = "RWByteAddressBuffer";
typename = uav ? "RWByteAddressBuffer" : "ByteAddressBuffer";
}
else if (r.ElementSize > 0)
{
// for structured buffers, display how many 'elements' there are in the buffer
typename = "RWStructuredBuffer[" + (bufs[t].length / r.ElementSize) + "]";
typename = (uav ? "RWStructuredBuffer" : "StructuredBuffer");
a = (uint)(bufs[t].length / r.ElementSize);
}
if (r.CounterResource != ResourceId.Null)
@@ -451,17 +461,12 @@ namespace renderdocui.Windows.PipelineState
// get the buffer type, whether it's just a basic type or a complex struct
if (shaderInput != null && !shaderInput.IsTexture)
{
if (r.Format.compType == FormatComponentType.None)
{
if (shaderInput.variableType.members.Length > 0)
format = "struct " + shaderInput.variableType.Name;
else
format = shaderInput.variableType.Name;
}
if (shaderInput.variableType.members.Length > 0)
format = "struct " + shaderInput.variableType.Name;
else if (r.Format.compType == FormatComponentType.None)
format = shaderInput.variableType.Name;
else
{
format = r.Format.ToString();
}
}
tag = new ViewBufTag(r, bufs[t], true, shaderInput);
@@ -472,7 +477,7 @@ namespace renderdocui.Windows.PipelineState
}
}
var node = list.Nodes.Add(new object[] { rootel, space, regname, name, typename, w, h, d, a, format });
var node = parent.Add(new object[] { rootel, space, regname, name, typename, w, h, d, a, format });
node.Image = global::renderdocui.Properties.Resources.action;
node.HoverImage = global::renderdocui.Properties.Resources.action_hover;
@@ -573,7 +578,14 @@ namespace renderdocui.Windows.PipelineState
var b = stage.BindpointMapping.ReadOnlyResources[i];
var res = stage.ShaderDetails.ReadOnlyResources[i];
if (b.bindset == space && b.bind == reg && res.IsSampler)
bool regMatch = b.bind == reg;
// handle unbounded arrays specially. It's illegal to have an unbounded array with
// anything after it
if (b.bind <= reg)
regMatch = (b.arraySize == UInt32.MaxValue) || (b.bind + b.arraySize > reg);
if (b.bindset == space && regMatch && res.IsSampler)
{
bind = b;
shaderInput = res;
@@ -702,7 +714,14 @@ namespace renderdocui.Windows.PipelineState
var bd = stage.BindpointMapping.ConstantBlocks[i];
var res = stage.ShaderDetails.ConstantBlocks[i];
if (bd.bindset == space && bd.bind == reg)
bool regMatch = bd.bind == reg;
// handle unbounded arrays specially. It's illegal to have an unbounded array with
// anything after it
if (bd.bind <= reg)
regMatch = (bd.arraySize == UInt32.MaxValue) || (bd.bind + bd.arraySize > reg);
if (bd.bindset == space && regMatch)
{
bind = bd;
shaderCBuf = res;