Handle D3D12 register spaces with high values without full array size

* Technically register space values are arbitrary so the array should not be
  resized to account for all space indices, in case one is very large.
This commit is contained in:
baldurk
2018-09-25 17:24:01 +01:00
parent 1985a6e87a
commit d0b650778b
8 changed files with 196 additions and 60 deletions
+20 -2
View File
@@ -413,11 +413,13 @@ struct RegisterSpace
DOCUMENT("");
bool operator==(const RegisterSpace &o) const
{
return constantBuffers == o.constantBuffers && samplers == o.samplers && srvs == o.srvs &&
uavs == o.uavs;
return spaceIndex == o.spaceIndex && constantBuffers == o.constantBuffers &&
samplers == o.samplers && srvs == o.srvs && uavs == o.uavs;
}
bool operator<(const RegisterSpace &o) const
{
if(!(spaceIndex == o.spaceIndex))
return spaceIndex < o.spaceIndex;
if(!(constantBuffers == o.constantBuffers))
return constantBuffers < o.constantBuffers;
if(!(samplers == o.samplers))
@@ -428,6 +430,8 @@ struct RegisterSpace
return uavs < o.uavs;
return false;
}
DOCUMENT("The index of this space, since space indices can be sparse");
uint32_t spaceIndex;
DOCUMENT("List of :class:`D3D12ConstantBuffer` containing the constant buffers.");
rdcarray<ConstantBuffer> constantBuffers;
DOCUMENT("List of :class:`D3D12Sampler` containing the samplers.");
@@ -456,6 +460,20 @@ mapping data.
DOCUMENT("A list of :class:`D3D12RegisterSpace` with the register spaces for this stage.");
rdcarray<RegisterSpace> spaces;
DOCUMENT(R"(Return the index in the :data:`spaces` array of a given register space.
:return: The index if the space exists, or ``-1`` if it doesn't.
:rtype: ``int``
)");
int32_t FindSpace(uint32_t spaceIndex) const
{
for(int32_t i = 0; i < spaces.count(); i++)
if(spaces[i].spaceIndex == spaceIndex)
return i;
return -1;
}
};
DOCUMENT("Describes a binding on the D3D12 stream-out stage.");
+9 -6
View File
@@ -924,12 +924,15 @@ BoundCBuffer PipeState::GetConstantBuffer(ShaderStage stage, uint32_t BufIdx, ui
const Bindpoint &bind =
s.bindpointMapping.constantBlocks[s.reflection->constantBlocks[BufIdx].bindPoint];
if(bind.bindset >= s.spaces.count() ||
bind.bind >= s.spaces[bind.bindset].constantBuffers.count())
int32_t space = s.FindSpace(bind.bindset);
if(space == -1)
return BoundCBuffer();
const D3D12Pipe::ConstantBuffer &descriptor =
s.spaces[bind.bindset].constantBuffers[bind.bind];
if(bind.bindset >= s.spaces.count() || bind.bind >= s.spaces[space].constantBuffers.count())
return BoundCBuffer();
const D3D12Pipe::ConstantBuffer &descriptor = s.spaces[space].constantBuffers[bind.bind];
buf = descriptor.resourceId;
ByteOffset = descriptor.byteOffset;
@@ -1031,7 +1034,7 @@ rdcarray<BoundResourceArray> PipeState::GetReadOnlyResources(ShaderStage stage)
for(int reg = 0; reg < s.spaces[space].srvs.count(); reg++)
{
const D3D12Pipe::View &bind = s.spaces[space].srvs[reg];
Bindpoint key(space, reg);
Bindpoint key(s.spaces[space].spaceIndex, reg);
BoundResource val;
// consider this register to not exist - it's in a gap defined by sparse root signature
@@ -1174,7 +1177,7 @@ rdcarray<BoundResourceArray> PipeState::GetReadWriteResources(ShaderStage stage)
for(int reg = 0; reg < s.spaces[space].uavs.count(); reg++)
{
const D3D12Pipe::View &bind = s.spaces[space].uavs[reg];
Bindpoint key(space, reg);
Bindpoint key(s.spaces[space].spaceIndex, reg);
BoundResource val;
// consider this register to not exist - it's in a gap defined by sparse root signature