Start adding reflection based on the metadata

This commit is contained in:
baldurk
2020-06-16 14:46:56 +01:00
parent 2f10c52b0c
commit b4ae6c4b10
+181 -12
View File
@@ -36,6 +36,42 @@ enum class ShaderTag
Compute = 4,
};
enum class ResField
{
ID = 0,
VarDecl = 1,
Name = 2,
Space = 3,
RegBase = 4,
RegCount = 5,
// SRV
SRVShape = 6,
SRVSampleCount = 7,
SRVTags = 8,
// UAV
UAVShape = 6,
UAVGloballyCoherent = 7,
UAVHiddenCounter = 8,
UAVRasterOrder = 9,
UAVTags = 10,
// CBuffer
CBufferByteSize = 6,
CBufferTags = 7,
// Sampler
SamplerType = 6,
SamplerTags = 7,
};
template <typename T>
T getival(const Metadata *m)
{
return T(m->val->val.uv[0]);
}
void Program::FetchComputeProperties(DXBC::Reflection *reflection)
{
for(const Function &f : m_Functions)
@@ -92,13 +128,13 @@ void Program::FetchComputeProperties(DXBC::Reflection *reflection)
for(size_t t = 0; t < tags.children.size(); t += 2)
{
RDCASSERT(tags.children[t]->value);
if(ShaderTag(tags.children[t]->val->val.uv[0]) == ShaderTag::Compute)
if(getival<ShaderTag>(tags.children[t]) == ShaderTag::Compute)
{
Metadata &threadDim = *tags.children[t + 1];
RDCASSERTEQUAL(threadDim.children.size(), 3);
reflection->DispatchThreadsDimension[0] = threadDim.children[0]->val->val.uv[0];
reflection->DispatchThreadsDimension[1] = threadDim.children[1]->val->val.uv[0];
reflection->DispatchThreadsDimension[2] = threadDim.children[2]->val->val.uv[0];
reflection->DispatchThreadsDimension[0] = getival<uint32_t>(threadDim.children[0]);
reflection->DispatchThreadsDimension[1] = getival<uint32_t>(threadDim.children[1]);
reflection->DispatchThreadsDimension[2] = getival<uint32_t>(threadDim.children[2]);
return;
}
}
@@ -114,12 +150,6 @@ void Program::FetchComputeProperties(DXBC::Reflection *reflection)
reflection->DispatchThreadsDimension[2] = 1;
}
DXBC::Reflection *Program::GetReflection()
{
RDCWARN("Unimplemented DXIL::Program::GetReflection()");
return new DXBC::Reflection;
}
D3D_PRIMITIVE_TOPOLOGY Program::GetOutputTopology()
{
if(m_Type != DXBC::ShaderType::Geometry && m_Type != DXBC::ShaderType::Domain)
@@ -139,11 +169,11 @@ D3D_PRIMITIVE_TOPOLOGY Program::GetOutputTopology()
for(size_t t = 0; t < tags.children.size(); t += 2)
{
RDCASSERT(tags.children[t]->value);
if(ShaderTag(tags.children[t]->val->val.uv[0]) == ShaderTag::Geometry)
if(getival<ShaderTag>(tags.children[t]) == ShaderTag::Geometry)
{
Metadata &geomData = *tags.children[t + 1];
RDCASSERTEQUAL(geomData.children.size(), 5);
return (D3D_PRIMITIVE_TOPOLOGY)geomData.children[3]->val->val.uv[0];
return getival<D3D_PRIMITIVE_TOPOLOGY>(geomData.children[3]);
}
}
@@ -156,4 +186,143 @@ D3D_PRIMITIVE_TOPOLOGY Program::GetOutputTopology()
return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
}
struct DXMeta
{
struct
{
const Metadata *contents = NULL;
const Metadata *defines = NULL;
const Metadata *mainFileName = NULL;
const Metadata *args = NULL;
} source;
const Metadata *version = NULL;
const Metadata *valver = NULL;
const Metadata *shaderModel = NULL;
const Metadata *resources = NULL;
const Metadata *typeAnnotations = NULL;
const Metadata *viewIdState = NULL;
const Metadata *entryPoints = NULL;
DXMeta(const rdcarray<NamedMetadata> &namedMeta)
{
DXMeta &dx = *this;
for(size_t i = 0; i < namedMeta.size(); i++)
{
#define GRAB_META(metaname) \
if(namedMeta[i].name == #metaname) \
metaname = &namedMeta[i];
GRAB_META(dx.source.contents);
GRAB_META(dx.source.defines);
GRAB_META(dx.source.mainFileName);
GRAB_META(dx.source.args);
GRAB_META(dx.version);
GRAB_META(dx.valver);
GRAB_META(dx.shaderModel);
GRAB_META(dx.resources);
GRAB_META(dx.typeAnnotations);
GRAB_META(dx.viewIdState);
GRAB_META(dx.entryPoints);
#undef GRAB_META
}
}
};
DXBC::Reflection *Program::GetReflection()
{
using namespace DXBC;
Reflection *refl = new Reflection;
DXMeta dx(m_NamedMeta);
if(dx.resources)
{
RDCASSERTEQUAL(dx.resources->children.size(), 1);
const Metadata *resList = dx.resources->children[0];
RDCASSERTEQUAL(resList->children.size(), 4);
const Metadata *SRVs = resList->children[0];
if(SRVs)
{
for(const Metadata *r : SRVs->children)
{
ShaderInputBind bind;
bind.name = r->children[(size_t)ResField::Name]->str;
bind.space = getival<uint32_t>(r->children[(size_t)ResField::Space]);
bind.reg = getival<uint32_t>(r->children[(size_t)ResField::RegBase]);
bind.bindCount = getival<uint32_t>(r->children[(size_t)ResField::RegCount]);
refl->SRVs.push_back(bind);
}
}
const Metadata *UAVs = resList->children[1];
if(UAVs)
{
for(const Metadata *r : UAVs->children)
{
ShaderInputBind bind;
bind.name = r->children[(size_t)ResField::Name]->str;
bind.space = getival<uint32_t>(r->children[(size_t)ResField::Space]);
bind.reg = getival<uint32_t>(r->children[(size_t)ResField::RegBase]);
bind.bindCount = getival<uint32_t>(r->children[(size_t)ResField::RegCount]);
refl->UAVs.push_back(bind);
}
}
const Metadata *CBVs = resList->children[2];
if(CBVs)
{
for(const Metadata *r : CBVs->children)
{
CBuffer bind;
bind.name = r->children[(size_t)ResField::Name]->str;
bind.identifier = getival<uint32_t>(r->children[(size_t)ResField::ID]);
bind.space = getival<uint32_t>(r->children[(size_t)ResField::Space]);
bind.reg = getival<uint32_t>(r->children[(size_t)ResField::RegBase]);
bind.bindCount = getival<uint32_t>(r->children[(size_t)ResField::RegCount]);
bind.descriptor.type = CBuffer::Descriptor::TYPE_CBUFFER;
bind.descriptor.byteSize = getival<uint32_t>(r->children[(size_t)ResField::CBufferByteSize]);
const Type *cbufType = r->children[(size_t)ResField::VarDecl]->type;
// variable should be a pointer to the cbuffer type
RDCASSERT(cbufType->type == Type::Pointer);
cbufType = cbufType->inner;
for(const Type *member : cbufType->members)
{
(void)member;
}
refl->CBuffers.push_back(bind);
}
}
const Metadata *Samplers = resList->children[3];
if(Samplers)
{
for(const Metadata *r : Samplers->children)
{
ShaderInputBind bind;
bind.name = r->children[(size_t)ResField::Name]->str;
bind.space = getival<uint32_t>(r->children[(size_t)ResField::Space]);
bind.reg = getival<uint32_t>(r->children[(size_t)ResField::RegBase]);
bind.bindCount = getival<uint32_t>(r->children[(size_t)ResField::RegCount]);
bind.type = ShaderInputBind::TYPE_SAMPLER;
bind.dimension = ShaderInputBind::DIM_UNKNOWN;
bind.numComps = 0;
refl->Samplers.push_back(bind);
}
}
}
return refl;
}
}; // namespace DXIL