Try to generate reasonable reflection from PDB info

* On FXC if the user strips reflection info and uses a separate PDB, that PDB
  does not contain reflection information. Try to re-generate what we can from
  the PDB debug info, which is not perfect but
This commit is contained in:
baldurk
2025-03-13 16:45:53 +00:00
parent 7171eea3f9
commit 9b6f1a5b59
4 changed files with 583 additions and 13 deletions
@@ -518,6 +518,8 @@ public:
virtual bool HasSourceMapping() const = 0;
virtual void GetLocals(const DXBC::DXBCContainer *dxbc, size_t instruction, uintptr_t offset,
rdcarray<SourceVariableMapping> &locals) const = 0;
virtual void FillReflection(DXBC::Reflection &refl) {}
};
rdcstr BasicDemangle(const rdcstr &possiblyMangledName);
@@ -2065,6 +2065,7 @@ DXBCContainer::DXBCContainer(const bytebuf &ByteCode, const rdcstr &debugInfoPat
// if reflection information was stripped (or never emitted with DXIL), attempt to reverse
// engineer basic info from declarations or read it from the DXIL
bool guessedReflection = false;
if(m_Reflection == NULL)
{
// need to disassemble now to guess resources
@@ -2074,6 +2075,7 @@ DXBCContainer::DXBCContainer(const bytebuf &ByteCode, const rdcstr &debugInfoPat
m_Reflection = dxilReflectProgram->BuildReflection();
else
m_Reflection = new Reflection;
guessedReflection = true;
}
if(dxilReflectProgram)
@@ -2353,7 +2355,11 @@ DXBCContainer::DXBCContainer(const bytebuf &ByteCode, const rdcstr &debugInfoPat
}
if(m_DXBCByteCode && m_DebugInfo == NULL && !m_DebugShaderBlob.empty())
{
m_DebugInfo = ProcessPDB(m_DebugShaderBlob.data(), (uint32_t)m_DebugShaderBlob.size());
if(m_DebugInfo && guessedReflection)
m_DebugInfo->FillReflection(*m_Reflection);
}
if(m_DXILByteCode)
m_DebugInfo = m_DXILByteCode;
+538 -12
View File
@@ -53,10 +53,12 @@ struct TypeDesc
VarType baseType;
uint32_t byteSize;
uint16_t vecSize;
uint16_t matSize;
uint16_t matArrayStride : 15;
uint16_t colMajorMatrix : 1;
LEAF_ENUM_e leafType;
rdcarray<TypeMember> members;
CV_builtin_e builtin;
};
bool IsPDBFile(void *data, size_t length)
@@ -73,6 +75,65 @@ bool IsPDBFile(void *data, size_t length)
return true;
}
CBufferVariableType MakeCBufferVariableType(std::map<uint32_t, TypeDesc> &typeInfo,
const TypeDesc &vartype)
{
CBufferVariableType ret = {};
if(!vartype.members.empty())
{
ret.varType = VarType::Unknown;
ret.varClass = CLASS_STRUCT;
ret.elements = 1;
if(vartype.matArrayStride > 0)
ret.elements = vartype.byteSize / (uint32_t)vartype.matArrayStride;
for(const TypeMember &m : vartype.members)
{
ret.members.push_back({});
ret.members.back().type = MakeCBufferVariableType(typeInfo, typeInfo[m.typeIndex]);
ret.members.back().name = m.name;
ret.members.back().offset = m.byteOffset;
}
RecalculateScalarOffsetsSizes(ret);
ret.bytesize = ret.members.back().offset + ret.members.back().type.bytesize;
return ret;
}
ret.bytesize = vartype.byteSize;
ret.varType = vartype.baseType;
ret.rows = vartype.matSize == 0 ? 1 : uint8_t(vartype.matSize);
ret.cols = uint8_t(vartype.vecSize);
ret.elements = 1;
ret.varClass = ret.cols > 1 ? CLASS_VECTOR : CLASS_SCALAR;
// if it's an array or matrix, figure out the index
if(vartype.matArrayStride)
{
if(vartype.colMajorMatrix)
std::swap(ret.rows, ret.cols);
if(vartype.leafType != LF_MATRIX)
ret.elements =
uint8_t((vartype.byteSize + vartype.matArrayStride - 1) / vartype.matArrayStride);
if(vartype.leafType == LF_MATRIX)
{
ret.varClass = vartype.colMajorMatrix ? CLASS_MATRIX_COLUMNS : CLASS_MATRIX_ROWS;
}
else
{
ret.elements = ret.rows;
ret.rows = 1;
}
}
if(VarTypeCompType(ret.varType) != CompType::Typeless)
ret.name = TypeName(ret);
return ret;
}
SPDBChunk::SPDBChunk(byte *data, uint32_t spdblength)
{
m_HasDebugInfo = false;
@@ -273,8 +334,9 @@ SPDBChunk::SPDBChunk(byte *data, uint32_t spdblength)
typeInfo[id] = {
name, typeInfo[vector->elemtype].baseType,
*bytelength, (uint16_t)vector->count,
0, 0,
type, {},
1, 0,
0, type,
{},
};
break;
@@ -291,21 +353,23 @@ SPDBChunk::SPDBChunk(byte *data, uint32_t spdblength)
id, name, matrix->elemtype, matrix->rows, matrix->cols, *bytelength,
matrix->majorStride, matrix->matattr.row_major ? "row" : "column");
uint16_t vecSize = 0, matStride = 0;
uint16_t vecSize = 0, matSize = 0, matStride = 0;
if(matrix->matattr.row_major)
{
vecSize = uint16_t(matrix->cols);
matSize = uint16_t(matrix->rows);
matStride = uint16_t(*bytelength / matrix->rows);
}
else
{
vecSize = uint16_t(matrix->rows);
matSize = uint16_t(matrix->cols);
matStride = uint16_t(*bytelength / matrix->cols);
}
typeInfo[id] = {
name, typeInfo[matrix->elemtype].baseType, *bytelength, vecSize,
name, typeInfo[matrix->elemtype].baseType, *bytelength, vecSize, matSize,
matStride, matrix->matattr.row_major == 0, type, {},
};
@@ -318,6 +382,7 @@ SPDBChunk::SPDBChunk(byte *data, uint32_t spdblength)
// that
const char *hlslTypeName = "";
VarType varType = VarType::Unknown;
switch((CV_builtin_e)hlsl->kind)
{
case CV_BI_HLSL_INTERFACE_POINTER: hlslTypeName = "INTERFACE_POINTER"; break;
@@ -363,8 +428,63 @@ SPDBChunk::SPDBChunk(byte *data, uint32_t spdblength)
default: hlslTypeName = "Unknown type";
}
switch((CV_builtin_e)hlsl->kind)
{
case CV_BI_HLSL_SAMPLER:
case CV_BI_HLSL_SAMPLERCOMPARISON: varType = VarType::Sampler; break;
case CV_BI_HLSL_TEXTURE1D:
case CV_BI_HLSL_TEXTURE1D_ARRAY:
case CV_BI_HLSL_TEXTURE2D:
case CV_BI_HLSL_TEXTURE2D_ARRAY:
case CV_BI_HLSL_TEXTURE3D:
case CV_BI_HLSL_TEXTURECUBE:
case CV_BI_HLSL_TEXTURECUBE_ARRAY:
case CV_BI_HLSL_TEXTURE2DMS:
case CV_BI_HLSL_TEXTURE2DMS_ARRAY:
case CV_BI_HLSL_BUFFER:
case CV_BI_HLSL_BYTEADDRESS_BUFFER:
case CV_BI_HLSL_STRUCTURED_BUFFER: varType = VarType::ReadOnlyResource; break;
case CV_BI_HLSL_RWTEXTURE1D:
case CV_BI_HLSL_RWTEXTURE1D_ARRAY:
case CV_BI_HLSL_RWTEXTURE2D:
case CV_BI_HLSL_RWTEXTURE2D_ARRAY:
case CV_BI_HLSL_RWTEXTURE3D:
case CV_BI_HLSL_RWBUFFER:
case CV_BI_HLSL_RWBYTEADDRESS_BUFFER:
case CV_BI_HLSL_RWSTRUCTURED_BUFFER:
case CV_BI_HLSL_APPEND_STRUCTURED_BUFFER:
case CV_BI_HLSL_CONSUME_STRUCTURED_BUFFER: varType = VarType::ReadWriteResource; break;
case CV_BI_HLSL_MIN8FLOAT:
case CV_BI_HLSL_MIN10FLOAT:
case CV_BI_HLSL_MIN16FLOAT: varType = VarType::Float; break;
case CV_BI_HLSL_MIN12INT:
case CV_BI_HLSL_MIN16INT: varType = VarType::SInt; break;
case CV_BI_HLSL_MIN16UINT: varType = VarType::UInt; break;
default: break;
}
SPDBLOG("Type %x is an hlsl %s[%u] (subtype %x)", id, hlslTypeName, hlsl->numprops,
hlsl->subtype);
if(hlsl->kind == 0x224) // constant buffer CV_BI_HLSL_CONSTANT_BUFFER
{
typeInfo[id] = typeInfo[hlsl->subtype];
}
else
{
typeInfo[id] = {
hlslTypeName,
varType,
0,
1,
1,
1,
0,
(LEAF_ENUM_e)hlsl->subtype,
{},
(CV_builtin_e)hlsl->kind,
};
}
break;
}
case LF_ALIAS:
@@ -382,8 +502,8 @@ SPDBChunk::SPDBChunk(byte *data, uint32_t spdblength)
lfModifierEx *modifier = (lfModifierEx *)leaf;
SPDBLOG("Type %x is %x modified with:", id, modifier->type);
// treat as basically an alias
typeInfo[id] = typeInfo[modifier->type];
typeInfo[id].name = "modif " + typeInfo[id].name;
uint16_t *mods = (uint16_t *)modifier->mods;
for(unsigned short i = 0; i < modifier->count; i++)
@@ -564,7 +684,15 @@ SPDBChunk::SPDBChunk(byte *data, uint32_t spdblength)
structType = "class";
typeInfo[id] = {
name, VarType::Float, *bytelength, 1, 0, 0, type, typeInfo[structure->field].members,
name,
VarType::Float,
*bytelength,
1,
1,
0,
0,
type,
typeInfo[structure->field].members,
};
SPDBLOG(
@@ -616,8 +744,17 @@ SPDBChunk::SPDBChunk(byte *data, uint32_t spdblength)
bytelength);
typeInfo[id] = {
"", typeInfo[stridedArray->elemtype].baseType, bytelength, 1, stride, 0,
type, typeInfo[stridedArray->elemtype].members,
"",
typeInfo[stridedArray->elemtype].baseType,
bytelength,
1,
1,
stride,
0,
LEAF_ENUM_e(VarTypeCompType(typeInfo[stridedArray->elemtype].baseType) == CompType::Typeless
? stridedArray->elemtype
: type),
typeInfo[stridedArray->elemtype].members,
};
break;
@@ -757,6 +894,384 @@ SPDBChunk::SPDBChunk(byte *data, uint32_t spdblength)
RDCASSERT(dbi->sig == 0xffffffff);
RDCASSERT(dbi->ver == 19990903);
// we don't use this lookup, we just process all symbols
#if 0
if(dbi->gssymStream >= 0 && dbi->gssymStream < streams.count())
{
PDBStream &s = streams[dbi->gssymStream];
PageMapping modMapping(pages, header->PageSize, &s.pageIndices[0],
(uint32_t)s.pageIndices.size());
byte *cur = (byte *)modMapping.Data();
HashHeader *hashHead = (HashHeader *)cur;
cur = (byte *)(hashHead + 1);
HashRecord *records = (HashRecord *)cur;
uint32_t numRecords = hashHead->size / sizeof(HashRecord);
for(uint32_t i = 0; i < numRecords; i++)
{
SPDBLOG("global symbol %u at %x", i, records[i].offset - 1);
}
}
if(dbi->pssymStream >= 0 && dbi->pssymStream < streams.count())
{
PDBStream &s = streams[dbi->pssymStream];
PageMapping modMapping(pages, header->PageSize, &s.pageIndices[0],
(uint32_t)s.pageIndices.size());
byte *cur = (byte *)modMapping.Data();
PublicStreamHeader *pubHead = (PublicStreamHeader *)cur;
cur = (byte *)(pubHead + 1);
HashHeader *hashHead = (HashHeader *)cur;
cur = (byte *)(hashHead + 1);
HashRecord *records = (HashRecord *)cur;
uint32_t numRecords = hashHead->size / sizeof(HashRecord);
for(uint32_t i = 0; i < numRecords; i++)
{
SPDBLOG("public symbol %u at %x", i, records[i].offset - 1);
}
}
#endif
if(dbi->symrecStream >= 0 && dbi->symrecStream < streams.count())
{
PDBStream &s = streams[dbi->symrecStream];
PageMapping modMapping(pages, header->PageSize, &s.pageIndices[0],
(uint32_t)s.pageIndices.size());
byte *cur = (byte *)modMapping.Data();
byte *end = cur + s.byteLength;
while(cur < end)
{
uint16_t *sym = (uint16_t *)cur;
uint16_t len = sym[0];
SYM_ENUM_e type = (SYM_ENUM_e)sym[1];
cur += len + sizeof(uint16_t); // len does not include itself
const TypeDesc *vartype = NULL;
DXBCBytecode::OperandType regType = DXBCBytecode::TYPE_TEMP;
uint32_t space = 0, reg = 0, regID = 0;
uint32_t cbufByteOffset = 0;
rdcstr name;
if(type == S_PROCREF)
{
SPDBLOG("Ingoring proc ref, unused");
continue;
}
else if(type == S_GDATA_HLSL)
{
DATASYMHLSL *gdata = (DATASYMHLSL *)sym;
// CV_HLSLREG_e == OperandType
name = (char *)gdata->name;
regType = (DXBCBytecode::OperandType)gdata->regType;
vartype = &typeInfo[gdata->typind];
if(regType == DXBCBytecode::TYPE_RESOURCE)
reg = gdata->texslot;
else if(regType == DXBCBytecode::TYPE_SAMPLER)
reg = gdata->sampslot;
else if(regType == DXBCBytecode::TYPE_UNORDERED_ACCESS_VIEW)
reg = gdata->uavslot;
else
reg = gdata->dataslot;
regID = reg;
cbufByteOffset = gdata->dataoff;
SPDBLOG(
"S_GDATA_HLSL: %s is type %x in register type %s data slot %hu data offset %hu, "
"tex/samp/uav slots %hu/%hu/%hu",
gdata->name, gdata->typind, ToStr(regType).c_str(), gdata->dataslot, gdata->dataoff,
gdata->texslot, gdata->sampslot, gdata->uavslot);
}
else if(type == S_GDATA_HLSL32)
{
DATASYMHLSL32 *gdata = (DATASYMHLSL32 *)sym;
// CV_HLSLREG_e == OperandType
name = (char *)gdata->name;
regType = (DXBCBytecode::OperandType)gdata->regType;
vartype = &typeInfo[gdata->typind];
if(regType == DXBCBytecode::TYPE_RESOURCE)
reg = gdata->texslot;
else if(regType == DXBCBytecode::TYPE_SAMPLER)
reg = gdata->sampslot;
else if(regType == DXBCBytecode::TYPE_UNORDERED_ACCESS_VIEW)
reg = gdata->uavslot;
else
reg = gdata->dataslot;
regID = reg;
cbufByteOffset = gdata->dataoff;
SPDBLOG(
"S_GDATA_HLSL: %s is type %x in register type %s data slot %hu data offset %hu, "
"tex/samp/uav slots %hu/%hu/%hu",
gdata->name, gdata->typind, ToStr(regType).c_str(), gdata->dataslot, gdata->dataoff,
gdata->texslot, gdata->sampslot, gdata->uavslot);
}
else if(type == S_GDATA_HLSL32_EX)
{
DATASYMHLSL32_EX *gdata = (DATASYMHLSL32_EX *)sym;
// CV_HLSLREG_e == OperandType
name = (char *)gdata->name;
regType = (DXBCBytecode::OperandType)gdata->regType;
vartype = &typeInfo[gdata->typind];
space = gdata->bindSpace;
reg = gdata->bindSlot;
regID = gdata->regID;
cbufByteOffset = gdata->dataoff;
SPDBLOG(
"S_GDATA_HLSL: %s is type %x in register type %s regID %u data offs %u space %u "
"register lower %u",
gdata->name, gdata->typind, ToStr(regType).c_str(), gdata->regID, gdata->dataoff,
gdata->bindSpace, gdata->bindSlot);
}
else
{
SPDBLOG("Unexpected type of global symbol %x", type);
continue;
}
if(regType == DXBCBytecode::TYPE_CONSTANT_BUFFER)
{
size_t idx = 0;
for(idx = 0; idx < CBuffers.size(); idx++)
if(CBuffers[idx].reg == reg && CBuffers[idx].space == space)
break;
if(idx == CBuffers.size())
{
CBuffers.push_back({});
CBuffers.back().descriptor.type = CBuffer::Descriptor::TYPE_CBUFFER;
CBuffers.back().descriptor.byteSize = 0;
CBuffers.back().bindCount = 1;
CBuffers.back().hasReflectionData = false;
CBuffers.back().name = StringFormat::Fmt("cbuffer_%u", regID);
CBuffers.back().reg = reg;
CBuffers.back().space = space;
CBuffers.back().identifier = regID;
}
// skip any modifiers or hlsl dummy entries
if(vartype->baseType == VarType::Unknown)
vartype = &typeInfo[vartype->leafType];
CBufferVariable var;
var.name = name;
var.offset = cbufByteOffset;
var.type = MakeCBufferVariableType(typeInfo, *vartype);
CBuffers[idx].variables.push_back(var);
}
else
{
ShaderInputBind desc;
desc.name = name;
desc.type = DXBC::ShaderInputBind::TYPE_TEXTURE;
desc.dimension = DXBC::ShaderInputBind::DIM_TEXTURE2D;
desc.space = space;
desc.reg = reg;
desc.bindCount = 1;
desc.numComps = 4;
if(vartype)
{
// skip any modifier
if(vartype->baseType == VarType::Unknown)
vartype = &typeInfo[vartype->leafType];
// handle resource arrays
if(vartype->builtin == 0)
{
desc.bindCount = vartype->byteSize;
vartype = &typeInfo[vartype->leafType];
}
if(vartype->builtin == 0)
{
RDCERR("Expected HLSL builtin for resource type");
}
else
{
switch(vartype->builtin)
{
case CV_BI_HLSL_SAMPLER:
case CV_BI_HLSL_SAMPLERCOMPARISON:
desc.type = DXBC::ShaderInputBind::TYPE_SAMPLER;
break;
case CV_BI_HLSL_TEXTURE1D:
desc.type = DXBC::ShaderInputBind::TYPE_TEXTURE;
desc.dimension = DXBC::ShaderInputBind::DIM_TEXTURE1D;
break;
case CV_BI_HLSL_TEXTURE1D_ARRAY:
desc.type = DXBC::ShaderInputBind::TYPE_TEXTURE;
desc.dimension = DXBC::ShaderInputBind::DIM_TEXTURE1DARRAY;
break;
case CV_BI_HLSL_TEXTURE2D:
desc.type = DXBC::ShaderInputBind::TYPE_TEXTURE;
desc.dimension = DXBC::ShaderInputBind::DIM_TEXTURE2D;
break;
case CV_BI_HLSL_TEXTURE2D_ARRAY:
desc.type = DXBC::ShaderInputBind::TYPE_TEXTURE;
desc.dimension = DXBC::ShaderInputBind::DIM_TEXTURE2DARRAY;
break;
case CV_BI_HLSL_TEXTURE3D:
desc.type = DXBC::ShaderInputBind::TYPE_TEXTURE;
desc.dimension = DXBC::ShaderInputBind::DIM_TEXTURE3D;
break;
case CV_BI_HLSL_TEXTURECUBE:
desc.type = DXBC::ShaderInputBind::TYPE_TEXTURE;
desc.dimension = DXBC::ShaderInputBind::DIM_TEXTURECUBE;
break;
case CV_BI_HLSL_TEXTURECUBE_ARRAY:
desc.type = DXBC::ShaderInputBind::TYPE_TEXTURE;
desc.dimension = DXBC::ShaderInputBind::DIM_TEXTURECUBEARRAY;
break;
case CV_BI_HLSL_TEXTURE2DMS:
desc.type = DXBC::ShaderInputBind::TYPE_TEXTURE;
desc.dimension = DXBC::ShaderInputBind::DIM_TEXTURE2DMS;
break;
case CV_BI_HLSL_TEXTURE2DMS_ARRAY:
desc.type = DXBC::ShaderInputBind::TYPE_TEXTURE;
desc.dimension = DXBC::ShaderInputBind::DIM_TEXTURE2DMSARRAY;
break;
case CV_BI_HLSL_BUFFER:
desc.type = DXBC::ShaderInputBind::TYPE_TBUFFER;
desc.dimension = DXBC::ShaderInputBind::DIM_BUFFER;
break;
case CV_BI_HLSL_BYTEADDRESS_BUFFER:
desc.type = DXBC::ShaderInputBind::TYPE_BYTEADDRESS;
desc.dimension = DXBC::ShaderInputBind::DIM_BUFFEREX;
break;
case CV_BI_HLSL_STRUCTURED_BUFFER:
desc.type = DXBC::ShaderInputBind::TYPE_STRUCTURED;
desc.dimension = DXBC::ShaderInputBind::DIM_BUFFER;
break;
case CV_BI_HLSL_RWTEXTURE1D:
desc.type = DXBC::ShaderInputBind::TYPE_UAV_RWTYPED;
desc.dimension = DXBC::ShaderInputBind::DIM_TEXTURE1D;
break;
case CV_BI_HLSL_RWTEXTURE1D_ARRAY:
desc.type = DXBC::ShaderInputBind::TYPE_UAV_RWTYPED;
desc.dimension = DXBC::ShaderInputBind::DIM_TEXTURE1DARRAY;
break;
case CV_BI_HLSL_RWTEXTURE2D:
desc.type = DXBC::ShaderInputBind::TYPE_UAV_RWTYPED;
desc.dimension = DXBC::ShaderInputBind::DIM_TEXTURE2D;
break;
case CV_BI_HLSL_RWTEXTURE2D_ARRAY:
desc.type = DXBC::ShaderInputBind::TYPE_UAV_RWTYPED;
desc.dimension = DXBC::ShaderInputBind::DIM_TEXTURE2DARRAY;
break;
case CV_BI_HLSL_RWTEXTURE3D:
desc.type = DXBC::ShaderInputBind::TYPE_UAV_RWTYPED;
desc.dimension = DXBC::ShaderInputBind::DIM_TEXTURE3D;
break;
case CV_BI_HLSL_RWBUFFER:
desc.type = DXBC::ShaderInputBind::TYPE_UAV_RWTYPED;
desc.dimension = DXBC::ShaderInputBind::DIM_BUFFER;
break;
case CV_BI_HLSL_RWBYTEADDRESS_BUFFER:
desc.type = DXBC::ShaderInputBind::TYPE_UAV_RWBYTEADDRESS;
desc.dimension = DXBC::ShaderInputBind::DIM_BUFFEREX;
break;
case CV_BI_HLSL_RWSTRUCTURED_BUFFER:
desc.type = DXBC::ShaderInputBind::TYPE_UAV_RWSTRUCTURED;
desc.dimension = DXBC::ShaderInputBind::DIM_BUFFER;
break;
case CV_BI_HLSL_APPEND_STRUCTURED_BUFFER:
case CV_BI_HLSL_CONSUME_STRUCTURED_BUFFER:
desc.type = DXBC::ShaderInputBind::TYPE_UAV_RWSTRUCTURED_WITH_COUNTER;
desc.dimension = DXBC::ShaderInputBind::DIM_BUFFER;
break;
default:
RDCERR("Unexpected buitin type for reflection resource: %d", vartype->builtin);
break;
}
// for non-samplers, examine the underlying type
if(desc.type != DXBC::ShaderInputBind::TYPE_SAMPLER)
{
vartype = &typeInfo[vartype->leafType];
// skip any modifier/hlsl intermdiary
while(vartype->baseType == VarType::Unknown && vartype->members.empty())
vartype = &typeInfo[vartype->leafType];
ResourceBinds[desc.name] = MakeCBufferVariableType(typeInfo, *vartype);
ResourceBinds[desc.name].name = name;
if(!vartype->members.empty())
desc.retType = DXBC::RETURN_TYPE_MIXED;
else if(VarTypeCompType(vartype->baseType) == CompType::Float)
desc.retType = DXBC::RETURN_TYPE_FLOAT;
else if(VarTypeCompType(vartype->baseType) == CompType::UInt)
desc.retType = DXBC::RETURN_TYPE_UINT;
else if(VarTypeCompType(vartype->baseType) == CompType::SInt)
desc.retType = DXBC::RETURN_TYPE_SINT;
else
desc.retType = DXBC::RETURN_TYPE_MIXED;
if(VarTypeCompType(vartype->baseType) != CompType::Typeless)
desc.numComps = ResourceBinds[desc.name].cols;
}
}
}
if(regType == DXBCBytecode::TYPE_RESOURCE)
{
SRVs.push_back(desc);
}
else if(regType == DXBCBytecode::TYPE_SAMPLER)
{
desc.retType = DXBC::RETURN_TYPE_UNKNOWN;
desc.dimension = DXBC::ShaderInputBind::DIM_UNKNOWN;
desc.numComps = 0;
Samplers.push_back(desc);
}
else if(regType == DXBCBytecode::TYPE_UNORDERED_ACCESS_VIEW)
{
UAVs.push_back(desc);
}
else
{
SPDBLOG("Ignoring global mapped to register %s", ToStr(regType).c_str());
}
}
}
for(size_t idx = 0; idx < CBuffers.size(); idx++)
{
std::sort(
CBuffers[idx].variables.begin(), CBuffers[idx].variables.end(),
[](const CBufferVariable &a, const CBufferVariable &b) { return a.offset < b.offset; });
}
}
byte *cur = (byte *)(dbi + 1);
byte *end = cur + dbi->gpmodiSize;
while(cur < end)
@@ -1053,7 +1568,6 @@ SPDBChunk::SPDBChunk(byte *data, uint32_t spdblength)
Inlinee inlinee;
inlinee.ptr = ptr;
inlinee.parentPtr = inlinesite->pParent;
inlinee.id = inlinesite->inlinee;
@@ -1334,7 +1848,7 @@ SPDBChunk::SPDBChunk(byte *data, uint32_t spdblength)
}
mapping.var.baseType = vartype->baseType;
mapping.var.rows = 1;
mapping.var.rows = uint8_t(vartype->matSize);
mapping.var.columns = uint8_t(vartype->vecSize);
mapping.var.elements = 1;
@@ -1343,8 +1857,9 @@ SPDBChunk::SPDBChunk(byte *data, uint32_t spdblength)
{
// number of rows is the number of vectors in the matrix's total byte size (each vector is
// a row)
mapping.var.rows =
uint8_t((varTypeByteSize + vartype->matArrayStride - 1) / vartype->matArrayStride);
if(mapping.var.rows == 1)
mapping.var.rows =
uint8_t((varTypeByteSize + vartype->matArrayStride - 1) / vartype->matArrayStride);
// unless this is a column major matrix, in which case each vector is a column so swap the
// rows/columns (the number of ROWS is the vector size, when each vector is a column)
@@ -1931,6 +2446,17 @@ void SPDBChunk::GetLocals(const DXBC::DXBCContainer *dxbc, size_t, uintptr_t off
}
}
void SPDBChunk::FillReflection(DXBC::Reflection &refl)
{
for(auto it = ResourceBinds.begin(); it != ResourceBinds.end(); ++it)
refl.ResourceBinds[it->first] = it->second;
refl.SRVs = SRVs;
refl.UAVs = UAVs;
refl.Samplers = Samplers;
refl.CBuffers = CBuffers;
}
void SPDBChunk::UnrollGroupsharedMappings(const std::map<uint32_t, TypeDesc> &typeInfo,
const rdcarray<TypeMember> &members, LocalMapping mapping,
uint32_t &comp)
+37 -1
View File
@@ -175,6 +175,33 @@ struct DBIModule
rdcstr objectName;
};
struct HashHeader
{
uint32_t sig;
uint32_t version;
uint32_t size;
uint32_t numBuckets;
};
struct HashRecord
{
uint32_t offset;
uint32_t cref;
};
struct PublicStreamHeader
{
uint32_t hash;
uint32_t addrMap;
uint32_t numThunks;
uint32_t thunkByteSize;
uint16_t isectThunkTable;
uint16_t pad;
uint32_t offsThunkTable;
uint16_t numSections;
uint16_t pad2;
};
struct CompilandDetails
{
uint8_t Language;
@@ -213,7 +240,6 @@ struct InstructionLocation
struct Inlinee
{
uint32_t id;
uint64_t ptr;
uint64_t parentPtr;
uint32_t fileOffs;
uint32_t baseLineNum;
@@ -283,6 +309,8 @@ public:
void GetLocals(const DXBC::DXBCContainer *dxbc, size_t instruction, uintptr_t offset,
rdcarray<SourceVariableMapping> &locals) const;
void FillReflection(DXBC::Reflection &refl);
private:
void UnrollGroupsharedMappings(const std::map<uint32_t, TypeDesc> &typeInfo,
const rdcarray<TypeMember> &members, LocalMapping mapping,
@@ -307,5 +335,13 @@ private:
std::map<uint32_t, Function> m_Functions;
std::map<uint32_t, InstInfo> m_InstructionInfo;
rdcarray<ShaderInputBind> SRVs;
rdcarray<ShaderInputBind> UAVs;
std::map<rdcstr, CBufferVariableType> ResourceBinds;
rdcarray<ShaderInputBind> Samplers;
rdcarray<CBuffer> CBuffers;
};
};