diff --git a/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.cpp b/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.cpp index 8abb3ca91..4f068b4e8 100644 --- a/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.cpp +++ b/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.cpp @@ -993,7 +993,8 @@ void D3D12PipelineStateViewer::setShaderState(const D3D12Pipe::Shader &stage, RD { for(int reg = 0; reg < stage.spaces[space].srvs.count(); reg++) { - addResourceRow(D3D12ViewTag(D3D12ViewTag::SRV, space, reg, stage.spaces[space].srvs[reg]), + addResourceRow(D3D12ViewTag(D3D12ViewTag::SRV, stage.spaces[space].spaceIndex, reg, + stage.spaces[space].srvs[reg]), &stage, resources); } } @@ -1008,7 +1009,8 @@ void D3D12PipelineStateViewer::setShaderState(const D3D12Pipe::Shader &stage, RD { for(int reg = 0; reg < stage.spaces[space].uavs.count(); reg++) { - addResourceRow(D3D12ViewTag(D3D12ViewTag::UAV, space, reg, stage.spaces[space].uavs[reg]), + addResourceRow(D3D12ViewTag(D3D12ViewTag::UAV, stage.spaces[space].spaceIndex, reg, + stage.spaces[space].uavs[reg]), &stage, uavs); } } @@ -1047,7 +1049,7 @@ void D3D12PipelineStateViewer::setShaderState(const D3D12Pipe::Shader &stage, RD if(b.bind <= reg) regMatch = (b.arraySize == ~0U) || (b.bind + (int)b.arraySize > reg); - if(b.bindset == space && regMatch) + if(b.bindset == (int32_t)stage.spaces[space].spaceIndex && regMatch) { bind = &b; shaderInput = &res; @@ -1117,7 +1119,7 @@ void D3D12PipelineStateViewer::setShaderState(const D3D12Pipe::Shader &stage, RD filter += QFormatStr(" (%1)").arg(ToQStr(s.filter.filter)); RDTreeWidgetItem *node = new RDTreeWidgetItem( - {rootel, space, regname, addressing, filter, + {rootel, stage.spaces[space].spaceIndex, regname, addressing, filter, QFormatStr("%1 - %2") .arg(s.minLOD == -FLT_MAX ? lit("0") : QString::number(s.minLOD)) .arg(s.maxLOD == FLT_MAX ? lit("FLT_MAX") : QString::number(s.maxLOD)), @@ -1165,7 +1167,7 @@ void D3D12PipelineStateViewer::setShaderState(const D3D12Pipe::Shader &stage, RD if(bm.bind <= reg) regMatch = (bm.arraySize == ~0U) || (bm.bind + (int)bm.arraySize > reg); - if(bm.bindset == space && regMatch) + if(bm.bindset == (int32_t)stage.spaces[space].spaceIndex && regMatch) { bind = &bm; shaderCBuf = &res; @@ -1224,7 +1226,7 @@ void D3D12PipelineStateViewer::setShaderState(const D3D12Pipe::Shader &stage, RD filledSlot = false; RDTreeWidgetItem *node = new RDTreeWidgetItem( - {rootel, (qulonglong)space, regname, b.resourceId, + {rootel, (qulonglong)stage.spaces[space].spaceIndex, regname, b.resourceId, QFormatStr("%1 - %2").arg(offset).arg(offset + bytesize), sizestr, QString()}); node->setTag(tag); @@ -2478,7 +2480,7 @@ void D3D12PipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const D3D12Pipe if(b.bind <= reg) regMatch = (b.arraySize == ~0U) || (b.bind + (int)b.arraySize > reg); - if(b.bindset == space && regMatch) + if(b.bindset == (int32_t)sh.spaces[space].spaceIndex && regMatch) { shaderInput = &res; break; @@ -2492,7 +2494,7 @@ void D3D12PipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const D3D12Pipe QVariantList row = exportViewHTML(v, false, shaderInput, QString()); row.push_front(reg); - row.push_front(space); + row.push_front(sh.spaces[space].spaceIndex); row.push_front(rootel); rows.push_back(row); @@ -2540,7 +2542,7 @@ void D3D12PipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const D3D12Pipe if(b.bind <= reg) regMatch = (b.arraySize == ~0U) || (b.bind + (int)b.arraySize > reg); - if(b.bindset == space && regMatch) + if(b.bindset == (int32_t)sh.spaces[space].spaceIndex && regMatch) { shaderInput = &res; break; @@ -2554,7 +2556,7 @@ void D3D12PipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const D3D12Pipe QVariantList row = exportViewHTML(v, true, shaderInput, QString()); row.push_front(reg); - row.push_front(space); + row.push_front(sh.spaces[space].spaceIndex); row.push_front(rootel); rows.push_back(row); @@ -2602,7 +2604,7 @@ void D3D12PipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const D3D12Pipe if(b.bind <= reg) regMatch = (b.arraySize == ~0U) || (b.bind + (int)b.arraySize > reg); - if(b.bindset == space && regMatch) + if(b.bindset == (int32_t)sh.spaces[space].spaceIndex && regMatch) { shaderInput = &res; break; @@ -2666,7 +2668,7 @@ void D3D12PipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const D3D12Pipe else if(s.filter.filter != FilterFunction::Normal) filter += QFormatStr(" (%1)").arg(ToQStr(s.filter.filter)); - rows.push_back({rootel, space, regname, addressing, filter, + rows.push_back({rootel, sh.spaces[space].spaceIndex, regname, addressing, filter, QFormatStr("%1 - %2") .arg(s.minLOD == -FLT_MAX ? lit("0") : QString::number(s.minLOD)) .arg(s.maxLOD == FLT_MAX ? lit("FLT_MAX") : QString::number(s.maxLOD)), @@ -2709,7 +2711,7 @@ void D3D12PipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const D3D12Pipe if(bm.bind <= reg) regMatch = (bm.arraySize == ~0U) || (bm.bind + (int)bm.arraySize > reg); - if(bm.bindset == space && regMatch) + if(bm.bindset == (int32_t)sh.spaces[space].spaceIndex && regMatch) { shaderCBuf = &res; break; @@ -2753,8 +2755,8 @@ void D3D12PipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const D3D12Pipe length = qMin(length, (uint64_t)bytesize); - rows.push_back( - {rootel, space, regname, name, (qulonglong)offset, (qulonglong)length, numvars}); + rows.push_back({rootel, sh.spaces[space].spaceIndex, regname, name, (qulonglong)offset, + (qulonglong)length, numvars}); } } } diff --git a/renderdoc/api/replay/d3d12_pipestate.h b/renderdoc/api/replay/d3d12_pipestate.h index e8714681b..db9b42a8c 100644 --- a/renderdoc/api/replay/d3d12_pipestate.h +++ b/renderdoc/api/replay/d3d12_pipestate.h @@ -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 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 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."); diff --git a/renderdoc/api/replay/pipestate.inl b/renderdoc/api/replay/pipestate.inl index 2104cb708..42d71b54d 100644 --- a/renderdoc/api/replay/pipestate.inl +++ b/renderdoc/api/replay/pipestate.inl @@ -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 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 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 diff --git a/renderdoc/driver/d3d12/d3d12_common.h b/renderdoc/driver/d3d12/d3d12_common.h index c44e15a18..dc729565c 100644 --- a/renderdoc/driver/d3d12/d3d12_common.h +++ b/renderdoc/driver/d3d12/d3d12_common.h @@ -231,7 +231,7 @@ struct D3D12RootSignatureParameter : D3D12_ROOT_PARAMETER1 return *this; } - void MakeFrom(const D3D12_ROOT_PARAMETER1 ¶m, UINT &numSpaces) + void MakeFrom(const D3D12_ROOT_PARAMETER1 ¶m, UINT &maxSpaceIndex) { ParameterType = param.ParameterType; ShaderVisibility = param.ShaderVisibility; @@ -247,7 +247,7 @@ struct D3D12RootSignatureParameter : D3D12_ROOT_PARAMETER1 { ranges[i] = param.DescriptorTable.pDescriptorRanges[i]; - numSpaces = RDCMAX(numSpaces, ranges[i].RegisterSpace + 1); + maxSpaceIndex = RDCMAX(maxSpaceIndex, ranges[i].RegisterSpace + 1); } DescriptorTable.NumDescriptorRanges = (UINT)ranges.size(); @@ -255,11 +255,11 @@ struct D3D12RootSignatureParameter : D3D12_ROOT_PARAMETER1 } else if(ParameterType == D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS) { - numSpaces = RDCMAX(numSpaces, Constants.RegisterSpace + 1); + maxSpaceIndex = RDCMAX(maxSpaceIndex, Constants.RegisterSpace + 1); } else { - numSpaces = RDCMAX(numSpaces, Descriptor.RegisterSpace + 1); + maxSpaceIndex = RDCMAX(maxSpaceIndex, Descriptor.RegisterSpace + 1); } } @@ -309,7 +309,7 @@ struct D3D12RootSignatureParameter : D3D12_ROOT_PARAMETER1 struct D3D12RootSignature { - uint32_t numSpaces = 0; + uint32_t maxSpaceIndex = 0; uint32_t dwordLength = 0; D3D12_ROOT_SIGNATURE_FLAGS Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE; diff --git a/renderdoc/driver/d3d12/d3d12_overlay.cpp b/renderdoc/driver/d3d12/d3d12_overlay.cpp index 56cc8c7c1..2b00e32d8 100644 --- a/renderdoc/driver/d3d12/d3d12_overlay.cpp +++ b/renderdoc/driver/d3d12/d3d12_overlay.cpp @@ -90,13 +90,13 @@ struct D3D12QuadOverdrawCallback : public D3D12DrawcallCallback { if(modsig.params[i].ParameterType == D3D12_ROOT_PARAMETER_TYPE_UAV) { - modsig.params[i].Descriptor.RegisterSpace = modsig.numSpaces; + modsig.params[i].Descriptor.RegisterSpace = modsig.maxSpaceIndex; } else if(modsig.params[i].ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE) { for(size_t r = 0; r < modsig.params[i].ranges.size(); r++) { - modsig.params[i].ranges[r].RegisterSpace = modsig.numSpaces; + modsig.params[i].ranges[r].RegisterSpace = modsig.maxSpaceIndex; } } } diff --git a/renderdoc/driver/d3d12/d3d12_replay.cpp b/renderdoc/driver/d3d12/d3d12_replay.cpp index ce4808501..c413aae68 100644 --- a/renderdoc/driver/d3d12/d3d12_replay.cpp +++ b/renderdoc/driver/d3d12/d3d12_replay.cpp @@ -53,6 +53,32 @@ T &resize_and_add(rdcarray &vec, size_t idx) return vec[idx]; } +D3D12Pipe::RegisterSpace &get_space(rdcarray &dstSpaces, + uint32_t RegisterSpace) +{ + // look to see if we've already added this space, if so then return it + for(D3D12Pipe::RegisterSpace &space : dstSpaces) + if(space.spaceIndex == RegisterSpace) + return space; + + // otherwise look for the right place to insert it + for(size_t i = 0; i < dstSpaces.size(); i++) + { + if(RegisterSpace < dstSpaces[i].spaceIndex) + { + dstSpaces.insert(i, D3D12Pipe::RegisterSpace()); + dstSpaces[i].spaceIndex = RegisterSpace; + return dstSpaces[i]; + } + } + + // if we got here, we didn't find an existing space nor a place to insert a new one, so we append + // it + dstSpaces.push_back(D3D12Pipe::RegisterSpace()); + dstSpaces.back().spaceIndex = RegisterSpace; + return dstSpaces.back(); +} + D3D12Replay::D3D12Replay() { m_pDevice = NULL; @@ -826,8 +852,7 @@ void D3D12Replay::FillRegisterSpaces(const D3D12RenderState::RootSignature &root // clear first to ensure the spaces are default-initialised dstSpaces.clear(); - dstSpaces.resize(sig->sig.numSpaces); - D3D12Pipe::RegisterSpace *spaces = dstSpaces.data(); + dstSpaces.reserve(8); for(size_t rootEl = 0; rootEl < sig->sig.params.size(); rootEl++) { @@ -838,8 +863,9 @@ void D3D12Replay::FillRegisterSpaces(const D3D12RenderState::RootSignature &root if(p.ParameterType == D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS) { - D3D12Pipe::ConstantBuffer &cb = resize_and_add( - spaces[p.Constants.RegisterSpace].constantBuffers, p.Constants.ShaderRegister); + D3D12Pipe::ConstantBuffer &cb = + resize_and_add(get_space(dstSpaces, p.Constants.RegisterSpace).constantBuffers, + p.Constants.ShaderRegister); cb.immediate = true; cb.rootElement = (uint32_t)rootEl; cb.byteSize = uint32_t(sizeof(uint32_t) * p.Constants.Num32BitValues); @@ -857,8 +883,9 @@ void D3D12Replay::FillRegisterSpaces(const D3D12RenderState::RootSignature &root } else if(p.ParameterType == D3D12_ROOT_PARAMETER_TYPE_CBV) { - D3D12Pipe::ConstantBuffer &cb = resize_and_add( - spaces[p.Descriptor.RegisterSpace].constantBuffers, p.Descriptor.ShaderRegister); + D3D12Pipe::ConstantBuffer &cb = + resize_and_add(get_space(dstSpaces, p.Descriptor.RegisterSpace).constantBuffers, + p.Descriptor.ShaderRegister); cb.immediate = true; cb.rootElement = (uint32_t)rootEl; @@ -877,8 +904,8 @@ void D3D12Replay::FillRegisterSpaces(const D3D12RenderState::RootSignature &root } else if(p.ParameterType == D3D12_ROOT_PARAMETER_TYPE_SRV) { - D3D12Pipe::View &view = - resize_and_add(spaces[p.Descriptor.RegisterSpace].srvs, p.Descriptor.ShaderRegister); + D3D12Pipe::View &view = resize_and_add(get_space(dstSpaces, p.Descriptor.RegisterSpace).srvs, + p.Descriptor.ShaderRegister); view.immediate = true; view.rootElement = (uint32_t)rootEl; @@ -902,8 +929,8 @@ void D3D12Replay::FillRegisterSpaces(const D3D12RenderState::RootSignature &root } else if(p.ParameterType == D3D12_ROOT_PARAMETER_TYPE_UAV) { - D3D12Pipe::View &view = - resize_and_add(spaces[p.Descriptor.RegisterSpace].uavs, p.Descriptor.ShaderRegister); + D3D12Pipe::View &view = resize_and_add(get_space(dstSpaces, p.Descriptor.RegisterSpace).uavs, + p.Descriptor.ShaderRegister); view.immediate = true; view.rootElement = (uint32_t)rootEl; @@ -944,7 +971,7 @@ void D3D12Replay::FillRegisterSpaces(const D3D12RenderState::RootSignature &root const D3D12_DESCRIPTOR_RANGE1 &range = p.ranges[r]; UINT shaderReg = range.BaseShaderRegister; - UINT regSpace = range.RegisterSpace; + D3D12Pipe::RegisterSpace ®Space = get_space(dstSpaces, range.RegisterSpace); D3D12Descriptor *desc = NULL; @@ -980,12 +1007,12 @@ void D3D12Replay::FillRegisterSpaces(const D3D12RenderState::RootSignature &root if(range.RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER) { UINT maxReg = shaderReg + num - 1; - if(maxReg >= spaces[regSpace].samplers.size()) - spaces[regSpace].samplers.resize(maxReg + 1); + if(maxReg >= regSpace.samplers.size()) + regSpace.samplers.resize(maxReg + 1); for(UINT i = 0; i < num; i++, shaderReg++) { - D3D12Pipe::Sampler &samp = spaces[regSpace].samplers[shaderReg]; + D3D12Pipe::Sampler &samp = regSpace.samplers[shaderReg]; samp.immediate = false; samp.rootElement = (uint32_t)rootEl; samp.tableIndex = offset + i; @@ -1016,12 +1043,12 @@ void D3D12Replay::FillRegisterSpaces(const D3D12RenderState::RootSignature &root else if(range.RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_CBV) { UINT maxReg = shaderReg + num - 1; - if(maxReg >= spaces[regSpace].constantBuffers.size()) - spaces[regSpace].constantBuffers.resize(maxReg + 1); + if(maxReg >= regSpace.constantBuffers.size()) + regSpace.constantBuffers.resize(maxReg + 1); for(UINT i = 0; i < num; i++, shaderReg++) { - D3D12Pipe::ConstantBuffer &cb = spaces[regSpace].constantBuffers[shaderReg]; + D3D12Pipe::ConstantBuffer &cb = regSpace.constantBuffers[shaderReg]; cb.immediate = false; cb.rootElement = (uint32_t)rootEl; cb.tableIndex = offset + i; @@ -1041,12 +1068,12 @@ void D3D12Replay::FillRegisterSpaces(const D3D12RenderState::RootSignature &root else if(range.RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SRV) { UINT maxReg = shaderReg + num - 1; - if(maxReg >= spaces[regSpace].srvs.size()) - spaces[regSpace].srvs.resize(maxReg + 1); + if(maxReg >= regSpace.srvs.size()) + regSpace.srvs.resize(maxReg + 1); for(UINT i = 0; i < num; i++, shaderReg++) { - D3D12Pipe::View &view = spaces[regSpace].srvs[shaderReg]; + D3D12Pipe::View &view = regSpace.srvs[shaderReg]; view.immediate = false; view.rootElement = (uint32_t)rootEl; view.tableIndex = offset + i; @@ -1062,12 +1089,12 @@ void D3D12Replay::FillRegisterSpaces(const D3D12RenderState::RootSignature &root else if(range.RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_UAV) { UINT maxReg = shaderReg + num - 1; - if(maxReg >= spaces[regSpace].uavs.size()) - spaces[regSpace].uavs.resize(maxReg + 1); + if(maxReg >= regSpace.uavs.size()) + regSpace.uavs.resize(maxReg + 1); for(UINT i = 0; i < num; i++, shaderReg++) { - D3D12Pipe::View &view = spaces[regSpace].uavs[shaderReg]; + D3D12Pipe::View &view = regSpace.uavs[shaderReg]; view.immediate = false; view.rootElement = (uint32_t)rootEl; view.tableIndex = offset + i; @@ -1092,8 +1119,8 @@ void D3D12Replay::FillRegisterSpaces(const D3D12RenderState::RootSignature &root sampDesc.ShaderVisibility != visibility) continue; - D3D12Pipe::Sampler &samp = - resize_and_add(spaces[sampDesc.RegisterSpace].samplers, sampDesc.ShaderRegister); + D3D12Pipe::Sampler &samp = resize_and_add(get_space(dstSpaces, sampDesc.RegisterSpace).samplers, + sampDesc.ShaderRegister); samp.immediate = true; samp.rootElement = (uint32_t)i; @@ -3576,3 +3603,88 @@ void D3D12_ProcessStructured(RDCFile *rdc, SDFile &output) static StructuredProcessRegistration D3D12ProcessRegistration(RDCDriver::D3D12, &D3D12_ProcessStructured); + +#if ENABLED(ENABLE_UNIT_TESTS) + +#undef None + +#include "3rdparty/catch/catch.hpp" + +TEST_CASE("Test get_space ensures sorted nature", "[d3d12]") +{ + D3D12Pipe::Shader shader; + rdcarray &spaces = shader.spaces; + + get_space(spaces, 0).samplers.resize(5); + + CHECK(spaces.size() == 1); + + REQUIRE(shader.FindSpace(0) == 0); + + CHECK(spaces[shader.FindSpace(0)].samplers.size() == 5); + + SECTION("Adding in sorted order") + { + get_space(spaces, 3).srvs.resize(7); + get_space(spaces, 4).uavs.resize(9); + get_space(spaces, 1000).constantBuffers.resize(2); + + CHECK(spaces.size() == 4); + + REQUIRE(shader.FindSpace(0) == 0); + REQUIRE(shader.FindSpace(3) == 1); + REQUIRE(shader.FindSpace(4) == 2); + REQUIRE(shader.FindSpace(1000) == 3); + REQUIRE(shader.FindSpace(99) == -1); + + CHECK(spaces[shader.FindSpace(0)].samplers.size() == 5); + CHECK(spaces[shader.FindSpace(3)].srvs.size() == 7); + CHECK(spaces[shader.FindSpace(4)].uavs.size() == 9); + CHECK(spaces[shader.FindSpace(1000)].constantBuffers.size() == 2); + } + + SECTION("Adding in reverse sorted order") + { + get_space(spaces, 1000).constantBuffers.resize(2); + get_space(spaces, 4).uavs.resize(9); + get_space(spaces, 3).srvs.resize(7); + + CHECK(spaces.size() == 4); + + REQUIRE(shader.FindSpace(0) == 0); + REQUIRE(shader.FindSpace(3) == 1); + REQUIRE(shader.FindSpace(4) == 2); + REQUIRE(shader.FindSpace(1000) == 3); + REQUIRE(shader.FindSpace(99) == -1); + + CHECK(spaces[shader.FindSpace(0)].samplers.size() == 5); + CHECK(spaces[shader.FindSpace(3)].srvs.size() == 7); + CHECK(spaces[shader.FindSpace(4)].uavs.size() == 9); + CHECK(spaces[shader.FindSpace(1000)].constantBuffers.size() == 2); + } + + SECTION("Adding in random order") + { + get_space(spaces, 4).uavs.resize(9); + get_space(spaces, 19).samplers.resize(100); + get_space(spaces, 3).srvs.resize(7); + get_space(spaces, 1000).constantBuffers.resize(2); + + CHECK(spaces.size() == 5); + + REQUIRE(shader.FindSpace(0) == 0); + REQUIRE(shader.FindSpace(3) == 1); + REQUIRE(shader.FindSpace(4) == 2); + REQUIRE(shader.FindSpace(19) == 3); + REQUIRE(shader.FindSpace(1000) == 4); + REQUIRE(shader.FindSpace(99) == -1); + + CHECK(spaces[shader.FindSpace(4)].uavs.size() == 9); + CHECK(spaces[shader.FindSpace(19)].samplers.size() == 100); + CHECK(spaces[shader.FindSpace(0)].samplers.size() == 5); + CHECK(spaces[shader.FindSpace(3)].srvs.size() == 7); + CHECK(spaces[shader.FindSpace(1000)].constantBuffers.size() == 2); + } +} + +#endif \ No newline at end of file diff --git a/renderdoc/driver/d3d12/d3d12_shader_cache.cpp b/renderdoc/driver/d3d12/d3d12_shader_cache.cpp index 6d401d7f1..5cc8f4b0b 100644 --- a/renderdoc/driver/d3d12/d3d12_shader_cache.cpp +++ b/renderdoc/driver/d3d12/d3d12_shader_cache.cpp @@ -216,7 +216,7 @@ D3D12RootSignature D3D12ShaderCache::GetRootSig(const void *data, size_t dataSiz for(size_t i = 0; i < ret.params.size(); i++) { - ret.params[i].MakeFrom(desc->pParameters[i], ret.numSpaces); + ret.params[i].MakeFrom(desc->pParameters[i], ret.maxSpaceIndex); // Descriptor tables cost 1 DWORD each. // Root constants cost 1 DWORD each, since they are 32-bit values. @@ -234,7 +234,7 @@ D3D12RootSignature D3D12ShaderCache::GetRootSig(const void *data, size_t dataSiz ret.samplers.assign(desc->pStaticSamplers, desc->pStaticSamplers + desc->NumStaticSamplers); for(size_t i = 0; i < ret.samplers.size(); i++) - ret.numSpaces = RDCMAX(ret.numSpaces, ret.samplers[i].RegisterSpace + 1); + ret.maxSpaceIndex = RDCMAX(ret.maxSpaceIndex, ret.samplers[i].RegisterSpace + 1); } SAFE_RELEASE(deser); @@ -274,7 +274,7 @@ D3D12RootSignature D3D12ShaderCache::GetRootSig(const void *data, size_t dataSiz for(size_t i = 0; i < ret.params.size(); i++) { - ret.params[i].MakeFrom(desc->pParameters[i], ret.numSpaces); + ret.params[i].MakeFrom(desc->pParameters[i], ret.maxSpaceIndex); // Descriptor tables cost 1 DWORD each. // Root constants cost 1 DWORD each, since they are 32-bit values. @@ -292,7 +292,7 @@ D3D12RootSignature D3D12ShaderCache::GetRootSig(const void *data, size_t dataSiz ret.samplers.assign(desc->pStaticSamplers, desc->pStaticSamplers + desc->NumStaticSamplers); for(size_t i = 0; i < ret.samplers.size(); i++) - ret.numSpaces = RDCMAX(ret.numSpaces, ret.samplers[i].RegisterSpace + 1); + ret.maxSpaceIndex = RDCMAX(ret.maxSpaceIndex, ret.samplers[i].RegisterSpace + 1); } SAFE_RELEASE(deser); diff --git a/renderdoc/replay/renderdoc_serialise.inl b/renderdoc/replay/renderdoc_serialise.inl index a080e8f1d..91f6611f0 100644 --- a/renderdoc/replay/renderdoc_serialise.inl +++ b/renderdoc/replay/renderdoc_serialise.inl @@ -1303,12 +1303,13 @@ void DoSerialise(SerialiserType &ser, D3D12Pipe::ConstantBuffer &el) template void DoSerialise(SerialiserType &ser, D3D12Pipe::RegisterSpace &el) { + SERIALISE_MEMBER(spaceIndex); SERIALISE_MEMBER(constantBuffers); SERIALISE_MEMBER(samplers); SERIALISE_MEMBER(srvs); SERIALISE_MEMBER(uavs); - SIZE_CHECK(64); + SIZE_CHECK(72); } template