From b4ae6c4b10dbe39d6f48d7c4c83507cdb8a54252 Mon Sep 17 00:00:00 2001 From: baldurk Date: Tue, 16 Jun 2020 14:46:56 +0100 Subject: [PATCH] Start adding reflection based on the metadata --- .../driver/shaders/dxil/dxil_reflect.cpp | 193 ++++++++++++++++-- 1 file changed, 181 insertions(+), 12 deletions(-) diff --git a/renderdoc/driver/shaders/dxil/dxil_reflect.cpp b/renderdoc/driver/shaders/dxil/dxil_reflect.cpp index 28146c1db..cc1fe45e6 100644 --- a/renderdoc/driver/shaders/dxil/dxil_reflect.cpp +++ b/renderdoc/driver/shaders/dxil/dxil_reflect.cpp @@ -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 +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(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(threadDim.children[0]); + reflection->DispatchThreadsDimension[1] = getival(threadDim.children[1]); + reflection->DispatchThreadsDimension[2] = getival(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(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(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 &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(r->children[(size_t)ResField::Space]); + bind.reg = getival(r->children[(size_t)ResField::RegBase]); + bind.bindCount = getival(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(r->children[(size_t)ResField::Space]); + bind.reg = getival(r->children[(size_t)ResField::RegBase]); + bind.bindCount = getival(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(r->children[(size_t)ResField::ID]); + bind.space = getival(r->children[(size_t)ResField::Space]); + bind.reg = getival(r->children[(size_t)ResField::RegBase]); + bind.bindCount = getival(r->children[(size_t)ResField::RegCount]); + + bind.descriptor.type = CBuffer::Descriptor::TYPE_CBUFFER; + bind.descriptor.byteSize = getival(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(r->children[(size_t)ResField::Space]); + bind.reg = getival(r->children[(size_t)ResField::RegBase]); + bind.bindCount = getival(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