mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-07-31 03:41:01 +00:00
Process cbuffer/structure types with type annotations
This commit is contained in:
@@ -615,7 +615,7 @@ bool D3D11Replay::RenderTextureInternal(TextureDisplay cfg, TexDisplayFlags flag
|
||||
if(var.name == "RENDERDOC_TexDim")
|
||||
{
|
||||
if(var.type.descriptor.rows == 1 && var.type.descriptor.cols == 4 &&
|
||||
var.type.descriptor.type == DXBC::VARTYPE_UINT)
|
||||
var.type.descriptor.varType == VarType::UInt)
|
||||
{
|
||||
uint32_t *d = (uint32_t *)(byteData + var.offset);
|
||||
|
||||
@@ -645,7 +645,7 @@ bool D3D11Replay::RenderTextureInternal(TextureDisplay cfg, TexDisplayFlags flag
|
||||
else if(var.name == "RENDERDOC_SelectedMip")
|
||||
{
|
||||
if(var.type.descriptor.rows == 1 && var.type.descriptor.cols == 1 &&
|
||||
var.type.descriptor.type == DXBC::VARTYPE_UINT)
|
||||
var.type.descriptor.varType == VarType::UInt)
|
||||
{
|
||||
uint32_t *d = (uint32_t *)(byteData + var.offset);
|
||||
|
||||
@@ -660,7 +660,7 @@ bool D3D11Replay::RenderTextureInternal(TextureDisplay cfg, TexDisplayFlags flag
|
||||
else if(var.name == "RENDERDOC_SelectedSliceFace")
|
||||
{
|
||||
if(var.type.descriptor.rows == 1 && var.type.descriptor.cols == 1 &&
|
||||
var.type.descriptor.type == DXBC::VARTYPE_UINT)
|
||||
var.type.descriptor.varType == VarType::UInt)
|
||||
{
|
||||
uint32_t *d = (uint32_t *)(byteData + var.offset);
|
||||
|
||||
@@ -675,7 +675,7 @@ bool D3D11Replay::RenderTextureInternal(TextureDisplay cfg, TexDisplayFlags flag
|
||||
else if(var.name == "RENDERDOC_SelectedSample")
|
||||
{
|
||||
if(var.type.descriptor.rows == 1 && var.type.descriptor.cols == 1 &&
|
||||
var.type.descriptor.type == DXBC::VARTYPE_INT)
|
||||
var.type.descriptor.varType == VarType::SInt)
|
||||
{
|
||||
int32_t *d = (int32_t *)(byteData + var.offset);
|
||||
|
||||
@@ -690,7 +690,7 @@ bool D3D11Replay::RenderTextureInternal(TextureDisplay cfg, TexDisplayFlags flag
|
||||
else if(var.name == "RENDERDOC_TextureType")
|
||||
{
|
||||
if(var.type.descriptor.rows == 1 && var.type.descriptor.cols == 1 &&
|
||||
var.type.descriptor.type == DXBC::VARTYPE_UINT)
|
||||
var.type.descriptor.varType == VarType::UInt)
|
||||
{
|
||||
uint32_t *d = (uint32_t *)(byteData + var.offset);
|
||||
|
||||
|
||||
@@ -542,7 +542,7 @@ bool D3D12Replay::RenderTextureInternal(D3D12_CPU_DESCRIPTOR_HANDLE rtv, Texture
|
||||
if(var.name == "RENDERDOC_TexDim")
|
||||
{
|
||||
if(var.type.descriptor.rows == 1 && var.type.descriptor.cols == 4 &&
|
||||
var.type.descriptor.type == DXBC::VARTYPE_UINT)
|
||||
var.type.descriptor.varType == VarType::UInt)
|
||||
{
|
||||
uint32_t *d = (uint32_t *)(byteData + var.offset);
|
||||
|
||||
@@ -576,7 +576,7 @@ bool D3D12Replay::RenderTextureInternal(D3D12_CPU_DESCRIPTOR_HANDLE rtv, Texture
|
||||
else if(var.name == "RENDERDOC_SelectedMip")
|
||||
{
|
||||
if(var.type.descriptor.rows == 1 && var.type.descriptor.cols == 1 &&
|
||||
var.type.descriptor.type == DXBC::VARTYPE_UINT)
|
||||
var.type.descriptor.varType == VarType::UInt)
|
||||
{
|
||||
uint32_t *d = (uint32_t *)(byteData + var.offset);
|
||||
|
||||
@@ -591,7 +591,7 @@ bool D3D12Replay::RenderTextureInternal(D3D12_CPU_DESCRIPTOR_HANDLE rtv, Texture
|
||||
else if(var.name == "RENDERDOC_SelectedSliceFace")
|
||||
{
|
||||
if(var.type.descriptor.rows == 1 && var.type.descriptor.cols == 1 &&
|
||||
var.type.descriptor.type == DXBC::VARTYPE_UINT)
|
||||
var.type.descriptor.varType == VarType::UInt)
|
||||
{
|
||||
uint32_t *d = (uint32_t *)(byteData + var.offset);
|
||||
|
||||
@@ -606,7 +606,7 @@ bool D3D12Replay::RenderTextureInternal(D3D12_CPU_DESCRIPTOR_HANDLE rtv, Texture
|
||||
else if(var.name == "RENDERDOC_SelectedSample")
|
||||
{
|
||||
if(var.type.descriptor.rows == 1 && var.type.descriptor.cols == 1 &&
|
||||
var.type.descriptor.type == DXBC::VARTYPE_INT)
|
||||
var.type.descriptor.varType == VarType::SInt)
|
||||
{
|
||||
int32_t *d = (int32_t *)(byteData + var.offset);
|
||||
|
||||
@@ -621,7 +621,7 @@ bool D3D12Replay::RenderTextureInternal(D3D12_CPU_DESCRIPTOR_HANDLE rtv, Texture
|
||||
else if(var.name == "RENDERDOC_TextureType")
|
||||
{
|
||||
if(var.type.descriptor.rows == 1 && var.type.descriptor.cols == 1 &&
|
||||
var.type.descriptor.type == DXBC::VARTYPE_UINT)
|
||||
var.type.descriptor.varType == VarType::UInt)
|
||||
{
|
||||
uint32_t *d = (uint32_t *)(byteData + var.offset);
|
||||
|
||||
|
||||
@@ -358,7 +358,7 @@ DXBC::Reflection *Program::GuessReflection()
|
||||
var.name = cb.name;
|
||||
var.offset = 0;
|
||||
var.type.descriptor.varClass = DXBC::VariableClass::CLASS_STRUCT;
|
||||
var.type.descriptor.type = DXBC::VariableType::VARTYPE_VOID;
|
||||
var.type.descriptor.varType = VarType::Unknown;
|
||||
var.type.descriptor.rows = 1;
|
||||
var.type.descriptor.cols = 4;
|
||||
var.type.descriptor.elements = 1;
|
||||
@@ -382,7 +382,7 @@ DXBC::Reflection *Program::GuessReflection()
|
||||
var.type.descriptor.rows = 1;
|
||||
var.type.descriptor.cols = 4;
|
||||
var.type.descriptor.elements = 0;
|
||||
var.type.descriptor.type = DXBC::VARTYPE_FLOAT;
|
||||
var.type.descriptor.varType = VarType::Float;
|
||||
var.type.descriptor.varClass = DXBC::CLASS_VECTOR;
|
||||
var.type.descriptor.name = TypeName(var.type.descriptor);
|
||||
|
||||
|
||||
@@ -279,7 +279,7 @@ struct CBufferVariableType
|
||||
struct Descriptor
|
||||
{
|
||||
VariableClass varClass;
|
||||
VariableType type;
|
||||
VarType varType;
|
||||
uint32_t rows;
|
||||
uint32_t cols;
|
||||
uint32_t elements;
|
||||
|
||||
@@ -265,32 +265,6 @@ static const uint32_t FOURCC_HASH = MAKE_FOURCC('H', 'A', 'S', 'H');
|
||||
static const uint32_t FOURCC_SFI0 = MAKE_FOURCC('S', 'F', 'I', '0');
|
||||
static const uint32_t FOURCC_PSV0 = MAKE_FOURCC('P', 'S', 'V', '0');
|
||||
|
||||
int TypeByteSize(VariableType t)
|
||||
{
|
||||
switch(t)
|
||||
{
|
||||
case VARTYPE_UINT8: return 1;
|
||||
case VARTYPE_BOOL:
|
||||
case VARTYPE_INT:
|
||||
case VARTYPE_FLOAT:
|
||||
case VARTYPE_UINT:
|
||||
return 4;
|
||||
// we pretend for our purposes that the 'min' formats round up to 4 bytes. For any external
|
||||
// interfaces they are treated as regular types, only using lower precision internally.
|
||||
case VARTYPE_MIN8FLOAT:
|
||||
case VARTYPE_MIN10FLOAT:
|
||||
case VARTYPE_MIN16FLOAT:
|
||||
case VARTYPE_MIN12INT:
|
||||
case VARTYPE_MIN16INT:
|
||||
case VARTYPE_MIN16UINT: return 4;
|
||||
case VARTYPE_DOUBLE:
|
||||
return 8;
|
||||
// 'virtual' type. Just return 1
|
||||
case VARTYPE_INTERFACE_POINTER: return 1;
|
||||
default: RDCERR("Trying to take size of undefined type %d", t); return 1;
|
||||
}
|
||||
}
|
||||
|
||||
ShaderBuiltin GetSystemValue(SVSemantic systemValue)
|
||||
{
|
||||
switch(systemValue)
|
||||
@@ -333,22 +307,15 @@ rdcstr TypeName(CBufferVariableType::Descriptor desc)
|
||||
rdcstr ret;
|
||||
|
||||
char *type = "";
|
||||
switch(desc.type)
|
||||
switch(desc.varType)
|
||||
{
|
||||
case VARTYPE_BOOL: type = "bool"; break;
|
||||
case VARTYPE_INT: type = "int"; break;
|
||||
case VARTYPE_FLOAT: type = "float"; break;
|
||||
case VARTYPE_DOUBLE: type = "double"; break;
|
||||
case VARTYPE_UINT: type = "uint"; break;
|
||||
case VARTYPE_UINT8: type = "ubyte"; break;
|
||||
case VARTYPE_VOID: type = "void"; break;
|
||||
case VARTYPE_INTERFACE_POINTER: type = "interface"; break;
|
||||
case VARTYPE_MIN8FLOAT: type = "min8float"; break;
|
||||
case VARTYPE_MIN10FLOAT: type = "min10float"; break;
|
||||
case VARTYPE_MIN16FLOAT: type = "min16float"; break;
|
||||
case VARTYPE_MIN12INT: type = "min12int"; break;
|
||||
case VARTYPE_MIN16INT: type = "min16int"; break;
|
||||
case VARTYPE_MIN16UINT: type = "min16uint"; break;
|
||||
case VarType::Bool: type = "bool"; break;
|
||||
case VarType::SInt: type = "int"; break;
|
||||
case VarType::Float: type = "float"; break;
|
||||
case VarType::Double: type = "double"; break;
|
||||
case VarType::UInt: type = "uint"; break;
|
||||
case VarType::UByte: type = "ubyte"; break;
|
||||
case VarType::Unknown: type = "void"; break;
|
||||
default: RDCERR("Unexpected type in RDEF variable type %d", type);
|
||||
}
|
||||
|
||||
@@ -398,7 +365,23 @@ CBufferVariableType DXBCContainer::ParseRDEFType(const RDEFHeader *h, const byte
|
||||
ret.descriptor.cols = type->cols;
|
||||
ret.descriptor.elements = type->numElems;
|
||||
ret.descriptor.rows = type->rows;
|
||||
ret.descriptor.type = (VariableType)type->varType;
|
||||
|
||||
switch((VariableType)type->varType)
|
||||
{
|
||||
// DXBC treats all cbuffer variables as 32-bit regardless of declaration
|
||||
case DXBC::VARTYPE_MIN12INT:
|
||||
case DXBC::VARTYPE_MIN16INT:
|
||||
case DXBC::VARTYPE_INT: ret.descriptor.varType = VarType::SInt; break;
|
||||
case DXBC::VARTYPE_BOOL: ret.descriptor.varType = VarType::Bool; break;
|
||||
case DXBC::VARTYPE_MIN16UINT:
|
||||
case DXBC::VARTYPE_UINT: ret.descriptor.varType = VarType::UInt; break;
|
||||
case DXBC::VARTYPE_DOUBLE: ret.descriptor.varType = VarType::Double; break;
|
||||
case DXBC::VARTYPE_FLOAT:
|
||||
case DXBC::VARTYPE_MIN8FLOAT:
|
||||
case DXBC::VARTYPE_MIN10FLOAT:
|
||||
case DXBC::VARTYPE_MIN16FLOAT:
|
||||
default: ret.descriptor.varType = VarType::Float; break;
|
||||
}
|
||||
|
||||
ret.descriptor.name = TypeName(ret.descriptor);
|
||||
|
||||
@@ -457,12 +440,12 @@ CBufferVariableType DXBCContainer::ParseRDEFType(const RDEFHeader *h, const byte
|
||||
// the other dimension
|
||||
if(ret.descriptor.varClass == CLASS_MATRIX_COLUMNS)
|
||||
{
|
||||
ret.descriptor.bytesize = TypeByteSize(ret.descriptor.type) * ret.descriptor.cols * 4 *
|
||||
ret.descriptor.bytesize = VarTypeByteSize(ret.descriptor.varType) * ret.descriptor.cols * 4 *
|
||||
RDCMAX(1U, ret.descriptor.elements);
|
||||
}
|
||||
else if(ret.descriptor.varClass == CLASS_MATRIX_ROWS)
|
||||
{
|
||||
ret.descriptor.bytesize = TypeByteSize(ret.descriptor.type) * ret.descriptor.rows * 4 *
|
||||
ret.descriptor.bytesize = VarTypeByteSize(ret.descriptor.varType) * ret.descriptor.rows * 4 *
|
||||
RDCMAX(1U, ret.descriptor.elements);
|
||||
}
|
||||
else
|
||||
@@ -470,10 +453,10 @@ CBufferVariableType DXBCContainer::ParseRDEFType(const RDEFHeader *h, const byte
|
||||
// arrays also take up a full vector for each element
|
||||
if(ret.descriptor.elements > 1)
|
||||
ret.descriptor.bytesize =
|
||||
TypeByteSize(ret.descriptor.type) * 4 * RDCMAX(1U, ret.descriptor.elements);
|
||||
VarTypeByteSize(ret.descriptor.varType) * 4 * RDCMAX(1U, ret.descriptor.elements);
|
||||
else
|
||||
ret.descriptor.bytesize =
|
||||
TypeByteSize(ret.descriptor.type) * ret.descriptor.rows * ret.descriptor.cols;
|
||||
VarTypeByteSize(ret.descriptor.varType) * ret.descriptor.rows * ret.descriptor.cols;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,22 +33,7 @@ static ShaderVariableType MakeShaderVariableType(DXBC::CBufferVariableType type)
|
||||
{
|
||||
ShaderVariableType ret;
|
||||
|
||||
switch(type.descriptor.type)
|
||||
{
|
||||
// D3D treats all cbuffer variables as 32-bit regardless of declaration
|
||||
case DXBC::VARTYPE_MIN12INT:
|
||||
case DXBC::VARTYPE_MIN16INT:
|
||||
case DXBC::VARTYPE_INT: ret.descriptor.type = VarType::SInt; break;
|
||||
case DXBC::VARTYPE_BOOL: ret.descriptor.type = VarType::Bool; break;
|
||||
case DXBC::VARTYPE_MIN16UINT:
|
||||
case DXBC::VARTYPE_UINT: ret.descriptor.type = VarType::UInt; break;
|
||||
case DXBC::VARTYPE_DOUBLE: ret.descriptor.type = VarType::Double; break;
|
||||
case DXBC::VARTYPE_FLOAT:
|
||||
case DXBC::VARTYPE_MIN8FLOAT:
|
||||
case DXBC::VARTYPE_MIN10FLOAT:
|
||||
case DXBC::VARTYPE_MIN16FLOAT:
|
||||
default: ret.descriptor.type = VarType::Float; break;
|
||||
}
|
||||
ret.descriptor.type = type.descriptor.varType;
|
||||
ret.descriptor.rows = (uint8_t)type.descriptor.rows;
|
||||
ret.descriptor.columns = (uint8_t)type.descriptor.cols;
|
||||
ret.descriptor.elements = type.descriptor.elements;
|
||||
|
||||
@@ -118,6 +118,18 @@ enum class SRVUAVTag
|
||||
StructStride = 1,
|
||||
};
|
||||
|
||||
enum class StructMemberAnnotation
|
||||
{
|
||||
SNorm = 0,
|
||||
UNorm = 1,
|
||||
Matrix = 2,
|
||||
CBufferOffset = 3,
|
||||
SemanticString = 4,
|
||||
InterpolationMode = 5,
|
||||
FieldName = 6,
|
||||
CompType = 7,
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
T getival(const Metadata *m)
|
||||
{
|
||||
@@ -283,7 +295,261 @@ struct DXMeta
|
||||
}
|
||||
};
|
||||
|
||||
static DXBC::ShaderInputBind MakeResourceBind(const Metadata *r, const bool srv)
|
||||
struct TypeInfo
|
||||
{
|
||||
struct MemberData
|
||||
{
|
||||
enum Flags : uint8_t
|
||||
{
|
||||
None = 0,
|
||||
UNorm = 0x1,
|
||||
SNorm = 0x2,
|
||||
RowMajor = 0x4,
|
||||
Matrix = 0x8,
|
||||
} flags = None;
|
||||
uint8_t rows = 0, cols = 0;
|
||||
uint32_t offset;
|
||||
rdcstr name;
|
||||
ComponentType type;
|
||||
};
|
||||
|
||||
struct StructData
|
||||
{
|
||||
uint32_t byteSize;
|
||||
rdcarray<MemberData> members;
|
||||
};
|
||||
|
||||
std::map<const Type *, StructData> structData;
|
||||
|
||||
TypeInfo(const Metadata *typeAnnotations)
|
||||
{
|
||||
RDCASSERT(typeAnnotations->children.size() >= 2, typeAnnotations->children.size());
|
||||
const Metadata *structAnnotations = typeAnnotations->children[0];
|
||||
|
||||
RDCASSERTEQUAL(getival<uint32_t>(structAnnotations->children[0]), 0);
|
||||
|
||||
for(size_t c = 1; c < structAnnotations->children.size(); c += 2)
|
||||
{
|
||||
const Type *type = structAnnotations->children[c]->type;
|
||||
const Metadata *structMembers = structAnnotations->children[c + 1];
|
||||
|
||||
RDCASSERT(structMembers->children.size() - 1 >= type->members.size(),
|
||||
structMembers->children.size(), type->members.size());
|
||||
|
||||
StructData &data = structData[type];
|
||||
data.byteSize = getival<uint32_t>(structMembers->children[0]);
|
||||
data.members.resize(type->members.size());
|
||||
|
||||
for(size_t m = 0; m < type->members.size(); m++)
|
||||
{
|
||||
const Metadata *memberIn = structMembers->children[m + 1];
|
||||
MemberData &memberOut = data.members[m];
|
||||
|
||||
for(size_t tag = 0; tag < memberIn->children.size(); tag += 2)
|
||||
{
|
||||
StructMemberAnnotation fieldTag = getival<StructMemberAnnotation>(memberIn->children[tag]);
|
||||
switch(fieldTag)
|
||||
{
|
||||
case StructMemberAnnotation::SNorm:
|
||||
{
|
||||
if(getival<uint32_t>(memberIn->children[tag + 1]) != 0)
|
||||
memberOut.flags = MemberData::Flags(memberOut.flags | MemberData::SNorm);
|
||||
break;
|
||||
}
|
||||
case StructMemberAnnotation::UNorm:
|
||||
{
|
||||
if(getival<uint32_t>(memberIn->children[tag + 1]) != 0)
|
||||
memberOut.flags = MemberData::Flags(memberOut.flags | MemberData::UNorm);
|
||||
break;
|
||||
}
|
||||
case StructMemberAnnotation::Matrix:
|
||||
{
|
||||
const Metadata *matrixData = memberIn->children[tag + 1];
|
||||
memberOut.rows = getival<uint8_t>(matrixData->children[0]);
|
||||
memberOut.cols = getival<uint8_t>(matrixData->children[1]);
|
||||
bool rowmajor = (getival<uint32_t>(matrixData->children[2]) == 1);
|
||||
if(rowmajor)
|
||||
memberOut.flags =
|
||||
MemberData::Flags(memberOut.flags | MemberData::RowMajor | MemberData::Matrix);
|
||||
else
|
||||
memberOut.flags = MemberData::Flags(memberOut.flags | MemberData::Matrix);
|
||||
break;
|
||||
}
|
||||
case StructMemberAnnotation::CBufferOffset:
|
||||
memberOut.offset = getival<uint32_t>(memberIn->children[tag + 1]);
|
||||
break;
|
||||
case StructMemberAnnotation::SemanticString: break;
|
||||
case StructMemberAnnotation::InterpolationMode: break;
|
||||
case StructMemberAnnotation::FieldName:
|
||||
memberOut.name = memberIn->children[tag + 1]->str;
|
||||
break;
|
||||
case StructMemberAnnotation::CompType:
|
||||
memberOut.type = getival<ComponentType>(memberIn->children[tag + 1]);
|
||||
break;
|
||||
default: RDCWARN("Unexpected field tag %u", fieldTag); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static DXBC::CBufferVariableType MakeCBufferVariableType(const TypeInfo &typeInfo, const Type *t)
|
||||
{
|
||||
using namespace DXBC;
|
||||
|
||||
CBufferVariableType ret = {};
|
||||
|
||||
if(t->type == Type::Scalar || t->type == Type::Vector)
|
||||
{
|
||||
ret.descriptor.rows = ret.descriptor.cols = 1;
|
||||
if(t->type == Type::Vector)
|
||||
ret.descriptor.cols = t->elemCount;
|
||||
ret.descriptor.bytesize = (t->bitWidth / 8) * ret.descriptor.cols;
|
||||
ret.descriptor.varClass = CLASS_SCALAR;
|
||||
|
||||
if(t->scalarType == Type::Float)
|
||||
{
|
||||
if(t->bitWidth > 32)
|
||||
ret.descriptor.varType = VarType::Double;
|
||||
else if(t->bitWidth == 16)
|
||||
ret.descriptor.varType = VarType::Half;
|
||||
else
|
||||
ret.descriptor.varType = VarType::Float;
|
||||
}
|
||||
else
|
||||
{
|
||||
// can't distinguish int/uint here, default to signed
|
||||
if(t->bitWidth > 32)
|
||||
ret.descriptor.varType = VarType::SLong;
|
||||
else if(t->bitWidth == 32)
|
||||
ret.descriptor.varType = VarType::SInt;
|
||||
else if(t->bitWidth == 16)
|
||||
ret.descriptor.varType = VarType::SShort;
|
||||
else if(t->bitWidth == 8)
|
||||
ret.descriptor.varType = VarType::SByte;
|
||||
else if(t->bitWidth == 1)
|
||||
ret.descriptor.varType = VarType::Bool;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
else if(t->type == Type::Array)
|
||||
{
|
||||
ret = MakeCBufferVariableType(typeInfo, t->inner);
|
||||
ret.descriptor.elements = t->elemCount;
|
||||
// assume normal D3D array packing with each element on float4 boundary
|
||||
ret.descriptor.bytesize += (t->elemCount - 1) * 16;
|
||||
return ret;
|
||||
}
|
||||
else if(t->type == Type::Struct)
|
||||
{
|
||||
// processing below
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCERR("Unexpected type %u iterating cbuffer variable type %s", t->type, t->name.c_str());
|
||||
return ret;
|
||||
}
|
||||
|
||||
// if there are no members, return straight away
|
||||
if(t->members.empty())
|
||||
return ret;
|
||||
|
||||
auto it = typeInfo.structData.find(t);
|
||||
|
||||
if(it != typeInfo.structData.end())
|
||||
{
|
||||
ret.descriptor.bytesize = it->second.byteSize;
|
||||
ret.descriptor.name = t->name;
|
||||
if(ret.descriptor.name.beginsWith("struct."))
|
||||
ret.descriptor.name.erase(0, 7);
|
||||
if(ret.descriptor.name.beginsWith("class."))
|
||||
ret.descriptor.name.erase(0, 6);
|
||||
ret.descriptor.varType = VarType::Unknown;
|
||||
ret.descriptor.varClass = CLASS_STRUCT;
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCERR("Don't have struct type annotations for %s", t->name.c_str());
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < t->members.size(); i++)
|
||||
{
|
||||
CBufferVariable var;
|
||||
var.type = MakeCBufferVariableType(typeInfo, t->members[i]);
|
||||
if(it != typeInfo.structData.end())
|
||||
{
|
||||
var.name = it->second.members[i].name;
|
||||
var.offset = it->second.members[i].offset;
|
||||
|
||||
if(it->second.members[i].flags & TypeInfo::MemberData::Matrix)
|
||||
{
|
||||
var.type.descriptor.rows = it->second.members[i].rows;
|
||||
var.type.descriptor.cols = it->second.members[i].cols;
|
||||
var.type.descriptor.varClass = (it->second.members[i].flags & TypeInfo::MemberData::RowMajor)
|
||||
? CLASS_MATRIX_ROWS
|
||||
: CLASS_MATRIX_COLUMNS;
|
||||
}
|
||||
|
||||
if(var.type.members.empty() && t->members[i]->type != Type::Struct)
|
||||
{
|
||||
switch(it->second.members[i].type)
|
||||
{
|
||||
case ComponentType::Invalid:
|
||||
var.type.descriptor.varType = VarType::Unknown;
|
||||
RDCERR("Unexpected type in cbuffer annotations");
|
||||
break;
|
||||
case ComponentType::I1: var.type.descriptor.varType = VarType::Bool; break;
|
||||
case ComponentType::I16: var.type.descriptor.varType = VarType::SShort; break;
|
||||
case ComponentType::U16: var.type.descriptor.varType = VarType::UShort; break;
|
||||
case ComponentType::I32: var.type.descriptor.varType = VarType::SInt; break;
|
||||
case ComponentType::U32: var.type.descriptor.varType = VarType::UInt; break;
|
||||
case ComponentType::I64: var.type.descriptor.varType = VarType::SLong; break;
|
||||
case ComponentType::U64: var.type.descriptor.varType = VarType::ULong; break;
|
||||
case ComponentType::F16: var.type.descriptor.varType = VarType::Half; break;
|
||||
case ComponentType::F32: var.type.descriptor.varType = VarType::Float; break;
|
||||
case ComponentType::F64: var.type.descriptor.varType = VarType::Double; break;
|
||||
case ComponentType::SNormF16:
|
||||
var.type.descriptor.varType = VarType::Half;
|
||||
RDCERR("Unexpected type in cbuffer annotations");
|
||||
break;
|
||||
case ComponentType::UNormF16:
|
||||
var.type.descriptor.varType = VarType::Half;
|
||||
RDCERR("Unexpected type in cbuffer annotations");
|
||||
break;
|
||||
case ComponentType::SNormF32:
|
||||
var.type.descriptor.varType = VarType::Float;
|
||||
RDCERR("Unexpected type in cbuffer annotations");
|
||||
break;
|
||||
case ComponentType::UNormF32:
|
||||
var.type.descriptor.varType = VarType::Float;
|
||||
RDCERR("Unexpected type in cbuffer annotations");
|
||||
break;
|
||||
case ComponentType::SNormF64:
|
||||
var.type.descriptor.varType = VarType::Double;
|
||||
RDCERR("Unexpected type in cbuffer annotations");
|
||||
break;
|
||||
case ComponentType::UNormF64:
|
||||
var.type.descriptor.varType = VarType::Double;
|
||||
RDCERR("Unexpected type in cbuffer annotations");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO if we have to handle this case, we should try to calculate the offset
|
||||
var.name = StringFormat::Fmt("_child%zu", i);
|
||||
var.offset = 0;
|
||||
}
|
||||
ret.members.push_back(var);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void AddResourceBind(DXBC::Reflection *refl, const TypeInfo &typeInfo, const Metadata *r,
|
||||
const bool srv)
|
||||
{
|
||||
using namespace DXBC;
|
||||
|
||||
@@ -300,6 +566,7 @@ static DXBC::ShaderInputBind MakeResourceBind(const Metadata *r, const bool srv)
|
||||
bind.numComps = 1;
|
||||
|
||||
const Type *resType = r->children[(size_t)ResField::VarDecl]->type;
|
||||
const Type *baseType = resType;
|
||||
|
||||
// variable should be a pointer to the underlying type
|
||||
RDCASSERT(resType->type == Type::Pointer);
|
||||
@@ -441,7 +708,18 @@ static DXBC::ShaderInputBind MakeResourceBind(const Metadata *r, const bool srv)
|
||||
bind.type = ShaderInputBind::TYPE_UAV_RWSTRUCTURED_WITH_COUNTER;
|
||||
}
|
||||
|
||||
return bind;
|
||||
switch(shape)
|
||||
{
|
||||
case ResShape::StructuredBuffer:
|
||||
case ResShape::StructuredBufferWithCounter:
|
||||
refl->ResourceBinds[bind.name] = MakeCBufferVariableType(typeInfo, baseType->inner);
|
||||
default: break;
|
||||
}
|
||||
|
||||
if(srv)
|
||||
refl->SRVs.push_back(bind);
|
||||
else
|
||||
refl->UAVs.push_back(bind);
|
||||
}
|
||||
|
||||
DXBC::Reflection *Program::GetReflection()
|
||||
@@ -452,6 +730,8 @@ DXBC::Reflection *Program::GetReflection()
|
||||
|
||||
DXMeta dx(m_NamedMeta);
|
||||
|
||||
TypeInfo typeInfo(dx.typeAnnotations);
|
||||
|
||||
if(dx.resources)
|
||||
{
|
||||
RDCASSERTEQUAL(dx.resources->children.size(), 1);
|
||||
@@ -464,7 +744,7 @@ DXBC::Reflection *Program::GetReflection()
|
||||
{
|
||||
for(const Metadata *r : SRVs->children)
|
||||
{
|
||||
refl->SRVs.push_back(MakeResourceBind(r, true));
|
||||
AddResourceBind(refl, typeInfo, r, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -473,7 +753,7 @@ DXBC::Reflection *Program::GetReflection()
|
||||
{
|
||||
for(const Metadata *r : UAVs->children)
|
||||
{
|
||||
refl->UAVs.push_back(MakeResourceBind(r, false));
|
||||
AddResourceBind(refl, typeInfo, r, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -498,10 +778,9 @@ DXBC::Reflection *Program::GetReflection()
|
||||
RDCASSERT(cbufType->type == Type::Pointer);
|
||||
cbufType = cbufType->inner;
|
||||
|
||||
for(const Type *member : cbufType->members)
|
||||
{
|
||||
(void)member;
|
||||
}
|
||||
CBufferVariableType rootType = MakeCBufferVariableType(typeInfo, cbufType);
|
||||
|
||||
bind.variables.swap(rootType.members);
|
||||
|
||||
refl->CBuffers.push_back(bind);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user