diff --git a/renderdoc/driver/d3d12/d3d12_command_list.h b/renderdoc/driver/d3d12/d3d12_command_list.h index 6c12583b9..73b578f6e 100644 --- a/renderdoc/driver/d3d12/d3d12_command_list.h +++ b/renderdoc/driver/d3d12/d3d12_command_list.h @@ -227,11 +227,11 @@ public: D3D12ResourceRecord *GetResourceRecord() { return m_ListRecord; } D3D12ResourceRecord *GetCreationRecord() { return m_CreationRecord; } - void FinaliseExecuteIndirectEvents(BakedCmdListInfo &info, BakedCmdListInfo::ExecuteData &exec); - void SaveExecuteIndirectParameters(ID3D12GraphicsCommandListX *list, - ID3D12CommandSignature *pCommandSignature, UINT MaxCommandCount, - ID3D12Resource *pArgumentBuffer, UINT64 ArgumentBufferOffset, - ID3D12Resource *pCountBuffer, UINT64 CountBufferOffset); + void FinaliseExecuteIndirectEvents(BakedCmdListInfo &info, size_t nodeIdx); + D3D12ExecuteData SaveExecuteIndirectParameters( + ID3D12GraphicsCommandListX *list, ID3D12CommandSignature *pCommandSignature, + UINT MaxCommandCount, ID3D12Resource *pArgumentBuffer, UINT64 ArgumentBufferOffset, + ID3D12Resource *pCountBuffer, UINT64 CountBufferOffset); void ResetAndRecordExecuteIndirectStates(ID3D12GraphicsCommandListX *list, uint32_t baseEventID, uint32_t execCount, ID3D12CommandSignature *pCommandSignature, diff --git a/renderdoc/driver/d3d12/d3d12_command_list1_wrap.cpp b/renderdoc/driver/d3d12/d3d12_command_list1_wrap.cpp index c9714de19..722a3296c 100644 --- a/renderdoc/driver/d3d12/d3d12_command_list1_wrap.cpp +++ b/renderdoc/driver/d3d12/d3d12_command_list1_wrap.cpp @@ -91,19 +91,18 @@ bool WrappedID3D12GraphicsCommandList::Serialise_AtomicCopyBufferUINT( m_Cmd->AddAction(action); - D3D12ActionTreeNode &actionNode = m_Cmd->GetActionStack().back()->children.back(); + D3D12EventNode &eventNode = m_Cmd->GetLastEventNode(); if(pSrcBuffer == pDstBuffer) { - actionNode.resourceUsage.push_back(make_rdcpair( - GetResID(pSrcBuffer), EventUsage(actionNode.action.eventId, ResourceUsage::Copy))); + eventNode.resourceUsage.push_back(make_rdcpair(GetResID(pSrcBuffer), ResourceUsage::Copy)); } else { - actionNode.resourceUsage.push_back(make_rdcpair( - GetResID(pSrcBuffer), EventUsage(actionNode.action.eventId, ResourceUsage::CopySrc))); - actionNode.resourceUsage.push_back(make_rdcpair( - GetResID(pDstBuffer), EventUsage(actionNode.action.eventId, ResourceUsage::CopyDst))); + eventNode.resourceUsage.push_back( + make_rdcpair(GetResID(pSrcBuffer), ResourceUsage::CopySrc)); + eventNode.resourceUsage.push_back( + make_rdcpair(GetResID(pDstBuffer), ResourceUsage::CopyDst)); } } } @@ -204,19 +203,18 @@ bool WrappedID3D12GraphicsCommandList::Serialise_AtomicCopyBufferUINT64( m_Cmd->AddAction(action); - D3D12ActionTreeNode &actionNode = m_Cmd->GetActionStack().back()->children.back(); + D3D12EventNode &eventNode = m_Cmd->GetLastEventNode(); if(pSrcBuffer == pDstBuffer) { - actionNode.resourceUsage.push_back(make_rdcpair( - GetResID(pSrcBuffer), EventUsage(actionNode.action.eventId, ResourceUsage::Copy))); + eventNode.resourceUsage.push_back(make_rdcpair(GetResID(pSrcBuffer), ResourceUsage::Copy)); } else { - actionNode.resourceUsage.push_back(make_rdcpair( - GetResID(pSrcBuffer), EventUsage(actionNode.action.eventId, ResourceUsage::CopySrc))); - actionNode.resourceUsage.push_back(make_rdcpair( - GetResID(pDstBuffer), EventUsage(actionNode.action.eventId, ResourceUsage::CopyDst))); + eventNode.resourceUsage.push_back( + make_rdcpair(GetResID(pSrcBuffer), ResourceUsage::CopySrc)); + eventNode.resourceUsage.push_back( + make_rdcpair(GetResID(pDstBuffer), ResourceUsage::CopyDst)); } } } @@ -487,21 +485,19 @@ bool WrappedID3D12GraphicsCommandList::Serialise_ResolveSubresourceRegion( m_Cmd->AddAction(action); - D3D12ActionTreeNode &actionNode = m_Cmd->GetActionStack().back()->children.back(); + D3D12EventNode &eventNode = m_Cmd->GetLastEventNode(); if(pSrcResource == pDstResource) { - actionNode.resourceUsage.push_back(make_rdcpair( - GetResID(pSrcResource), EventUsage(actionNode.action.eventId, ResourceUsage::Resolve))); + eventNode.resourceUsage.push_back( + make_rdcpair(GetResID(pSrcResource), ResourceUsage::Resolve)); } else { - actionNode.resourceUsage.push_back( - make_rdcpair(GetResID(pSrcResource), - EventUsage(actionNode.action.eventId, ResourceUsage::ResolveSrc))); - actionNode.resourceUsage.push_back( - make_rdcpair(GetResID(pDstResource), - EventUsage(actionNode.action.eventId, ResourceUsage::ResolveDst))); + eventNode.resourceUsage.push_back( + make_rdcpair(GetResID(pSrcResource), ResourceUsage::ResolveSrc)); + eventNode.resourceUsage.push_back( + make_rdcpair(GetResID(pDstResource), ResourceUsage::ResolveDst)); } } } diff --git a/renderdoc/driver/d3d12/d3d12_command_list4_wrap.cpp b/renderdoc/driver/d3d12/d3d12_command_list4_wrap.cpp index 53ddd49a9..4ab2b1af0 100644 --- a/renderdoc/driver/d3d12/d3d12_command_list4_wrap.cpp +++ b/renderdoc/driver/d3d12/d3d12_command_list4_wrap.cpp @@ -1397,15 +1397,16 @@ bool WrappedID3D12GraphicsCommandList::Serialise_EmitRaytracingAccelerationStruc m_Cmd->AddAction(action); - D3D12ActionTreeNode &actionNode = m_Cmd->GetActionStack().back()->children.back(); + D3D12EventNode &eventNode = m_Cmd->GetLastEventNode(); - actionNode.resourceUsage.push_back( - make_rdcpair(WrappedID3D12Resource::GetResIDFromAddr(Desc.DestBuffer), - EventUsage(actionNode.action.eventId, ResourceUsage::CopyDst))); + eventNode.resourceUsage.push_back(make_rdcpair( + WrappedID3D12Resource::GetResIDFromAddr(Desc.DestBuffer), ResourceUsage::CopyDst)); for(UINT i = 0; i < NumSourceAccelerationStructures; i++) - actionNode.resourceUsage.push_back(make_rdcpair( + { + eventNode.resourceUsage.push_back(make_rdcpair( WrappedID3D12Resource::GetResIDFromAddr(pSourceAccelerationStructureData[i]), - EventUsage(actionNode.action.eventId, ResourceUsage::CopySrc))); + ResourceUsage::CopySrc)); + } } } diff --git a/renderdoc/driver/d3d12/d3d12_command_list7_wrap.cpp b/renderdoc/driver/d3d12/d3d12_command_list7_wrap.cpp index 8e06c2dc6..79a4baf08 100644 --- a/renderdoc/driver/d3d12/d3d12_command_list7_wrap.cpp +++ b/renderdoc/driver/d3d12/d3d12_command_list7_wrap.cpp @@ -63,7 +63,7 @@ bool WrappedID3D12GraphicsCommandList::Serialise_Barrier(SerialiserType &ser, UI D3D12_TEXTURE_BARRIER *tex = filteredUnwrappedTex.data(); D3D12_BUFFER_BARRIER *buf = filteredUnwrappedBuf.data(); - BakedCmdListInfo &cmdinfo = m_Cmd->m_BakedCmdListInfo[m_Cmd->m_LastCmdListID]; + D3D12EventNode &eventNode = m_Cmd->m_LoadingEventNode; // filter out any barriers that reference a NULL resource - this means the resource wasn't used // elsewhere so was discarded from the capture @@ -86,8 +86,8 @@ bool WrappedID3D12GraphicsCommandList::Serialise_Barrier(SerialiserType &ser, UI buf[group.NumBarriers].pResource = Unwrap(res); group.NumBarriers++; - cmdinfo.resourceUsage.push_back(make_rdcpair( - GetResID(res), EventUsage(cmdinfo.curEventID, ResourceUsage::Barrier))); + if(IsLoading(m_State)) + eventNode.resourceUsage.push_back(make_rdcpair(GetResID(res), ResourceUsage::Barrier)); } } @@ -112,8 +112,8 @@ bool WrappedID3D12GraphicsCommandList::Serialise_Barrier(SerialiserType &ser, UI tex[group.NumBarriers].pResource = Unwrap(res); group.NumBarriers++; - cmdinfo.resourceUsage.push_back(make_rdcpair( - GetResID(res), EventUsage(cmdinfo.curEventID, ResourceUsage::Barrier))); + if(IsLoading(m_State)) + eventNode.resourceUsage.push_back(make_rdcpair(GetResID(res), ResourceUsage::Barrier)); } } diff --git a/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp b/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp index d850b9206..cc6ca53bf 100644 --- a/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp +++ b/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp @@ -95,11 +95,6 @@ bool WrappedID3D12GraphicsCommandList::Serialise_Close(SerialiserType &ser) { GetResourceManager()->GetResAs(CommandList)->Close(); - { - if(m_Cmd->GetActionStack().size() > 1) - m_Cmd->GetActionStack().pop_back(); - } - BakedCmdListInfo &baked = m_Cmd->m_BakedCmdListInfo[BakedCommandList]; BakedCmdListInfo &parent = m_Cmd->m_BakedCmdListInfo[CommandList]; @@ -111,7 +106,6 @@ bool WrappedID3D12GraphicsCommandList::Serialise_Close(SerialiserType &ser) parent.curEventID = 0; parent.eventCount = 0; - parent.actionCount = 0; } } @@ -290,8 +284,6 @@ bool WrappedID3D12GraphicsCommandList::Serialise_Reset(SerialiserType &ser, m_Cmd->m_BakedCmdListInfo[BakedCommandList].markerCount = 0; m_Cmd->m_BakedCmdListInfo[CommandList].curEventID = m_Cmd->m_BakedCmdListInfo[BakedCommandList].curEventID = 0; - m_Cmd->m_BakedCmdListInfo[CommandList].executeEvents = - m_Cmd->m_BakedCmdListInfo[BakedCommandList].executeEvents; m_Cmd->m_BakedCmdListInfo[CommandList].barriers.clear(); m_Cmd->m_BakedCmdListInfo[BakedCommandList].barriers.clear(); } @@ -337,9 +329,6 @@ bool WrappedID3D12GraphicsCommandList::Serialise_Reset(SerialiserType &ser, } { - D3D12ActionTreeNode *action = new D3D12ActionTreeNode; - m_Cmd->m_BakedCmdListInfo[BakedCommandList].action = action; - m_Cmd->m_BakedCmdListInfo[CommandList].type = m_Cmd->m_BakedCmdListInfo[BakedCommandList].type = type; m_Cmd->m_BakedCmdListInfo[CommandList].nodeMask = @@ -353,9 +342,6 @@ bool WrappedID3D12GraphicsCommandList::Serialise_Reset(SerialiserType &ser, // m_RootEventID and insert them into the tree. m_Cmd->m_BakedCmdListInfo[BakedCommandList].curEventID = 0; m_Cmd->m_BakedCmdListInfo[BakedCommandList].eventCount = 0; - m_Cmd->m_BakedCmdListInfo[BakedCommandList].actionCount = 0; - - m_Cmd->m_BakedCmdListInfo[BakedCommandList].actionStack.push_back(action); m_Cmd->m_BakedCmdListInfo[BakedCommandList].beginChunk = uint32_t(m_Cmd->m_StructuredFile->chunks.size() - 1); @@ -524,17 +510,15 @@ bool WrappedID3D12GraphicsCommandList::Serialise_ResourceBarrier( if(IsLoading(m_State) && (res1 || res2)) { - BakedCmdListInfo &cmdinfo = m_Cmd->m_BakedCmdListInfo[m_Cmd->m_LastCmdListID]; + D3D12EventNode &eventNode = m_Cmd->m_LoadingEventNode; if(res1) { - cmdinfo.resourceUsage.push_back(make_rdcpair( - GetResID(res1), EventUsage(cmdinfo.curEventID, ResourceUsage::Barrier))); + eventNode.resourceUsage.push_back(make_rdcpair(GetResID(res1), ResourceUsage::Barrier)); } if(res2) { - cmdinfo.resourceUsage.push_back(make_rdcpair( - GetResID(res2), EventUsage(cmdinfo.curEventID, ResourceUsage::Barrier))); + eventNode.resourceUsage.push_back(make_rdcpair(GetResID(res2), ResourceUsage::Barrier)); } } } @@ -3032,11 +3016,9 @@ bool WrappedID3D12GraphicsCommandList::Serialise_ResolveQueryData( m_Cmd->AddAction(action); - D3D12ActionTreeNode &actionNode = m_Cmd->GetActionStack().back()->children.back(); - - actionNode.resourceUsage.push_back( - make_rdcpair(GetResID(pDestinationBuffer), - EventUsage(actionNode.action.eventId, ResourceUsage::ResolveDst))); + D3D12EventNode &eventNode = m_Cmd->GetLastEventNode(); + eventNode.resourceUsage.push_back( + make_rdcpair(GetResID(pDestinationBuffer), ResourceUsage::ResolveDst)); } } } @@ -3368,10 +3350,8 @@ bool WrappedID3D12GraphicsCommandList::Serialise_SetCommandAnnotation( ResourceId cmdId = GetResID(pCommandList); - PendingAnnotation annot = {m_Cmd->m_BakedCmdListInfo[m_Cmd->m_LastCmdListID].curEventID, key, - valueType, valueVectorWidth, value}; - - m_Cmd->m_BakedCmdListInfo[m_Cmd->m_LastCmdListID].annotations.push_back(annot); + PendingAnnotation annot = {0, key, valueType, valueVectorWidth, value}; + m_Cmd->m_BakedCmdListInfo[m_Cmd->m_LastCmdListID].pendingAnnotations.push_back(annot); m_pDevice->GetReplay()->WriteFrameRecord().frameInfo.containsAnnotations = true; } @@ -3685,15 +3665,13 @@ void WrappedID3D12GraphicsCommandList::ExecuteBundle(ID3D12GraphicsCommandList * } } -void WrappedID3D12GraphicsCommandList::SaveExecuteIndirectParameters( +D3D12ExecuteData WrappedID3D12GraphicsCommandList::SaveExecuteIndirectParameters( ID3D12GraphicsCommandListX *list, ID3D12CommandSignature *pCommandSignature, UINT MaxCommandCount, ID3D12Resource *pArgumentBuffer, UINT64 ArgumentBufferOffset, ID3D12Resource *pCountBuffer, UINT64 CountBufferOffset) { WrappedID3D12CommandSignature *comSig = (WrappedID3D12CommandSignature *)pCommandSignature; - BakedCmdListInfo &cmdListInfo = m_Cmd->m_BakedCmdListInfo[m_Cmd->m_LastCmdListID]; - const size_t argsSize = comSig->sig.ByteStride * (RDCMAX(1U, MaxCommandCount) - 1) + comSig->sig.PackedByteSize; const size_t countSize = 16; @@ -3709,10 +3687,12 @@ void WrappedID3D12GraphicsCommandList::SaveExecuteIndirectParameters( Unwrap(list)->CopyBufferRegion(Unwrap(buf), offs + countSize, Unwrap(pArgumentBuffer), ArgumentBufferOffset, argsSize); - BakedCmdListInfo::ExecuteData exec = {}; - exec.baseEvent = cmdListInfo.curEventID; + D3D12ExecuteData exec = {}; exec.sig = comSig; exec.maxCount = MaxCommandCount; + // For variable count indirects only allocate up to one indirect command to avoid pessimistic + // allocation if MaxCommandCount is very high but the actual action count is low. + exec.reservedCount = pCountBuffer ? RDCMIN(1U, MaxCommandCount) : MaxCommandCount; if(pCountBuffer) { exec.countBuf = buf; @@ -3721,7 +3701,7 @@ void WrappedID3D12GraphicsCommandList::SaveExecuteIndirectParameters( exec.argBuf = buf; exec.argOffs = offs + 16; - cmdListInfo.executeEvents.push_back(exec); + return exec; } void WrappedID3D12GraphicsCommandList::ResetAndRecordExecuteIndirectStates( @@ -3835,8 +3815,12 @@ void WrappedID3D12GraphicsCommandList::ResetAndRecordExecuteIndirectStates( } void WrappedID3D12GraphicsCommandList::FinaliseExecuteIndirectEvents(BakedCmdListInfo &info, - BakedCmdListInfo::ExecuteData &exec) + size_t nodeIdx) { + rdcarray &eventNodes = info.eventNodes; + D3D12EventNode &baseActionNode = eventNodes[nodeIdx]; + const D3D12ExecuteData &exec = baseActionNode.executeData; + WrappedID3D12CommandSignature *comSig = exec.sig; uint32_t count = exec.maxCount; @@ -3861,40 +3845,72 @@ void WrappedID3D12GraphicsCommandList::FinaliseExecuteIndirectEvents(BakedCmdLis if(m_pDevice->HasFatalError()) return; - rdcarray &actions = info.action->children; - - size_t idx = 0; - uint32_t eid = exec.baseEvent; - - uint32_t firstActionEid = eid; - - // find the action where our execute begins - for(; idx < actions.size(); idx++) - if(actions[idx].action.eventId == firstActionEid) - break; - - RDCASSERTMSG("Couldn't find base event action!", idx < actions.size(), idx, actions.size()); - // patch the name for the base action - actions[idx].action.customName = + baseActionNode.action.customName = StringFormat::Fmt("ExecuteIndirect(maxCount %u, count <%u>)", exec.maxCount, count); - // move to the first actual action of the commands + // move to the first actual event of the commands + size_t idx = nodeIdx; idx++; - eid++; D3D12RenderState state; SDChunk *baseChunk = NULL; + SDFile *sdFile = m_Cmd->m_StructuredFile; if(count > 0) { - RDCASSERT(actions[idx].state); + size_t firstAction = idx; + // Find the first action (which should have state) + for(uint32_t a = 0; a < sigSize; ++a) + { + if(eventNodes[firstAction].action.actionId == UINT32_MAX) + break; + firstAction++; + } + RDCASSERT(eventNodes[firstAction].state); + state = *eventNodes[firstAction].state; - state = *actions[idx].state; - baseChunk = m_Cmd->m_StructuredFile->chunks[actions[idx].action.events[0].chunkIndex]; + baseChunk = m_Cmd->m_StructuredFile->chunks[eventNodes[idx].event.chunkIndex]; + } + // this can be negative if count is 0 + int32_t countExtraActions = count - exec.reservedCount; + // exec.reservedCount copies of the signatuire were reserved for the indirect count actions + // if we ended up with a different number countExtraNodes will be non-zero, + // we need to adjust and either remove the nodes we allocated (if no actions happened) + // or clone the nodes to create more that we can then patch. + if(countExtraActions != 0) + { + if(count == 0) + { + // idx is the start of the signature nodes + eventNodes.erase(idx, sigSize); + } + else if(countExtraActions > 0) + { + size_t baseCommandStart = idx; + // We need to clone the signature nodes countExtraNode times + size_t countExtraNodes = countExtraActions * sigSize; + sdFile->chunks.reserve(sdFile->chunks.size() + countExtraNodes); + // Insert space for the new nodes + eventNodes.resize(eventNodes.size() + countExtraNodes); + size_t endActionNode = idx + sigSize; + for(size_t e = eventNodes.size() - 1; e > endActionNode; e--) + eventNodes[e] = std::move(eventNodes[e - countExtraNodes]); + + size_t newIdx = endActionNode; + for(size_t extra = 0; extra < countExtraNodes; ++extra) + { + for(uint32_t a = 0; a < sigSize; ++a) + { + // duplicate the base node + eventNodes[newIdx++] = eventNodes[baseCommandStart + a]; + } + } + } } + size_t countNodes = eventNodes.size(); for(uint32_t i = 0; i < count; i++) { byte *data = mapPtr + exec.argOffs; @@ -3904,26 +3920,14 @@ void WrappedID3D12GraphicsCommandList::FinaliseExecuteIndirectEvents(BakedCmdLis { const D3D12_INDIRECT_ARGUMENT_DESC &arg = comSig->sig.arguments[a]; - ActionDescription &curAction = actions[idx].action; - - APIEvent *curEvent = NULL; - - for(APIEvent &ev : curAction.events) + if(idx >= countNodes) { - if(ev.eventId == eid) - { - curEvent = &ev; - break; - } + RDCERR("Couldn't find child event %u in current action while patching ExecuteIndirect", idx); + break; } - APIEvent dummy; - if(!curEvent) - { - RDCERR("Couldn't find EID %u in current action while patching ExecuteIndirect", eid); - // assign a dummy so we don't have to NULL-check below - curEvent = &dummy; - } + D3D12EventNode &eventNode = eventNodes[idx]; + ActionDescription &curAction = eventNodes[idx].action; SDChunk *fakeChunk = new SDChunk(""_lit); fakeChunk->metadata = baseChunk->metadata; @@ -3958,17 +3962,7 @@ void WrappedID3D12GraphicsCommandList::FinaliseExecuteIndirectEvents(BakedCmdLis structuriser.Serialise("ArgumentData"_lit, *args).Important(); - // if this is the first action of the indirect, we could have picked up previous - // non-indirect events in this action, so the EID will be higher than we expect. Just - // assign the action's EID - eid = curAction.eventId; - - m_Cmd->AddUsage(state, actions[idx]); - - // advance - idx++; - eid++; - + m_Cmd->AddUsage(state, eventNode); break; } case D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED: @@ -3991,17 +3985,7 @@ void WrappedID3D12GraphicsCommandList::FinaliseExecuteIndirectEvents(BakedCmdLis structuriser.Serialise("ArgumentData"_lit, *args).Important(); - // if this is the first action of the indirect, we could have picked up previous - // non-indirect events in this action, so the EID will be higher than we expect. Just - // assign the action's EID - eid = curAction.eventId; - - m_Cmd->AddUsage(state, actions[idx]); - - // advance - idx++; - eid++; - + m_Cmd->AddUsage(state, eventNode); break; } case D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH: @@ -4021,17 +4005,7 @@ void WrappedID3D12GraphicsCommandList::FinaliseExecuteIndirectEvents(BakedCmdLis structuriser.Serialise("ArgumentData"_lit, *args).Important(); - // if this is the first action of the indirect, we could have picked up previous - // non-indirect events in this action, so the EID will be higher than we expect. Just - // assign the action's EID - eid = curAction.eventId; - - m_Cmd->AddUsage(state, actions[idx]); - - // advance - idx++; - eid++; - + m_Cmd->AddUsage(state, eventNode); break; } case D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH_MESH: @@ -4052,17 +4026,7 @@ void WrappedID3D12GraphicsCommandList::FinaliseExecuteIndirectEvents(BakedCmdLis structuriser.Serialise("ArgumentData"_lit, *args).Important(); - // if this is the first action of the indirect, we could have picked up previous - // non-indirect events in this action, so the EID will be higher than we expect. Just - // assign the action's EID - eid = curAction.eventId; - - m_Cmd->AddUsage(state, actions[idx]); - - // advance - idx++; - eid++; - + m_Cmd->AddUsage(state, eventNode); break; } case D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH_RAYS: @@ -4100,17 +4064,7 @@ void WrappedID3D12GraphicsCommandList::FinaliseExecuteIndirectEvents(BakedCmdLis structuriser.Serialise("ArgumentData"_lit, *args).Important(); - // if this is the first action of the indirect, we could have picked up previous - // non-indirect events in this action, so the EID will be higher than we expect. Just - // assign the action's EID - eid = curAction.eventId; - - m_Cmd->AddUsage(state, actions[idx]); - - // advance - idx++; - eid++; - + m_Cmd->AddUsage(state, eventNode); break; } case D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT: @@ -4134,14 +4088,11 @@ void WrappedID3D12GraphicsCommandList::FinaliseExecuteIndirectEvents(BakedCmdLis state.compute.sigelems[arg.Constant.RootParameterIndex].SetConstants( arg.Constant.Num32BitValuesToSet, data32, arg.Constant.DestOffsetIn32BitValues); } - - // advance only the EID, since we're still in the same action - eid++; - break; } case D3D12_INDIRECT_ARGUMENT_TYPE_VERTEX_BUFFER_VIEW: { + // This modifies the mapped data via vb D3D12_VERTEX_BUFFER_VIEW *vb = (D3D12_VERTEX_BUFFER_VIEW *)data; data += sizeof(D3D12_VERTEX_BUFFER_VIEW); @@ -4165,10 +4116,6 @@ void WrappedID3D12GraphicsCommandList::FinaliseExecuteIndirectEvents(BakedCmdLis fakeChunk->name = StringFormat::Fmt("[%u] arg%u: IndirectIASetVertexBuffer", i, a); structuriser.Serialise("ArgumentData"_lit, *vb).Important(); - - // advance only the EID, since we're still in the same action - eid++; - break; } case D3D12_INDIRECT_ARGUMENT_TYPE_INDEX_BUFFER_VIEW: @@ -4193,10 +4140,6 @@ void WrappedID3D12GraphicsCommandList::FinaliseExecuteIndirectEvents(BakedCmdLis fakeChunk->name = StringFormat::Fmt("[%u] arg%u: IndirectIASetIndexBuffer", i, a); structuriser.Serialise("ArgumentData"_lit, *ib).Important(); - - // advance only the EID, since we're still in the same action - eid++; - break; } case D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT_BUFFER_VIEW: @@ -4243,42 +4186,22 @@ void WrappedID3D12GraphicsCommandList::FinaliseExecuteIndirectEvents(BakedCmdLis D3D12BufferLocation buf = *addr; structuriser.Serialise("ArgumentData"_lit, buf).Important(); - - // advance only the EID, since we're still in the same action - eid++; - break; } default: RDCERR("Unexpected argument type! %d", arg.Type); break; } } + // Set the chunk data + sdFile->chunks.push_back(fakeChunk); - m_Cmd->m_StructuredFile->chunks.push_back(fakeChunk); + eventNode.event.chunkIndex = uint32_t(sdFile->chunks.size() - 1); - curEvent->chunkIndex = uint32_t(m_Cmd->m_StructuredFile->chunks.size() - 1); + ++idx; } } range.End = range.Begin = 0; exec.argBuf->Unmap(0, &range); - - // remove excesss actions if count < maxCount - if(count < exec.maxCount) - { - uint32_t shiftEID = (exec.maxCount - count) * sigSize; - uint32_t lastEID = exec.baseEvent + 1 + sigSize * exec.maxCount; - - uint32_t shiftActionID = 0; - - while(idx + shiftActionID < actions.size() && - actions[idx + shiftActionID].action.eventId < lastEID) - shiftActionID++; - - actions.erase(idx, shiftActionID); - - // shift all subsequent EIDs and action IDs so they're contiguous - info.ShiftForRemoved(shiftActionID, shiftEID, idx); - } } template @@ -4579,8 +4502,9 @@ bool WrappedID3D12GraphicsCommandList::Serialise_ExecuteIndirect( barriers.Apply(list); - SaveExecuteIndirectParameters(list, pCommandSignature, MaxCommandCount, pArgumentBuffer, - ArgumentBufferOffset, pCountBuffer, CountBufferOffset); + D3D12ExecuteData execData = + SaveExecuteIndirectParameters(list, pCommandSignature, MaxCommandCount, pArgumentBuffer, + ArgumentBufferOffset, pCountBuffer, CountBufferOffset); barriers.Unapply(list); @@ -4629,19 +4553,25 @@ bool WrappedID3D12GraphicsCommandList::Serialise_ExecuteIndirect( action.flags |= ActionFlags::MultiAction | ActionFlags::PushMarker; m_Cmd->AddAction(action); - cmdInfo.curEventID++; - D3D12ActionTreeNode &actionNode = m_Cmd->GetActionStack().back()->children.back(); + D3D12EventNode &eventNode = m_Cmd->GetLastEventNode(); + eventNode.executeData = execData; + eventNode.hasExecuteData = true; + cmdInfo.hasExecuteDatas = true; - actionNode.resourceUsage.push_back( - make_rdcpair(GetResID(pArgumentBuffer), - EventUsage(actionNode.action.eventId, ResourceUsage::Indirect))); + eventNode.resourceUsage.push_back( + make_rdcpair(GetResID(pArgumentBuffer), ResourceUsage::Indirect)); if(pCountBuffer) - actionNode.resourceUsage.push_back(make_rdcpair( - GetResID(pCountBuffer), EventUsage(actionNode.action.eventId, ResourceUsage::Indirect))); + { + eventNode.resourceUsage.push_back( + make_rdcpair(GetResID(pCountBuffer), ResourceUsage::Indirect)); + } } - for(uint32_t i = 0; i < MaxCommandCount; i++) + // For variable count indirects only allocate up to one indirect command to avoid pessimistic + // allocation if MaxCommandCount is very high but the actual action count is low. + uint32_t maxCountCmds = execData.reservedCount; + for(uint32_t i = 0; i < maxCountCmds; i++) { for(uint32_t a = 0; a < sigSize; a++) { @@ -4660,9 +4590,8 @@ bool WrappedID3D12GraphicsCommandList::Serialise_ExecuteIndirect( ActionDescription action; action.customName = "ExecuteIndirect"; m_Cmd->AddAction(action); - m_Cmd->GetActionStack().back()->children.back().state = - new D3D12RenderState(cmdInfo.state); - cmdInfo.curEventID++; + D3D12EventNode &eventNode = m_Cmd->GetLastEventNode(); + eventNode.state = new D3D12RenderState(cmdInfo.state); break; } case D3D12_INDIRECT_ARGUMENT_TYPE_VERTEX_BUFFER_VIEW: @@ -4673,7 +4602,6 @@ bool WrappedID3D12GraphicsCommandList::Serialise_ExecuteIndirect( case D3D12_INDIRECT_ARGUMENT_TYPE_UNORDERED_ACCESS_VIEW: // add dummy event m_Cmd->AddEvent(); - cmdInfo.curEventID++; break; default: RDCERR("Unexpected argument type! %d", arg.Type); break; } @@ -4835,11 +4763,9 @@ bool WrappedID3D12GraphicsCommandList::Serialise_ClearDepthStencilView( Subresource(GetMipForDsv(descriptor->GetDSV()), GetSliceForDsv(descriptor->GetDSV())); m_Cmd->AddAction(action); - D3D12ActionTreeNode &actionNode = m_Cmd->GetActionStack().back()->children.back(); - - actionNode.resourceUsage.push_back( - make_rdcpair(descriptor->GetResResourceId(), - EventUsage(actionNode.action.eventId, ResourceUsage::Clear))); + D3D12EventNode &eventNode = m_Cmd->GetLastEventNode(); + eventNode.resourceUsage.push_back( + make_rdcpair(descriptor->GetResResourceId(), ResourceUsage::Clear)); } } } @@ -4936,11 +4862,9 @@ bool WrappedID3D12GraphicsCommandList::Serialise_ClearRenderTargetView( Subresource(GetMipForRtv(descriptor->GetRTV()), GetSliceForRtv(descriptor->GetRTV())); m_Cmd->AddAction(action); - D3D12ActionTreeNode &actionNode = m_Cmd->GetActionStack().back()->children.back(); - - actionNode.resourceUsage.push_back( - make_rdcpair(descriptor->GetResResourceId(), - EventUsage(actionNode.action.eventId, ResourceUsage::Clear))); + D3D12EventNode &eventNode = m_Cmd->GetLastEventNode(); + eventNode.resourceUsage.push_back( + make_rdcpair(descriptor->GetResResourceId(), ResourceUsage::Clear)); } } } @@ -5040,10 +4964,8 @@ bool WrappedID3D12GraphicsCommandList::Serialise_ClearUnorderedAccessViewUint( m_Cmd->AddAction(action); - D3D12ActionTreeNode &actionNode = m_Cmd->GetActionStack().back()->children.back(); - - actionNode.resourceUsage.push_back(make_rdcpair( - GetResID(pResource), EventUsage(actionNode.action.eventId, ResourceUsage::Clear))); + D3D12EventNode &eventNode = m_Cmd->GetLastEventNode(); + eventNode.resourceUsage.push_back(make_rdcpair(GetResID(pResource), ResourceUsage::Clear)); } } } @@ -5151,10 +5073,8 @@ bool WrappedID3D12GraphicsCommandList::Serialise_ClearUnorderedAccessViewFloat( m_Cmd->AddAction(action); - D3D12ActionTreeNode &actionNode = m_Cmd->GetActionStack().back()->children.back(); - - actionNode.resourceUsage.push_back(make_rdcpair( - GetResID(pResource), EventUsage(actionNode.action.eventId, ResourceUsage::Clear))); + D3D12EventNode &eventNode = m_Cmd->GetLastEventNode(); + eventNode.resourceUsage.push_back(make_rdcpair(GetResID(pResource), ResourceUsage::Clear)); } } } @@ -5240,10 +5160,8 @@ bool WrappedID3D12GraphicsCommandList::Serialise_DiscardResource(SerialiserType m_Cmd->AddAction(action); - D3D12ActionTreeNode &actionNode = m_Cmd->GetActionStack().back()->children.back(); - - actionNode.resourceUsage.push_back(make_rdcpair( - GetResID(pResource), EventUsage(actionNode.action.eventId, ResourceUsage::Discard))); + D3D12EventNode &eventNode = m_Cmd->GetLastEventNode(); + eventNode.resourceUsage.push_back(make_rdcpair(GetResID(pResource), ResourceUsage::Discard)); } } } @@ -5327,19 +5245,18 @@ bool WrappedID3D12GraphicsCommandList::Serialise_CopyBufferRegion(SerialiserType m_Cmd->AddAction(action); - D3D12ActionTreeNode &actionNode = m_Cmd->GetActionStack().back()->children.back(); + D3D12EventNode &eventNode = m_Cmd->GetLastEventNode(); if(pSrcBuffer == pDstBuffer) { - actionNode.resourceUsage.push_back(make_rdcpair( - GetResID(pSrcBuffer), EventUsage(actionNode.action.eventId, ResourceUsage::Copy))); + eventNode.resourceUsage.push_back(make_rdcpair(GetResID(pSrcBuffer), ResourceUsage::Copy)); } else { - actionNode.resourceUsage.push_back(make_rdcpair( - GetResID(pSrcBuffer), EventUsage(actionNode.action.eventId, ResourceUsage::CopySrc))); - actionNode.resourceUsage.push_back(make_rdcpair( - GetResID(pDstBuffer), EventUsage(actionNode.action.eventId, ResourceUsage::CopyDst))); + eventNode.resourceUsage.push_back( + make_rdcpair(GetResID(pSrcBuffer), ResourceUsage::CopySrc)); + eventNode.resourceUsage.push_back( + make_rdcpair(GetResID(pDstBuffer), ResourceUsage::CopyDst)); } } } @@ -5444,19 +5361,16 @@ bool WrappedID3D12GraphicsCommandList::Serialise_CopyTextureRegion( m_Cmd->AddAction(action); - D3D12ActionTreeNode &actionNode = m_Cmd->GetActionStack().back()->children.back(); + D3D12EventNode &eventNode = m_Cmd->GetLastEventNode(); if(origSrc == origDst) { - actionNode.resourceUsage.push_back( - make_rdcpair(liveSrc, EventUsage(actionNode.action.eventId, ResourceUsage::Copy))); + eventNode.resourceUsage.push_back(make_rdcpair(liveSrc, ResourceUsage::Copy)); } else { - actionNode.resourceUsage.push_back( - make_rdcpair(liveSrc, EventUsage(actionNode.action.eventId, ResourceUsage::CopySrc))); - actionNode.resourceUsage.push_back( - make_rdcpair(liveDst, EventUsage(actionNode.action.eventId, ResourceUsage::CopyDst))); + eventNode.resourceUsage.push_back(make_rdcpair(liveSrc, ResourceUsage::CopySrc)); + eventNode.resourceUsage.push_back(make_rdcpair(liveDst, ResourceUsage::CopyDst)); } } } @@ -5539,19 +5453,18 @@ bool WrappedID3D12GraphicsCommandList::Serialise_CopyResource(SerialiserType &se m_Cmd->AddAction(action); - D3D12ActionTreeNode &actionNode = m_Cmd->GetActionStack().back()->children.back(); + D3D12EventNode &eventNode = m_Cmd->GetLastEventNode(); if(pSrcResource == pDstResource) { - actionNode.resourceUsage.push_back(make_rdcpair( - GetResID(pSrcResource), EventUsage(actionNode.action.eventId, ResourceUsage::Copy))); + eventNode.resourceUsage.push_back(make_rdcpair(GetResID(pSrcResource), ResourceUsage::Copy)); } else { - actionNode.resourceUsage.push_back(make_rdcpair( - GetResID(pSrcResource), EventUsage(actionNode.action.eventId, ResourceUsage::CopySrc))); - actionNode.resourceUsage.push_back(make_rdcpair( - GetResID(pDstResource), EventUsage(actionNode.action.eventId, ResourceUsage::CopyDst))); + eventNode.resourceUsage.push_back( + make_rdcpair(GetResID(pSrcResource), ResourceUsage::CopySrc)); + eventNode.resourceUsage.push_back( + make_rdcpair(GetResID(pDstResource), ResourceUsage::CopyDst)); } } } @@ -5637,21 +5550,19 @@ bool WrappedID3D12GraphicsCommandList::Serialise_ResolveSubresource( m_Cmd->AddAction(action); - D3D12ActionTreeNode &actionNode = m_Cmd->GetActionStack().back()->children.back(); + D3D12EventNode &eventNode = m_Cmd->GetLastEventNode(); if(pSrcResource == pDstResource) { - actionNode.resourceUsage.push_back(make_rdcpair( - GetResID(pSrcResource), EventUsage(actionNode.action.eventId, ResourceUsage::Resolve))); + eventNode.resourceUsage.push_back( + make_rdcpair(GetResID(pSrcResource), ResourceUsage::Resolve)); } else { - actionNode.resourceUsage.push_back( - make_rdcpair(GetResID(pSrcResource), - EventUsage(actionNode.action.eventId, ResourceUsage::ResolveSrc))); - actionNode.resourceUsage.push_back( - make_rdcpair(GetResID(pDstResource), - EventUsage(actionNode.action.eventId, ResourceUsage::ResolveDst))); + eventNode.resourceUsage.push_back( + make_rdcpair(GetResID(pSrcResource), ResourceUsage::ResolveSrc)); + eventNode.resourceUsage.push_back( + make_rdcpair(GetResID(pDstResource), ResourceUsage::ResolveDst)); } } } @@ -5756,12 +5667,9 @@ bool WrappedID3D12GraphicsCommandList::Serialise_CopyTiles( m_Cmd->AddAction(action); - D3D12ActionTreeNode &actionNode = m_Cmd->GetActionStack().back()->children.back(); - - actionNode.resourceUsage.push_back( - make_rdcpair(liveSrc, EventUsage(actionNode.action.eventId, ResourceUsage::CopySrc))); - actionNode.resourceUsage.push_back( - make_rdcpair(liveDst, EventUsage(actionNode.action.eventId, ResourceUsage::CopyDst))); + D3D12EventNode &eventNode = m_Cmd->GetLastEventNode(); + eventNode.resourceUsage.push_back(make_rdcpair(liveSrc, ResourceUsage::CopySrc)); + eventNode.resourceUsage.push_back(make_rdcpair(liveDst, ResourceUsage::CopyDst)); } } } diff --git a/renderdoc/driver/d3d12/d3d12_command_queue.h b/renderdoc/driver/d3d12/d3d12_command_queue.h index 2a7c3e910..ca2c5f61d 100644 --- a/renderdoc/driver/d3d12/d3d12_command_queue.h +++ b/renderdoc/driver/d3d12/d3d12_command_queue.h @@ -225,7 +225,7 @@ public: D3D12ResourceRecord *GetCreationRecord() { return m_CreationRecord; } WrappedID3D12Device *GetWrappedDevice() { return m_pDevice; } const rdcarray &GetCmdLists() { return m_CmdListRecords; } - D3D12ActionTreeNode &GetParentAction() { return m_Cmd.m_ParentAction; } + void BakeEventNodes(ActionDescription &rootAction) { return m_Cmd.BakeEventNodes(rootAction); } const APIEvent &GetEvent(uint32_t eventId); uint32_t GetMaxEID() { return m_Cmd.m_Events.back().eventId; } void ClearAfterCapture(); diff --git a/renderdoc/driver/d3d12/d3d12_command_queue_wrap.cpp b/renderdoc/driver/d3d12/d3d12_command_queue_wrap.cpp index b12806eb4..9c4b8f4ba 100644 --- a/renderdoc/driver/d3d12/d3d12_command_queue_wrap.cpp +++ b/renderdoc/driver/d3d12/d3d12_command_queue_wrap.cpp @@ -460,8 +460,9 @@ bool WrappedID3D12CommandQueue::Serialise_ExecuteCommandLists(SerialiserType &se if(m_pDevice->GetReplayOptions().apiValidation) DebugMessages.clear(); + D3D12EventNode &eventNode = m_Cmd.m_LoadingEventNode; for(const DebugMessage &msg : DebugMessages) - m_Cmd.m_EventMessages.push_back(msg); + eventNode.debugMessages.push_back(msg); } } @@ -487,9 +488,6 @@ bool WrappedID3D12CommandQueue::Serialise_ExecuteCommandLists(SerialiserType &se { m_Cmd.AddEvent(); - // we're adding multiple events, need to increment ourselves - m_Cmd.m_RootEventID++; - for(uint32_t i = 0; i < NumCommandLists; i++) { ResourceId cmd = GetResID(ppCommandLists[i]); @@ -583,17 +581,13 @@ bool WrappedID3D12CommandQueue::Serialise_ExecuteCommandLists(SerialiserType &se } } - if(!info.executeEvents.empty()) + if(info.hasExecuteDatas) { // ensure all GPU work has finished for readback of arguments m_pDevice->DeviceWaitForIdle(); if(m_pDevice->HasFatalError()) return false; - - // readback the patch buffer and update recorded events - for(size_t c = 0; c < info.executeEvents.size(); c++) - m_ReplayList->FinaliseExecuteIndirectEvents(info, info.executeEvents[c]); } } @@ -620,56 +614,16 @@ bool WrappedID3D12CommandQueue::Serialise_ExecuteCommandLists(SerialiserType &se ActionFlags::BeginPass; m_Cmd.AddEvent(); - m_Cmd.m_RootEvents.back().chunkIndex = cmdListInfo.beginChunk; - m_Cmd.m_Events.back().chunkIndex = cmdListInfo.beginChunk; - m_Cmd.AddAction(action); - m_Cmd.m_RootEventID++; + D3D12EventNode &eventNode = m_Cmd.GetLastEventNode(); + eventNode.event.chunkIndex = cmdListInfo.beginChunk; + eventNode.addActionUse = false; + eventNode.addPrimaryExecute = true; + eventNode.primaryCmdId = cmd; } - // insert the baked command list in-line into this list of nodes, assigning new event and - // drawIDs - m_Cmd.InsertActionsAndRefreshIDs(cmd, cmdListInfo); - - for(size_t e = 0; e < cmdListInfo.action->executedCmds.size(); e++) - { - rdcarray &submits = m_Cmd.m_Partial[D3D12CommandData::Secondary] - .cmdListExecs[cmdListInfo.action->executedCmds[e]]; - - for(size_t s = 0; s < submits.size(); s++) - submits[s] += m_Cmd.m_RootEventID; - } - - for(size_t i = 0; i < cmdListInfo.debugMessages.size(); i++) - { - DebugMessage msg = cmdListInfo.debugMessages[i]; - msg.eventId += m_Cmd.m_RootEventID; - m_pDevice->AddDebugMessage(msg); - } - - // only primary command lists can be submitted - m_Cmd.m_Partial[D3D12CommandData::Primary].cmdListExecs[cmd].push_back(m_Cmd.m_RootEventID); - - // pull in any remaining events on the command buffer that weren't added to an action - for(size_t e = 0; e < cmdListInfo.curEvents.size(); e++) - { - APIEvent apievent = cmdListInfo.curEvents[e]; - apievent.eventId += m_Cmd.m_RootEventID; - - m_Cmd.m_RootEvents.push_back(apievent); - m_Cmd.m_Events.resize_for_index(apievent.eventId); - m_Cmd.m_Events[apievent.eventId] = apievent; - } - - for(auto it = cmdListInfo.resourceUsage.begin(); it != cmdListInfo.resourceUsage.end(); ++it) - { - EventUsage u = it->second; - u.eventId += m_Cmd.m_RootEventID; - m_Cmd.m_ResourceUses[it->first].push_back(u); - } - - m_Cmd.m_RootEventID += cmdListInfo.eventCount; - m_Cmd.m_RootActionID += cmdListInfo.actionCount; + // insert the baked command buffer into the root events, resolving indirect actions + SDObject *localAnnotations = m_Cmd.InsertEventNodes(m_ReplayList, cmd, cmdListInfo); { action.customName = @@ -678,11 +632,25 @@ bool WrappedID3D12CommandQueue::Serialise_ExecuteCommandLists(SerialiserType &se ActionFlags::CommandBufferBoundary | ActionFlags::PassBoundary | ActionFlags::EndPass; m_Cmd.AddEvent(); - m_Cmd.m_RootEvents.back().chunkIndex = cmdListInfo.endChunk; - m_Cmd.m_Events.back().chunkIndex = cmdListInfo.endChunk; - m_Cmd.AddAction(action); - m_Cmd.m_RootEventID++; + + D3D12EventNode &eventNode = m_Cmd.GetLastEventNode(); + eventNode.event.chunkIndex = cmdListInfo.endChunk; + eventNode.addActionUse = false; + if(localAnnotations) + { + // Modify using the annotations stored in the event node + for(const PendingAnnotation &annot : cmdListInfo.pendingAnnotations) + { + if(annot.valueType == eRENDERDOC_Empty) + localAnnotations->EraseChildByKeyPath(annot.key); + else + WriteAnnotation(localAnnotations->CreateChildByKeyPath(annot.key), annot.valueType, + annot.valueVectorWidth, annot.value); + } + eventNode.event.annotations = localAnnotations->Duplicate(); + delete localAnnotations; + } } } @@ -703,12 +671,10 @@ bool WrappedID3D12CommandQueue::Serialise_ExecuteCommandLists(SerialiserType &se ResourceId cmd = GetResID(ppCommandLists[c]); m_Cmd.m_RootEventID += m_Cmd.m_BakedCmdListInfo[cmd].eventCount; - m_Cmd.m_RootActionID += m_Cmd.m_BakedCmdListInfo[cmd].actionCount; // 2 extra for the virtual labels around the command list { m_Cmd.m_RootEventID += 2; - m_Cmd.m_RootActionID += 2; } } @@ -1321,9 +1287,6 @@ bool WrappedID3D12CommandQueue::Serialise_BeginEvent(SerialiserType &ser, UINT M m_Cmd.AddEvent(); m_Cmd.AddAction(action); - - // now push the action stack - m_Cmd.GetActionStack().push_back(&m_Cmd.GetActionStack().back()->children.back()); } } @@ -1365,9 +1328,6 @@ bool WrappedID3D12CommandQueue::Serialise_EndEvent(SerialiserType &ser) m_Cmd.AddEvent(); m_Cmd.AddAction(action); - - if(m_Cmd.GetActionStack().size() > 1) - m_Cmd.GetActionStack().pop_back(); } } diff --git a/renderdoc/driver/d3d12/d3d12_commands.cpp b/renderdoc/driver/d3d12/d3d12_commands.cpp index d6fc6182b..239382088 100644 --- a/renderdoc/driver/d3d12/d3d12_commands.cpp +++ b/renderdoc/driver/d3d12/d3d12_commands.cpp @@ -740,7 +740,11 @@ const APIEvent &WrappedID3D12CommandQueue::GetEvent(uint32_t eventId) bool WrappedID3D12CommandQueue::ProcessChunk(ReadSerialiser &ser, D3D12Chunk chunk) { - m_Cmd.m_AddedAction = false; + if(IsLoading(m_State)) + { + m_Cmd.m_AddedEventNode = false; + m_Cmd.m_LoadingEventNode = D3D12EventNode(); + } bool ret = false; @@ -1129,13 +1133,11 @@ bool WrappedID3D12CommandQueue::ProcessChunk(ReadSerialiser &ser, D3D12Chunk chu } else { - if(!m_Cmd.m_AddedAction) + if(!m_Cmd.m_AddedEventNode) m_Cmd.AddEvent(); } } - m_Cmd.m_AddedAction = false; - return ret; } @@ -1192,8 +1194,6 @@ RDResult WrappedID3D12CommandQueue::ReplayLog(CaptureState readType, uint32_t st ser.EndChunk(); - m_Cmd.m_RootEvents.clear(); - if(IsLoading(m_State)) { m_pDevice->ApplyInitialContents(); @@ -1233,7 +1233,6 @@ RDResult WrappedID3D12CommandQueue::ReplayLog(CaptureState readType, uint32_t st else { m_Cmd.m_RootEventID = 1; - m_Cmd.m_RootActionID = 1; m_Cmd.m_FirstEventID = 0; m_Cmd.m_LastEventID = ~0U; } @@ -1757,49 +1756,6 @@ HRESULT STDMETHODCALLTYPE WrappedID3D12GraphicsCommandList::QueryInterface(REFII return m_RefCounter.QueryInterface("ID3D12GraphicsCommandList", riid, ppvObject); } -void BakedCmdListInfo::ShiftForRemoved(uint32_t shiftActionID, uint32_t shiftEID, size_t idx) -{ - rdcarray &actions = action->children; - - actionCount -= shiftActionID; - eventCount -= shiftEID; - - if(idx < actions.size()) - { - for(size_t i = idx; i < actions.size(); i++) - { - // should have no children as we don't push in for markers since they - // can cross command list boundaries. - RDCASSERT(actions[i].children.empty()); - - actions[i].action.eventId -= shiftEID; - actions[i].action.actionId -= shiftActionID; - - for(APIEvent &ev : actions[i].action.events) - ev.eventId -= shiftEID; - - for(size_t u = 0; u < actions[i].resourceUsage.size(); u++) - actions[i].resourceUsage[u].second.eventId -= shiftEID; - } - - uint32_t lastEID = actions[idx].action.eventId; - - // shift any resource usage for actions after the removed section - - // patch any subsequent executes - for(size_t i = 0; i < executeEvents.size(); i++) - { - if(executeEvents[i].baseEvent >= lastEID) - executeEvents[i].baseEvent -= shiftEID; - } - } - - for(size_t i = 0; i < curEvents.size(); i++) - { - curEvents[i].eventId -= shiftEID; - } -} - SubresourceStateVector BakedCmdListInfo::GetState(WrappedID3D12Device *device, ResourceId id) { std::map data; @@ -1835,7 +1791,6 @@ D3D12CommandData::D3D12CommandData() m_IndirectOffset = 0; m_RootEventID = 1; - m_RootActionID = 1; m_FirstEventID = 0; m_LastEventID = ~0U; @@ -1845,9 +1800,7 @@ D3D12CommandData::D3D12CommandData() m_ActionCallback = NULL; - m_AddedAction = false; - - m_RootActionStack.push_back(&m_ParentAction); + m_AddedEventNode = false; } void D3D12CommandData::GetIndirectBuffer(size_t size, ID3D12Resource **buf, uint64_t *offs) @@ -2018,74 +1971,57 @@ ID3D12GraphicsCommandListX *D3D12CommandData::RerecordCmdList(ResourceId cmdid, void D3D12CommandData::AddEvent() { - APIEvent apievent; + rdcarray &eventNodes = + (m_LastCmdListID != ResourceId() ? m_BakedCmdListInfo[m_LastCmdListID].eventNodes + : m_EventNodes); + eventNodes.emplace_back(m_LoadingEventNode); + m_LoadingEventNode = D3D12EventNode(); - apievent.fileOffset = m_CurChunkOffset; - apievent.eventId = m_LastCmdListID != ResourceId() ? m_BakedCmdListInfo[m_LastCmdListID].curEventID - : m_RootEventID; + D3D12EventNode &node = eventNodes.back(); - apievent.chunkIndex = uint32_t(m_StructuredFile->chunks.size() - 1); - - // if we're using replay-time debug messages, fetch them now since we can do better to correlate - // to events on replay + // if we're using replay-time debug messages, fetch them now since we can do better to correlate to events on replay if(m_pDevice->GetReplayOptions().apiValidation) - m_EventMessages = m_pDevice->GetDebugMessages(); - - for(size_t i = 0; i < m_EventMessages.size(); i++) - m_EventMessages[i].eventId = apievent.eventId; + node.debugMessages = m_pDevice->GetDebugMessages(); + APIEvent &apievent = node.event; + apievent.fileOffset = m_CurChunkOffset; + apievent.chunkIndex = uint32_t(m_StructuredFile->chunks.size() - 1); + // event IDs start from one not zero + apievent.eventId = (uint32_t)eventNodes.count(); if(m_LastCmdListID != ResourceId()) { - m_BakedCmdListInfo[m_LastCmdListID].curEvents.push_back(apievent); - - rdcarray &msgs = m_BakedCmdListInfo[m_LastCmdListID].debugMessages; - - msgs.append(m_EventMessages); + node.annotations.swap(m_BakedCmdListInfo[m_LastCmdListID].pendingAnnotations); } else { if(m_RootAnnotation) - { apievent.annotations = m_RootAnnotation->Duplicate(); - m_EventAnnotations.push_back(apievent.annotations); - } - - m_RootEvents.push_back(apievent); - m_Events.resize_for_index(apievent.eventId); - m_Events[apievent.eventId] = apievent; - - for(auto it = m_EventMessages.begin(); it != m_EventMessages.end(); ++it) - m_pDevice->AddDebugMessage(*it); } - m_EventMessages.clear(); + m_AddedEventNode = true; } -void D3D12CommandData::AddResourceUsage(D3D12ActionTreeNode &actionNode, ResourceId id, - uint32_t EID, ResourceUsage usage) +void D3D12CommandData::AddResourceUsage(D3D12EventNode &eventNode, ResourceId id, ResourceUsage usage) { if(id == ResourceId()) return; - actionNode.resourceUsage.push_back(make_rdcpair(id, EventUsage(EID, usage))); + eventNode.resourceUsage.push_back(make_rdcpair(id, usage)); } void D3D12CommandData::AddCPUUsage(ResourceId id, ResourceUsage usage) { - m_ResourceUses[id].push_back(EventUsage(m_RootEventID, usage)); + m_LoadingEventNode.resourceUsage.push_back(make_rdcpair(id, usage)); } void D3D12CommandData::AddUsageForBindInRootSig(const D3D12RenderState &state, - D3D12ActionTreeNode &actionNode, + D3D12EventNode &eventNode, const D3D12RenderState::RootSignature *rootsig, D3D12_DESCRIPTOR_RANGE_TYPE type, uint32_t space, uint32_t bind, uint32_t rangeSize) { static bool hugeRangeWarned = false; - ActionDescription &a = actionNode.action; - uint32_t eid = a.eventId; - // use a 'clamped' range size to avoid annoying overflow issues rangeSize = RDCMIN(rangeSize, 0x10000000U); @@ -2128,7 +2064,7 @@ void D3D12CommandData::AddUsageForBindInRootSig(const D3D12RenderState &state, type == D3D12_DESCRIPTOR_RANGE_TYPE_CBV && p.Descriptor.RegisterSpace == space && p.Descriptor.ShaderRegister >= bind && p.Descriptor.ShaderRegister < bind + rangeSize) { - AddResourceUsage(actionNode, el.id, eid, cb); + AddResourceUsage(eventNode, el.id, cb); // common case - root element matches 1:1 with a non-array shader bind, if so we can exit. If // not we might have to continue since other parts of it might be mapped to a table, or @@ -2140,7 +2076,7 @@ void D3D12CommandData::AddUsageForBindInRootSig(const D3D12RenderState &state, type == D3D12_DESCRIPTOR_RANGE_TYPE_SRV && p.Descriptor.RegisterSpace == space && p.Descriptor.ShaderRegister >= bind && p.Descriptor.ShaderRegister < bind + rangeSize) { - AddResourceUsage(actionNode, el.id, eid, ro); + AddResourceUsage(eventNode, el.id, ro); // common case - root element matches 1:1 with a non-array shader bind, if so we can exit. If // not we might have to continue since other parts of it might be mapped to a table, or @@ -2152,7 +2088,7 @@ void D3D12CommandData::AddUsageForBindInRootSig(const D3D12RenderState &state, type == D3D12_DESCRIPTOR_RANGE_TYPE_UAV && p.Descriptor.RegisterSpace == space && p.Descriptor.ShaderRegister >= bind && p.Descriptor.ShaderRegister < bind + rangeSize) { - AddResourceUsage(actionNode, el.id, eid, rw); + AddResourceUsage(eventNode, el.id, rw); // common case - root element matches 1:1 with a non-array shader bind, if so we can exit. If // not we might have to continue since other parts of it might be mapped to a table, or @@ -2225,13 +2161,11 @@ void D3D12CommandData::AddUsageForBindInRootSig(const D3D12RenderState &state, if(range.RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_CBV) { - EventUsage usage(eid, cb); - for(UINT i = 0; i < num && i < rangeSize; i++) { ResourceId id = WrappedID3D12Resource::GetResIDFromAddr(desc->GetCBV().BufferLocation); - AddResourceUsage(actionNode, id, eid, cb); + AddResourceUsage(eventNode, id, cb); desc++; } @@ -2243,7 +2177,7 @@ void D3D12CommandData::AddUsageForBindInRootSig(const D3D12RenderState &state, for(UINT i = 0; i < num && i < rangeSize; i++) { - AddResourceUsage(actionNode, desc->GetResResourceId(), eid, usage); + AddResourceUsage(eventNode, desc->GetResResourceId(), usage); desc++; } @@ -2258,11 +2192,9 @@ void D3D12CommandData::AddUsageForBindInRootSig(const D3D12RenderState &state, } } -void D3D12CommandData::AddUsage(const D3D12RenderState &state, D3D12ActionTreeNode &actionNode) +void D3D12CommandData::AddUsage(const D3D12RenderState &state, D3D12EventNode &eventNode) { - ActionDescription &a = actionNode.action; - - uint32_t eid = a.eventId; + ActionDescription &a = eventNode.action; ActionFlags DrawMask = ActionFlags::Drawcall | ActionFlags::MeshDispatch | ActionFlags::Dispatch; if(!(a.flags & DrawMask)) @@ -2320,26 +2252,25 @@ void D3D12CommandData::AddUsage(const D3D12RenderState &state, D3D12ActionTreeNo } if(a.flags & ActionFlags::Indexed && state.ibuffer.buf != ResourceId()) - actionNode.resourceUsage.push_back( - make_rdcpair(state.ibuffer.buf, EventUsage(eid, ResourceUsage::IndexBuffer))); + eventNode.resourceUsage.push_back(make_rdcpair(state.ibuffer.buf, ResourceUsage::IndexBuffer)); if(a.flags & ActionFlags::Drawcall) { for(size_t i = 0; i < state.vbuffers.size(); i++) { if(state.vbuffers[i].buf != ResourceId()) - actionNode.resourceUsage.push_back( - make_rdcpair(state.vbuffers[i].buf, EventUsage(eid, ResourceUsage::VertexBuffer))); + eventNode.resourceUsage.push_back( + make_rdcpair(state.vbuffers[i].buf, ResourceUsage::VertexBuffer)); } for(size_t i = 0; i < state.streamouts.size(); i++) { if(state.streamouts[i].buf != ResourceId()) - actionNode.resourceUsage.push_back( - make_rdcpair(state.streamouts[i].buf, EventUsage(eid, ResourceUsage::StreamOut))); + eventNode.resourceUsage.push_back( + make_rdcpair(state.streamouts[i].buf, ResourceUsage::StreamOut)); if(state.streamouts[i].countbuf != ResourceId()) - actionNode.resourceUsage.push_back(make_rdcpair( - state.streamouts[i].countbuf, EventUsage(eid, ResourceUsage::StreamOut))); + eventNode.resourceUsage.push_back( + make_rdcpair(state.streamouts[i].countbuf, ResourceUsage::StreamOut)); } } @@ -2348,14 +2279,12 @@ void D3D12CommandData::AddUsage(const D3D12RenderState &state, D3D12ActionTreeNo for(size_t i = 0; i < rts.size(); i++) { if(rts[i] != ResourceId()) - actionNode.resourceUsage.push_back( - make_rdcpair(rts[i], EventUsage(eid, ResourceUsage::ColorTarget))); + eventNode.resourceUsage.push_back(make_rdcpair(rts[i], ResourceUsage::ColorTarget)); } ResourceId id = state.GetDSVID(); if(id != ResourceId()) - actionNode.resourceUsage.push_back( - make_rdcpair(id, EventUsage(eid, ResourceUsage::DepthStencilTarget))); + eventNode.resourceUsage.push_back(make_rdcpair(id, ResourceUsage::DepthStencilTarget)); } if(rootsig) @@ -2371,34 +2300,144 @@ void D3D12CommandData::AddUsage(const D3D12RenderState &state, D3D12ActionTreeNo for(const ConstantBlock &b : refls[sh]->constantBlocks) { - AddUsageForBindInRootSig(state, actionNode, rootsig, D3D12_DESCRIPTOR_RANGE_TYPE_CBV, + AddUsageForBindInRootSig(state, eventNode, rootsig, D3D12_DESCRIPTOR_RANGE_TYPE_CBV, b.fixedBindSetOrSpace, b.fixedBindNumber, b.bindArraySize); } for(const ShaderResource &r : refls[sh]->readOnlyResources) { - AddUsageForBindInRootSig(state, actionNode, rootsig, D3D12_DESCRIPTOR_RANGE_TYPE_SRV, + AddUsageForBindInRootSig(state, eventNode, rootsig, D3D12_DESCRIPTOR_RANGE_TYPE_SRV, r.fixedBindSetOrSpace, r.fixedBindNumber, r.bindArraySize); } for(const ShaderResource &r : refls[sh]->readWriteResources) { - AddUsageForBindInRootSig(state, actionNode, rootsig, D3D12_DESCRIPTOR_RANGE_TYPE_UAV, + AddUsageForBindInRootSig(state, eventNode, rootsig, D3D12_DESCRIPTOR_RANGE_TYPE_UAV, r.fixedBindSetOrSpace, r.fixedBindNumber, r.bindArraySize); } } } } +void D3D12CommandData::BakeEventNodes(ActionDescription &rootAction) +{ + // EIDs start from 1 + m_Events.resize(1); + uint32_t eid = 1; + uint32_t actionId = 1; + rdcarray actionEvents; + + rdcarray actionStack; + actionStack.push_back(&rootAction); + + ActionDescription *parentAction = actionStack.back(); + + std::map cmdListStarts; + + for(const D3D12EventNode &node : m_EventNodes) + { + m_Events.push_back(node.event); + APIEvent &apievent = m_Events.back(); + apievent.eventId = eid; + actionEvents.push_back(apievent); + + for(const DebugMessage &msg : node.debugMessages) + { + DebugMessage m(msg); + m.eventId = eid; + m_pDevice->AddDebugMessage(m); + } + + if(apievent.annotations) + m_EventAnnotations.push_back(apievent.annotations); + + for(auto it = node.resourceUsage.begin(); it != node.resourceUsage.end(); ++it) + { + ResourceUsage usage = it->second; + m_ResourceUses[it->first].push_back({eid, usage}); + } + + if(node.action.actionId == UINT32_MAX) + { + parentAction->children.push_back(node.action); + ActionDescription &action = parentAction->children.back(); + + RDCASSERT(action.events.isEmpty()); + action.events.swap(actionEvents); + action.eventId = eid; + action.actionId = actionId; + + ActionFlags flags = action.flags; + if(flags & ActionFlags::PushMarker) + { + actionStack.push_back(parentAction); + parentAction = &action; + } + + if(!action.events.empty() && node.addActionUse) + { + auto it = cmdListStarts.find(node.cmdListID); + uint32_t startEID = 0; + if(it != cmdListStarts.end()) + startEID = it->second; + + ActionUse use(action.events.back().fileOffset, eid, node.cmdListID, eid - startEID); + + // insert in sorted location + auto drawit = std::lower_bound(m_ActionUses.begin(), m_ActionUses.end(), use); + m_ActionUses.insert(drawit - m_ActionUses.begin(), use); + } + + if(flags & ActionFlags::PopMarker) + { + if(actionStack.count() == 0) + { + RDCERR("Pop but the action stack is empty"); + parentAction = &rootAction; + } + else + { + parentAction = actionStack.back(); + RDCASSERT(parentAction); + if(!parentAction) + { + RDCERR("NULL parent on the action stack"); + parentAction = &rootAction; + } + actionStack.pop_back(); + } + } + + // markers don't increment action ID + ActionFlags MarkerMask = ActionFlags::SetMarker | ActionFlags::PushMarker | + ActionFlags::PopMarker | ActionFlags::PassBoundary; + bool isMarker = (flags & MarkerMask) ? true : false; + if(!isMarker) + ++actionId; + } + + if(node.addPrimaryExecute) + { + RDCASSERT(node.primaryCmdId != ResourceId()); + cmdListStarts[node.primaryCmdId] = eid + 1; + m_Partial[D3D12CommandData::Primary].cmdListExecs[node.primaryCmdId].push_back(eid + 1); + } + ++eid; + } + + // release the EventNodes now they are baked into actions and events + m_EventNodes.clear(); + for(auto it = m_BakedCmdListInfo.begin(); it != m_BakedCmdListInfo.end(); ++it) + it->second.eventNodes.clear(); +} + void D3D12CommandData::AddAction(const ActionDescription &a) { - m_AddedAction = true; + RDCASSERT(m_AddedEventNode); - ActionDescription action = a; - action.eventId = m_LastCmdListID != ResourceId() ? m_BakedCmdListInfo[m_LastCmdListID].curEventID - : m_RootEventID; - action.actionId = m_LastCmdListID != ResourceId() ? m_BakedCmdListInfo[m_LastCmdListID].actionCount - : m_RootActionID; + D3D12EventNode &node = GetLastEventNode(); + ActionDescription &action = node.action; + action = a; for(int i = 0; i < 8; i++) action.outputs[i] = ResourceId(); @@ -2407,6 +2446,9 @@ void D3D12CommandData::AddAction(const ActionDescription &a) if(m_LastCmdListID != ResourceId()) { + node.addActionUse = true; + node.cmdListID = m_LastCmdListID; + rdcarray rts = m_BakedCmdListInfo[m_LastCmdListID].state.GetRTVIDs(); for(size_t i = 0; i < ARRAY_COUNT(action.outputs); i++) @@ -2420,110 +2462,50 @@ void D3D12CommandData::AddAction(const ActionDescription &a) action.depthOut = m_BakedCmdListInfo[m_LastCmdListID].state.GetDSVID(); } - // markers don't increment action ID - ActionFlags MarkerMask = ActionFlags::SetMarker | ActionFlags::PushMarker | - ActionFlags::PopMarker | ActionFlags::PassBoundary; - if(!(action.flags & MarkerMask)) - { - if(m_LastCmdListID != ResourceId()) - m_BakedCmdListInfo[m_LastCmdListID].actionCount++; - else - m_RootActionID++; - } + // Mark the action as active + action.actionId = UINT32_MAX; - action.events.swap(m_LastCmdListID != ResourceId() ? m_BakedCmdListInfo[m_LastCmdListID].curEvents - : m_RootEvents); - - // should have at least the root action here, push this action - // onto the back's children list. - if(!GetActionStack().empty()) - { - D3D12ActionTreeNode node(action); - - if(m_LastCmdListID != ResourceId()) - { - node.resourceUsage.swap(m_BakedCmdListInfo[m_LastCmdListID].resourceUsage); - AddUsage(m_BakedCmdListInfo[m_LastCmdListID].state, node); - } - - for(const ActionDescription &child : action.children) - node.children.push_back(D3D12ActionTreeNode(child)); - GetActionStack().back()->children.push_back(node); - } - else - RDCERR("Somehow lost action stack!"); + if(m_LastCmdListID != ResourceId()) + AddUsage(m_BakedCmdListInfo[m_LastCmdListID].state, node); } -void D3D12CommandData::InsertActionsAndRefreshIDs(ResourceId cmd, const BakedCmdListInfo &cmdListInfo) +SDObject *D3D12CommandData::InsertEventNodes(WrappedID3D12GraphicsCommandList *replayList, + ResourceId cmd, BakedCmdListInfo &cmdListInfo) { - const rdcarray &cmdBufNodes = cmdListInfo.action->children; - + // Start with the Queue annotation (RootAnnotations) SDObject *localAnnotations = NULL; if(m_RootAnnotation) localAnnotations = m_RootAnnotation->Duplicate(); - size_t curAnnot = 0; - - // assign new action IDs - for(size_t i = 0; i < cmdBufNodes.size(); i++) + rdcarray &eventNodes = cmdListInfo.eventNodes; + for(size_t i = 0; i < eventNodes.size(); i++) { - D3D12ActionTreeNode n = cmdBufNodes[i]; - n.action.eventId += m_RootEventID; - n.action.actionId += m_RootActionID; - - for(APIEvent &ev : n.action.events) + if(eventNodes[i].hasExecuteData) { - if(localAnnotations) + // Readback the patch buffer and update the event nodes + // The reserved execute indirect event nodes might get duplicated or deleted + // This modifies eventNodes including the current node + replayList->FinaliseExecuteIndirectEvents(cmdListInfo, i); + } + + D3D12EventNode n = eventNodes[i]; + + if(localAnnotations) + { + // Modify using the annotations stored in the event node + for(const PendingAnnotation &annot : n.annotations) { - for(; curAnnot < cmdListInfo.annotations.size(); curAnnot++) - { - const PendingAnnotation &annot = cmdListInfo.annotations[curAnnot]; - if(annot.eventId == ev.eventId) - { - if(annot.valueType == eRENDERDOC_Empty) - localAnnotations->EraseChildByKeyPath(annot.key); - else - WriteAnnotation(localAnnotations->CreateChildByKeyPath(annot.key), annot.valueType, - annot.valueVectorWidth, annot.value); - } - else if(annot.eventId > ev.eventId) - { - break; - } - } - - ev.annotations = localAnnotations->Duplicate(); - m_EventAnnotations.push_back(ev.annotations); + if(annot.valueType == eRENDERDOC_Empty) + localAnnotations->EraseChildByKeyPath(annot.key); + else + WriteAnnotation(localAnnotations->CreateChildByKeyPath(annot.key), annot.valueType, + annot.valueVectorWidth, annot.value); } - - ev.eventId += m_RootEventID; - m_Events.resize(ev.eventId + 1); - m_Events[ev.eventId] = ev; + n.event.annotations = localAnnotations->Duplicate(); } - - ActionUse use(m_Events.back().fileOffset, n.action.eventId, cmd, cmdBufNodes[i].action.eventId); - - // insert in sorted location - auto drawit = std::lower_bound(m_ActionUses.begin(), m_ActionUses.end(), use); - m_ActionUses.insert(drawit - m_ActionUses.begin(), use); - - RDCASSERT(n.children.empty()); - - for(auto it = n.resourceUsage.begin(); it != n.resourceUsage.end(); ++it) - { - EventUsage u = it->second; - u.eventId += m_RootEventID; - m_ResourceUses[it->first].push_back(u); - } - - GetActionStack().back()->children.push_back(n); - - // if this is a push marker too, step down the action stack - if(cmdBufNodes[i].action.flags & ActionFlags::PushMarker) - GetActionStack().push_back(&GetActionStack().back()->children.back()); - - // similarly for a pop, but don't pop off the root - if((cmdBufNodes[i].action.flags & ActionFlags::PopMarker) && GetActionStack().size() > 1) - GetActionStack().pop_back(); + m_EventNodes.push_back(n); } + cmdListInfo.eventCount = (uint32_t)eventNodes.size(); + + return localAnnotations; } diff --git a/renderdoc/driver/d3d12/d3d12_commands.h b/renderdoc/driver/d3d12/d3d12_commands.h index 2c4762dee..ca1d7cb90 100644 --- a/renderdoc/driver/d3d12/d3d12_commands.h +++ b/renderdoc/driver/d3d12/d3d12_commands.h @@ -30,77 +30,65 @@ #include "d3d12_resources.h" #include "d3d12_state.h" -struct D3D12ActionTreeNode +struct D3D12ExecuteData { - D3D12ActionTreeNode() {} - explicit D3D12ActionTreeNode(const ActionDescription &a) : action(a) {} - D3D12ActionTreeNode(const D3D12ActionTreeNode &other) { *this = other; } - ~D3D12ActionTreeNode() { SAFE_DELETE(state); } + ID3D12Resource *argBuf = NULL; + ID3D12Resource *countBuf = NULL; + uint64_t argOffs = 0; + uint64_t countOffs = 0; + WrappedID3D12CommandSignature *sig = NULL; + UINT maxCount = 0; + UINT reservedCount = 0; +}; + +struct D3D12EventNode +{ + D3D12EventNode() = default; + ~D3D12EventNode() { SAFE_DELETE(state); } + D3D12EventNode(const D3D12EventNode &other) { *this = other; } + D3D12EventNode &operator=(const D3D12EventNode &a) + { + event = a.event; + action = a.action; + if(a.state) + { + state = new D3D12RenderState(); + *state = *a.state; + } + executeData = a.executeData; + resourceUsage = a.resourceUsage; + debugMessages = a.debugMessages; + annotations = a.annotations; + cmdListID = a.cmdListID; + primaryCmdId = a.primaryCmdId; + childCmdBufId = a.childCmdBufId; + addActionUse = a.addActionUse; + addPrimaryExecute = a.addPrimaryExecute; + hasExecuteData = a.hasExecuteData; + return *this; + } + + // eventId is not used + APIEvent event; + ActionDescription action; - rdcarray children; D3D12RenderState *state = NULL; - rdcarray> resourceUsage; + D3D12ExecuteData executeData; - rdcarray executedCmds; + rdcarray> resourceUsage; - D3D12ActionTreeNode &operator=(const ActionDescription &a) - { - *this = D3D12ActionTreeNode(a); - return *this; - } + // eventId is not used + rdcarray debugMessages; + rdcarray annotations; - D3D12ActionTreeNode &operator=(const D3D12ActionTreeNode &a) - { - action = a.action; - children = a.children; - - if(a.state) - state = new D3D12RenderState(*a.state); - else - state = NULL; - - resourceUsage = a.resourceUsage; - - executedCmds = a.executedCmds; - return *this; - } - - void InsertAndUpdateIDs(const D3D12ActionTreeNode &child, uint32_t baseEventID, uint32_t baseDrawID) - { - for(size_t i = 0; i < child.resourceUsage.size(); i++) - { - resourceUsage.push_back(child.resourceUsage[i]); - resourceUsage.back().second.eventId += baseEventID; - } - - for(size_t i = 0; i < child.children.size(); i++) - { - children.push_back(child.children[i]); - children.back().action.eventId += baseEventID; - children.back().action.actionId += baseDrawID; - - for(APIEvent &ev : children.back().action.events) - ev.eventId += baseEventID; - } - } - - rdcarray Bake() - { - rdcarray ret; - if(children.empty()) - return ret; - - ret.resize(children.size()); - for(size_t i = 0; i < children.size(); i++) - { - ret[i] = children[i].action; - ret[i].children = children[i].Bake(); - } - - return ret; - } + ResourceId cmdListID; + ResourceId primaryCmdId; + ResourceId childCmdBufId; + bool addActionUse = false; + bool addPrimaryExecute = false; + bool hasExecuteData = false; }; struct D3D12ActionCallback @@ -178,30 +166,13 @@ struct AccStructPatchInfo; struct BakedCmdListInfo { - ~BakedCmdListInfo() { SAFE_DELETE(action); } - void ShiftForRemoved(uint32_t shiftActionID, uint32_t shiftEID, size_t idx); + ~BakedCmdListInfo() {} SubresourceStateVector GetState(WrappedID3D12Device *device, ResourceId id); - struct ExecuteData - { - uint32_t baseEvent = 0; - ID3D12Resource *argBuf = NULL; - ID3D12Resource *countBuf = NULL; - uint64_t argOffs = 0; - uint64_t countOffs = 0; - WrappedID3D12CommandSignature *sig = NULL; - UINT maxCount = 0; - }; + rdcarray eventNodes; - rdcarray executeEvents; - - rdcarray curEvents; - rdcarray debugMessages; - rdcarray actionStack; - rdcarray annotations; - - rdcarray> resourceUsage; + rdcarray pendingAnnotations; struct PatchRaytracing { @@ -244,10 +215,10 @@ struct BakedCmdListInfo uint32_t beginChunk = 0; uint32_t endChunk = 0; - D3D12ActionTreeNode *action = NULL; // the root action to copy from when submitting - uint32_t eventCount; // how many events are in this cmd list, for quick skipping - uint32_t curEventID; // current event ID while reading or executing - uint32_t actionCount; // similar to above + uint32_t eventCount; // how many events are in this cmd list, for quick skipping + uint32_t curEventID; // current event ID while replaying, not used during loading + + bool hasExecuteDatas = false; }; class WrappedID3D12Device; @@ -337,7 +308,8 @@ struct D3D12CommandData // so we just set this command list ID3D12GraphicsCommandListX *m_OutsideCmdList = NULL; - void InsertActionsAndRefreshIDs(ResourceId cmd, const BakedCmdListInfo &cmdListInfo); + SDObject *InsertEventNodes(WrappedID3D12GraphicsCommandList *replayList, ResourceId cmd, + BakedCmdListInfo &cmdListInfo); // this is a list of uint64_t file offset -> uint32_t EIDs of where each // action is used. E.g. the action at offset 873954 is EID 50. If a @@ -368,13 +340,14 @@ struct D3D12CommandData std::map m_RerecordCmds; rdcarray m_RerecordCmdList; - bool m_AddedAction; - - rdcarray m_RootEvents, m_Events; + rdcarray m_Events; + D3D12EventNode m_LoadingEventNode; + rdcarray m_EventNodes; + bool m_AddedEventNode; uint64_t m_CurChunkOffset; SDChunkMetaData m_ChunkMetadata; - uint32_t m_RootEventID, m_RootActionID; + uint32_t m_RootEventID; uint32_t m_FirstEventID, m_LastEventID; D3D12Chunk m_LastChunk; @@ -388,10 +361,6 @@ struct D3D12CommandData std::map> m_ResourceUses; - D3D12ActionTreeNode m_ParentAction; - - rdcarray m_RootActionStack; - struct IndirectReplayData { ID3D12CommandSignature *commandSig = NULL; @@ -399,14 +368,6 @@ struct D3D12CommandData UINT64 argsOffset = 0; } m_IndirectData; - rdcarray &GetActionStack() - { - if(m_LastCmdListID != ResourceId()) - return m_BakedCmdListInfo[m_LastCmdListID].actionStack; - - return m_RootActionStack; - } - void GetIndirectBuffer(size_t size, ID3D12Resource **buf, uint64_t *offs); // util function to handle fetching the right eventId, calling any @@ -422,14 +383,24 @@ struct D3D12CommandData void AddAction(const ActionDescription &a); void AddEvent(); - void AddUsage(const D3D12RenderState &state, D3D12ActionTreeNode &actionNode); - void AddUsageForBindInRootSig(const D3D12RenderState &state, D3D12ActionTreeNode &actionNode, + D3D12EventNode &GetLastEventNode() + { + rdcarray &eventNodes = + (m_LastCmdListID != ResourceId() ? m_BakedCmdListInfo[m_LastCmdListID].eventNodes + : m_EventNodes); + return eventNodes.back(); + } + + void BakeEventNodes(ActionDescription &rootAction); + + void AddUsage(const D3D12RenderState &state, D3D12EventNode &eventNode); + + void AddUsageForBindInRootSig(const D3D12RenderState &state, D3D12EventNode &eventNode, const D3D12RenderState::RootSignature *rootsig, D3D12_DESCRIPTOR_RANGE_TYPE type, uint32_t space, uint32_t bind, uint32_t rangeSize); - void AddResourceUsage(D3D12ActionTreeNode &actionNode, ResourceId id, uint32_t EID, - ResourceUsage usage); + void AddResourceUsage(D3D12EventNode &eventNode, ResourceId id, ResourceUsage usage); void AddCPUUsage(ResourceId id, ResourceUsage usage); }; diff --git a/renderdoc/driver/d3d12/d3d12_device.cpp b/renderdoc/driver/d3d12/d3d12_device.cpp index edad40ccc..bbb052526 100644 --- a/renderdoc/driver/d3d12/d3d12_device.cpp +++ b/renderdoc/driver/d3d12/d3d12_device.cpp @@ -5649,10 +5649,9 @@ RDResult WrappedID3D12Device::ReadLogInitialisation(RDCFile *rdc, bool storeStru if(!IsStructuredExporting(m_State)) { - GetReplay()->WriteFrameRecord().actionList = m_Queue->GetParentAction().Bake(); - - m_Queue->GetParentAction().children.clear(); - + ActionDescription rootAction; + m_Queue->BakeEventNodes(rootAction); + rootAction.children.swap(GetReplay()->WriteFrameRecord().actionList); SetupActionPointers(m_Actions, GetReplay()->WriteFrameRecord().actionList); }