Put resource specific data in a union in DXIL::EntryPoint::ResourceBase

This commit is contained in:
Jake Turner
2024-07-27 14:20:58 +01:00
parent 7f1cb948b3
commit 1120148a54
3 changed files with 165 additions and 154 deletions
+47 -40
View File
@@ -1425,6 +1425,42 @@ struct EntryPointInterface
int32_t startCol;
};
struct SRV
{
SRV(const Metadata *srv);
ResourceKind shape;
uint32_t sampleCount;
ComponentType compType;
uint32_t elementStride;
};
struct UAV
{
UAV(const Metadata *uav);
ResourceKind shape;
bool globallCoherent;
bool hasCounter;
bool rasterizerOrderedView;
ComponentType compType;
uint32_t elementStride;
SamplerFeedbackType samplerFeedback;
bool atomic64Use;
};
struct CBuffer
{
CBuffer(const Metadata *cbuffer);
uint32_t sizeInBytes;
bool isTBuffer;
const DXBC::CBuffer *cbufferRefl;
};
struct Sampler
{
Sampler(const Metadata *sampler);
SamplerKind samplerType;
};
struct ResourceBase
{
ResourceBase(ResourceClass resourceClass, const Metadata *resourceBase);
@@ -1445,42 +1481,13 @@ struct EntryPointInterface
uint32_t regBase;
uint32_t regCount;
const ResourceClass resClass;
};
struct SRV : ResourceBase
{
SRV(const Metadata *srv);
ResourceKind shape;
uint32_t sampleCount;
ComponentType compType;
uint32_t elementStride;
};
struct UAV : ResourceBase
{
UAV(const Metadata *uav);
ResourceKind shape;
bool globallCoherent;
bool hasCounter;
bool rasterizerOrderedView;
ComponentType compType;
uint32_t elementStride;
SamplerFeedbackType samplerFeedback;
bool atomic64Use;
};
struct CBuffer : ResourceBase
{
CBuffer(const Metadata *cbuffer);
uint32_t sizeInBytes;
bool isTBuffer;
const DXBC::CBuffer *cbufferRefl;
};
struct Sampler : ResourceBase
{
Sampler(const Metadata *sampler);
SamplerKind samplerType;
union
{
SRV srvData;
UAV uavData;
CBuffer cbufferData;
Sampler samplerData;
};
};
rdcstr name;
@@ -1488,10 +1495,10 @@ struct EntryPointInterface
rdcarray<Signature> inputs;
rdcarray<Signature> outputs;
rdcarray<Signature> patchConstants;
rdcarray<SRV> srvs;
rdcarray<UAV> uavs;
rdcarray<CBuffer> cbuffers;
rdcarray<Sampler> samplers;
rdcarray<ResourceBase> srvs;
rdcarray<ResourceBase> uavs;
rdcarray<ResourceBase> cbuffers;
rdcarray<ResourceBase> samplers;
};
struct ResourceReference
@@ -2574,7 +2574,7 @@ static const DXBC::CBufferVariable *FindCBufferVar(const uint32_t minOffset, con
}
static rdcstr MakeCBufferRegisterStr(uint32_t reg, uint32_t bytesPerElement,
DXIL::EntryPointInterface::CBuffer cbuffer,
const DXIL::EntryPointInterface::CBuffer &cbuffer,
const rdcstr &handleStr)
{
rdcstr ret = "{";
@@ -2872,20 +2872,21 @@ void Program::MakeRDDisassemblyString(const DXBC::Reflection *reflection)
{
if(needBlankLine)
DisassemblyAddNewLine();
EntryPointInterface::SRV &srv = entryPoint->srvs[j];
const DXIL::EntryPointInterface::ResourceBase &resource = entryPoint->srvs[j];
const DXIL::EntryPointInterface::SRV &srv = resource.srvData;
m_Disassembly += GetResourceShapeName(srv.shape, false);
if(srv.shape != DXIL::ResourceKind::RTAccelerationStructure)
m_Disassembly += "<" + GetResourceTypeName(srv.type) + ">";
m_Disassembly += " " + srv.name;
if(srv.regCount > 1)
m_Disassembly += "<" + GetResourceTypeName(resource.type) + ">";
m_Disassembly += " " + resource.name;
if(resource.regCount > 1)
{
m_Disassembly += "[";
if(srv.regCount != ~0U)
m_Disassembly += ToStr(srv.regCount);
if(resource.regCount != ~0U)
m_Disassembly += ToStr(resource.regCount);
m_Disassembly += "]";
}
m_Disassembly +=
" : register(t" + ToStr(srv.regBase) + ", space" + ToStr(srv.space) + ")";
" : register(t" + ToStr(resource.regBase) + ", space" + ToStr(resource.space) + ")";
m_Disassembly += ";";
needBlankLine = true;
}
@@ -2898,19 +2899,20 @@ void Program::MakeRDDisassemblyString(const DXBC::Reflection *reflection)
{
if(needBlankLine)
DisassemblyAddNewLine();
EntryPointInterface::UAV &uav = entryPoint->uavs[j];
const DXIL::EntryPointInterface::ResourceBase &resource = entryPoint->uavs[j];
const DXIL::EntryPointInterface::UAV &uav = resource.uavData;
m_Disassembly += GetResourceShapeName(uav.shape, true);
m_Disassembly += "<" + GetResourceTypeName(uav.type) + ">";
m_Disassembly += " " + uav.name;
if(uav.regCount > 1)
m_Disassembly += "<" + GetResourceTypeName(resource.type) + ">";
m_Disassembly += " " + resource.name;
if(resource.regCount > 1)
{
m_Disassembly += "[";
if(uav.regCount != ~0U)
m_Disassembly += ToStr(uav.regCount);
if(resource.regCount != ~0U)
m_Disassembly += ToStr(resource.regCount);
m_Disassembly += "]";
}
m_Disassembly +=
" : register(u" + ToStr(uav.regBase) + ", space" + ToStr(uav.space) + ")";
" : register(u" + ToStr(resource.regBase) + ", space" + ToStr(resource.space) + ")";
m_Disassembly += ";";
needBlankLine = true;
}
@@ -2921,14 +2923,15 @@ void Program::MakeRDDisassemblyString(const DXBC::Reflection *reflection)
{
for(size_t j = 0; j < entryPoint->cbuffers.size(); ++j)
{
EntryPointInterface::CBuffer &cbuffer = entryPoint->cbuffers[j];
DXIL::EntryPointInterface::ResourceBase &resource = entryPoint->cbuffers[j];
DXIL::EntryPointInterface::CBuffer &cbuffer = resource.cbufferData;
if(reflection)
{
for(size_t cbIdx = 0; cbIdx < reflection->CBuffers.size(); ++cbIdx)
{
const DXBC::CBuffer &cb = reflection->CBuffers[cbIdx];
if((cb.space == cbuffer.space) && (cb.reg == cbuffer.regBase) &&
(cb.bindCount == cbuffer.regCount))
if((cb.space == resource.space) && (cb.reg == resource.regBase) &&
(cb.bindCount == resource.regCount))
{
if(!cbuffer.cbufferRefl)
cbuffer.cbufferRefl = &reflection->CBuffers[cbIdx];
@@ -2937,16 +2940,16 @@ void Program::MakeRDDisassemblyString(const DXBC::Reflection *reflection)
}
if(needBlankLine)
DisassemblyAddNewLine();
m_Disassembly += "cbuffer " + cbuffer.name;
if(cbuffer.regCount > 1)
m_Disassembly += "cbuffer " + resource.name;
if(resource.regCount > 1)
{
m_Disassembly += "[";
if(cbuffer.regCount != ~0U)
m_Disassembly += ToStr(cbuffer.regCount);
if(resource.regCount != ~0U)
m_Disassembly += ToStr(resource.regCount);
m_Disassembly += "]";
}
m_Disassembly +=
" : register(b" + ToStr(cbuffer.regBase) + ", space" + ToStr(cbuffer.space) + ")";
" : register(b" + ToStr(resource.regBase) + ", space" + ToStr(resource.space) + ")";
// Ignore cbuffer's which don't have reflection data
if(cbuffer.cbufferRefl && cbuffer.cbufferRefl->hasReflectionData)
{
@@ -2986,18 +2989,18 @@ void Program::MakeRDDisassemblyString(const DXBC::Reflection *reflection)
{
if(needBlankLine)
DisassemblyAddNewLine();
EntryPointInterface::Sampler &sampler = entryPoint->samplers[j];
m_Disassembly += GetSamplerTypeName(sampler.type);
m_Disassembly += " " + sampler.name;
if(sampler.regCount > 1)
const DXIL::EntryPointInterface::ResourceBase &resource = entryPoint->samplers[j];
m_Disassembly += GetSamplerTypeName(resource.type);
m_Disassembly += " " + resource.name;
if(resource.regCount > 1)
{
m_Disassembly += "[";
if(sampler.regCount != ~0U)
m_Disassembly += ToStr(sampler.regCount);
if(resource.regCount != ~0U)
m_Disassembly += ToStr(resource.regCount);
m_Disassembly += "]";
}
m_Disassembly +=
" : register(s" + ToStr(sampler.regBase) + ", space" + ToStr(sampler.space) + ")";
" : register(s" + ToStr(resource.regBase) + ", space" + ToStr(resource.space) + ")";
m_Disassembly += ";";
needBlankLine = true;
}
@@ -3416,8 +3419,9 @@ void Program::MakeRDDisassemblyString(const DXBC::Reflection *reflection)
regIndex = regIndex / 16;
// uint32_t alignment = getival<uint32_t>(inst.args[3]);
}
const EntryPointInterface::CBuffer &cbuffer =
const DXIL::EntryPointInterface::ResourceBase &resource =
entryPoint->cbuffers[resRef->resourceIndex];
const DXIL::EntryPointInterface::CBuffer &cbuffer = resource.cbufferData;
if(cbuffer.cbufferRefl && cbuffer.cbufferRefl->hasReflectionData)
{
const Type *retType = inst.type;
@@ -3431,7 +3435,7 @@ void Program::MakeRDDisassemblyString(const DXBC::Reflection *reflection)
}
lineStr +=
MakeCBufferRegisterStr(regIndex, bytesPerElement, cbuffer, handleStr);
commentStr += " cbuffer = " + cbuffer.name;
commentStr += " cbuffer = " + resource.name;
commentStr += ", byte_offset = " + ToStr(regIndex * 16);
}
else
@@ -3551,9 +3555,10 @@ void Program::MakeRDDisassemblyString(const DXBC::Reflection *reflection)
if(entryPoint && resRef)
{
uint32_t resourceIndex = resRef->resourceIndex;
const EntryPointInterface::SRV *texture = resourceIndex < entryPoint->srvs.size()
? &entryPoint->srvs[resourceIndex]
: NULL;
const EntryPointInterface::SRV *texture =
resourceIndex < entryPoint->srvs.size()
? &entryPoint->srvs[resourceIndex].srvData
: NULL;
if(texture)
sampleCount = texture->sampleCount;
}
@@ -4724,7 +4729,7 @@ void Program::ParseReferences(const DXBC::Reflection *reflection)
// Use resource names from the reflection data if the resource name data is empty
if(reflection)
{
for(EntryPointInterface::CBuffer &cbuffer : entryPoint->cbuffers)
for(EntryPointInterface::ResourceBase &cbuffer : entryPoint->cbuffers)
{
if(cbuffer.name.empty())
{
@@ -4737,7 +4742,7 @@ void Program::ParseReferences(const DXBC::Reflection *reflection)
}
}
for(EntryPointInterface::SRV &srv : entryPoint->srvs)
for(EntryPointInterface::ResourceBase &srv : entryPoint->srvs)
{
if(srv.name.empty())
{
@@ -4750,7 +4755,7 @@ void Program::ParseReferences(const DXBC::Reflection *reflection)
}
}
for(EntryPointInterface::UAV &uav : entryPoint->uavs)
for(EntryPointInterface::ResourceBase &uav : entryPoint->uavs)
{
if(uav.name.empty())
{
@@ -4765,7 +4770,7 @@ void Program::ParseReferences(const DXBC::Reflection *reflection)
for(size_t j = 0; j < entryPoint->samplers.size(); ++j)
{
EntryPointInterface::Sampler &sampler = entryPoint->samplers[j];
EntryPointInterface::ResourceBase &sampler = entryPoint->samplers[j];
if(sampler.name.empty())
{
for(DXBC::ShaderInputBind bind : reflection->Samplers)
+74 -75
View File
@@ -287,89 +287,88 @@ EntryPointInterface::Signature::Signature(const Metadata *signature)
startCol = getival<int8_t>(signature->children[SignatureElement::StartCol]);
}
EntryPointInterface::ResourceBase::ResourceBase(ResourceClass resourceClass,
const Metadata *resourceBase)
EntryPointInterface::ResourceBase::ResourceBase(ResourceClass resourceClass, const Metadata *md)
: resClass(resourceClass)
{
id = getival<uint32_t>(resourceBase->children[(size_t)ResField::ID]);
type = resourceBase->children[(size_t)ResField::VarDecl]->type;
name = resourceBase->children[(size_t)ResField::Name]->str;
space = getival<uint32_t>(resourceBase->children[(size_t)ResField::Space]);
regBase = getival<uint32_t>(resourceBase->children[(size_t)ResField::RegBase]);
regCount = getival<uint32_t>(resourceBase->children[(size_t)ResField::RegCount]);
}
EntryPointInterface::SRV::SRV(const Metadata *srv) : ResourceBase(ResourceClass::SRV, srv)
{
shape = getival<ResourceKind>(srv->children[(size_t)ResField::SRVShape]);
sampleCount = getival<uint32_t>(srv->children[(size_t)ResField::SRVSampleCount]);
const Metadata *tags = srv->children[(size_t)ResField::SRVTags];
for(size_t t = 0; tags && t < tags->children.size(); t += 2)
id = getival<uint32_t>(md->children[(size_t)ResField::ID]);
type = md->children[(size_t)ResField::VarDecl]->type;
name = md->children[(size_t)ResField::Name]->str;
space = getival<uint32_t>(md->children[(size_t)ResField::Space]);
regBase = getival<uint32_t>(md->children[(size_t)ResField::RegBase]);
regCount = getival<uint32_t>(md->children[(size_t)ResField::RegCount]);
if(resourceClass == ResourceClass::SRV)
{
RDCASSERT(tags->children[t]->isConstant);
ResourcesTag tag = getival<ResourcesTag>(tags->children[t]);
switch(tag)
SRV &srv = srvData;
srv.shape = getival<ResourceKind>(md->children[(size_t)ResField::SRVShape]);
srv.sampleCount = getival<uint32_t>(md->children[(size_t)ResField::SRVSampleCount]);
const Metadata *tags = md->children[(size_t)ResField::SRVTags];
for(size_t t = 0; tags && t < tags->children.size(); t += 2)
{
case ResourcesTag::ElementType:
compType = getival<ComponentType>(tags->children[t + 1]);
break;
case ResourcesTag::StructStride:
elementStride = getival<uint32_t>(tags->children[t + 1]);
break;
default: break;
RDCASSERT(tags->children[t]->isConstant);
ResourcesTag tag = getival<ResourcesTag>(tags->children[t]);
switch(tag)
{
case ResourcesTag::ElementType:
srv.compType = getival<ComponentType>(tags->children[t + 1]);
break;
case ResourcesTag::StructStride:
srv.elementStride = getival<uint32_t>(tags->children[t + 1]);
break;
default: break;
}
}
}
}
EntryPointInterface::UAV::UAV(const Metadata *uav) : ResourceBase(ResourceClass::UAV, uav)
{
shape = getival<ResourceKind>(uav->children[(size_t)ResField::UAVShape]);
globallCoherent = (getival<uint32_t>(uav->children[(size_t)ResField::UAVGloballyCoherent]) == 1);
hasCounter = (getival<uint32_t>(uav->children[(size_t)ResField::UAVHiddenCounter]) == 1);
rasterizerOrderedView = (getival<uint32_t>(uav->children[(size_t)ResField::UAVRasterOrder]) == 1);
const Metadata *tags = uav->children[(size_t)ResField::UAVTags];
for(size_t t = 0; tags && t < tags->children.size(); t += 2)
else if(resourceClass == ResourceClass::UAV)
{
RDCASSERT(tags->children[t]->isConstant);
ResourcesTag tag = getival<ResourcesTag>(tags->children[t]);
switch(tag)
UAV &uav = uavData;
uav.shape = getival<ResourceKind>(md->children[(size_t)ResField::UAVShape]);
uav.globallCoherent =
(getival<uint32_t>(md->children[(size_t)ResField::UAVGloballyCoherent]) == 1);
uav.hasCounter = (getival<uint32_t>(md->children[(size_t)ResField::UAVHiddenCounter]) == 1);
uav.rasterizerOrderedView =
(getival<uint32_t>(md->children[(size_t)ResField::UAVRasterOrder]) == 1);
const Metadata *tags = md->children[(size_t)ResField::UAVTags];
for(size_t t = 0; tags && t < tags->children.size(); t += 2)
{
case ResourcesTag::ElementType:
compType = getival<ComponentType>(tags->children[t + 1]);
break;
case ResourcesTag::StructStride:
elementStride = getival<uint32_t>(tags->children[t + 1]);
break;
case ResourcesTag::SamplerFeedbackKind:
samplerFeedback = getival<SamplerFeedbackType>(tags->children[t + 1]);
break;
case ResourcesTag::Atomic64Use:
atomic64Use = (getival<uint32_t>(tags->children[t + 1]) == 1);
break;
default: break;
RDCASSERT(tags->children[t]->isConstant);
ResourcesTag tag = getival<ResourcesTag>(tags->children[t]);
switch(tag)
{
case ResourcesTag::ElementType:
uav.compType = getival<ComponentType>(tags->children[t + 1]);
break;
case ResourcesTag::StructStride:
uav.elementStride = getival<uint32_t>(tags->children[t + 1]);
break;
case ResourcesTag::SamplerFeedbackKind:
uav.samplerFeedback = getival<SamplerFeedbackType>(tags->children[t + 1]);
break;
case ResourcesTag::Atomic64Use:
uav.atomic64Use = (getival<uint32_t>(tags->children[t + 1]) == 1);
break;
default: break;
}
}
}
}
EntryPointInterface::CBuffer::CBuffer(const Metadata *cbuffer)
: ResourceBase(ResourceClass::CBuffer, cbuffer)
{
sizeInBytes = getival<uint32_t>(cbuffer->children[(size_t)ResField::CBufferByteSize]);
const Metadata *tags = cbuffer->children[(size_t)ResField::CBufferTags];
for(size_t t = 0; tags && t < tags->children.size(); t += 2)
else if(resourceClass == ResourceClass::CBuffer)
{
RDCASSERT(tags->children[t]->isConstant);
ResourcesTag tag = getival<ResourcesTag>(tags->children[t]);
if(tag == ResourcesTag::IsTBufferTag)
isTBuffer = (getival<uint32_t>(tags->children[t + 1]) == 1);
CBuffer &cbuffer = cbufferData;
cbuffer.sizeInBytes = getival<uint32_t>(md->children[(size_t)ResField::CBufferByteSize]);
const Metadata *tags = md->children[(size_t)ResField::CBufferTags];
for(size_t t = 0; tags && t < tags->children.size(); t += 2)
{
RDCASSERT(tags->children[t]->isConstant);
ResourcesTag tag = getival<ResourcesTag>(tags->children[t]);
if(tag == ResourcesTag::IsTBufferTag)
cbuffer.isTBuffer = (getival<uint32_t>(tags->children[t + 1]) == 1);
}
cbuffer.cbufferRefl = NULL;
}
else if(resourceClass == ResourceClass::Sampler)
{
Sampler &sampler = samplerData;
sampler.samplerType = getival<SamplerKind>(md->children[(size_t)ResField::SamplerType]);
}
cbufferRefl = NULL;
}
EntryPointInterface::Sampler::Sampler(const Metadata *sampler)
: ResourceBase(ResourceClass::Sampler, sampler)
{
samplerType = getival<SamplerKind>(sampler->children[(size_t)ResField::SamplerType]);
}
EntryPointInterface::EntryPointInterface(const Metadata *entryPoint)
@@ -411,26 +410,26 @@ EntryPointInterface::EntryPointInterface(const Metadata *entryPoint)
if(srvsMeta)
{
for(size_t i = 0; i < srvsMeta->children.size(); ++i)
srvs.push_back(srvsMeta->children[i]);
srvs.push_back(ResourceBase(ResourceClass::SRV, srvsMeta->children[i]));
}
const Metadata *uavsMeta = resources->children[1];
if(uavsMeta)
{
for(size_t i = 0; i < uavsMeta->children.size(); ++i)
uavs.push_back(uavsMeta->children[i]);
uavs.push_back(ResourceBase(ResourceClass::UAV, uavsMeta->children[i]));
}
const Metadata *cbuffersMeta = resources->children[2];
if(cbuffersMeta)
{
for(size_t i = 0; i < cbuffersMeta->children.size(); ++i)
cbuffers.push_back(cbuffersMeta->children[i]);
cbuffers.push_back(ResourceBase(ResourceClass::CBuffer, cbuffersMeta->children[i]));
}
const Metadata *samplersMeta = resources->children[3];
if(samplersMeta)
{
for(size_t i = 0; i < samplersMeta->children.size(); ++i)
samplers.push_back(samplersMeta->children[i]);
samplers.push_back(ResourceBase(ResourceClass::Sampler, samplersMeta->children[i]));
}
}
/*