From 78ef96b2e7fc0417714a7d488f30dc55bdd1bb29 Mon Sep 17 00:00:00 2001 From: baldurk Date: Mon, 5 Sep 2016 20:12:22 +0200 Subject: [PATCH] Set up capturing to flatten/deinterleave deferred context recording --- renderdoc/core/resource_manager.h | 15 ++++++++++ renderdoc/driver/d3d11/d3d11_common.h | 1 + renderdoc/driver/d3d11/d3d11_context.cpp | 26 +++++++---------- renderdoc/driver/d3d11/d3d11_context.h | 1 - renderdoc/driver/d3d11/d3d11_context_wrap.cpp | 29 +++++++++++++++---- renderdoc/driver/d3d11/d3d11_device.cpp | 1 + renderdoc/serialise/serialiser.cpp | 19 ++++++++++++ renderdoc/serialise/serialiser.h | 3 ++ renderdocui/Code/Core.cs | 4 +-- 9 files changed, 74 insertions(+), 25 deletions(-) diff --git a/renderdoc/core/resource_manager.h b/renderdoc/core/resource_manager.h index aad7e240e..c347aee08 100644 --- a/renderdoc/core/resource_manager.h +++ b/renderdoc/core/resource_manager.h @@ -202,6 +202,21 @@ struct ResourceRecord UnlockChunks(); } + void AppendFrom(ResourceRecord *other) + { + LockChunks(); + other->LockChunks(); + + for(auto it = other->m_Chunks.begin(); it != other->m_Chunks.end(); ++it) + AddChunk(it->second->Duplicate()); + + for(auto it = other->Parents.begin(); it != other->Parents.end(); ++it) + AddParent(*it); + + other->UnlockChunks(); + UnlockChunks(); + } + void DeleteChunks() { LockChunks(); diff --git a/renderdoc/driver/d3d11/d3d11_common.h b/renderdoc/driver/d3d11/d3d11_common.h index a2401920d..43304408e 100644 --- a/renderdoc/driver/d3d11/d3d11_common.h +++ b/renderdoc/driver/d3d11/d3d11_common.h @@ -346,6 +346,7 @@ enum D3D11ChunkType SWAP_PRESENT, RESTORE_STATE_AFTER_EXEC, + RESTORE_STATE_AFTER_FINISH, NUM_D3D11_CHUNKS, }; diff --git a/renderdoc/driver/d3d11/d3d11_context.cpp b/renderdoc/driver/d3d11/d3d11_context.cpp index d5a253b33..c29e1684d 100644 --- a/renderdoc/driver/d3d11/d3d11_context.cpp +++ b/renderdoc/driver/d3d11/d3d11_context.cpp @@ -435,10 +435,6 @@ void WrappedID3D11DeviceContext::AttemptCapture() m_SuccessfulCapture = true; m_FailureReason = CaptureSucceeded; - for(auto it = m_DeferredRecords.begin(); it != m_DeferredRecords.end(); ++it) - (*it)->Delete(m_pDevice->GetResourceManager()); - m_DeferredRecords.clear(); - m_ContextRecord->LockChunks(); while(m_ContextRecord->HasChunks()) { @@ -463,13 +459,6 @@ void WrappedID3D11DeviceContext::FinishCapture() m_SuccessfulCapture = false; m_FailureReason = CaptureSucceeded; } - - for(auto it = m_DeferredRecords.begin(); it != m_DeferredRecords.end(); ++it) - { - m_ContextRecord->AddParent(*it); - (*it)->Delete(m_pDevice->GetResourceManager()); - } - m_DeferredRecords.clear(); } void WrappedID3D11DeviceContext::EndCaptureFrame() @@ -563,10 +552,6 @@ void WrappedID3D11DeviceContext::CleanupCapture() m_FailureReason = CaptureSucceeded; } - for(auto it = m_DeferredRecords.begin(); it != m_DeferredRecords.end(); ++it) - (*it)->Delete(m_pDevice->GetResourceManager()); - m_DeferredRecords.clear(); - m_ContextRecord->LockChunks(); while(m_ContextRecord->HasChunks()) { @@ -600,7 +585,8 @@ void WrappedID3D11DeviceContext::EndFrame() { DrainAnnotationQueue(); - m_pDevice->GetResourceManager()->FlushPendingDirty(); + if(m_State == WRITING_IDLE) + m_pDevice->GetResourceManager()->FlushPendingDirty(); } bool WrappedID3D11DeviceContext::IsFL11_1() @@ -756,6 +742,14 @@ void WrappedID3D11DeviceContext::ProcessChunk(uint64_t offset, D3D11ChunkType ch break; } + case RESTORE_STATE_AFTER_FINISH: + { + D3D11RenderState state(m_pSerialiser); + state.Serialise(m_State, m_pDevice); + state.ApplyState(this); + break; + } + case SWAP_PRESENT: { // we don't do anything with these parameters, they're just here to store diff --git a/renderdoc/driver/d3d11/d3d11_context.h b/renderdoc/driver/d3d11/d3d11_context.h index 0095fc782..5e093b301 100644 --- a/renderdoc/driver/d3d11/d3d11_context.h +++ b/renderdoc/driver/d3d11/d3d11_context.h @@ -194,7 +194,6 @@ private: bool m_NeedUpdateSubWorkaround; - set m_DeferredRecords; map m_MapResourceRecordAllocs; set m_MissingTracks; diff --git a/renderdoc/driver/d3d11/d3d11_context_wrap.cpp b/renderdoc/driver/d3d11/d3d11_context_wrap.cpp index 7f14fc522..7ba166214 100644 --- a/renderdoc/driver/d3d11/d3d11_context_wrap.cpp +++ b/renderdoc/driver/d3d11/d3d11_context_wrap.cpp @@ -4790,6 +4790,7 @@ bool WrappedID3D11DeviceContext::Serialise_ExecuteCommandList(ID3D11CommandList if(m_State <= EXECUTING && RestoreContextState) { + SAFE_DELETE(m_DeferredSavedState); m_DeferredSavedState = new D3D11RenderState(this); } @@ -4843,15 +4844,20 @@ void WrappedID3D11DeviceContext::ExecuteCommandList(ID3D11CommandList *pCommandL D3D11ResourceRecord *cmdListRecord = m_pDevice->GetResourceManager()->GetResourceRecord(contextId); - if(m_DeferredRecords.find(cmdListRecord) == m_DeferredRecords.end()) - { - m_DeferredRecords.insert(cmdListRecord); - cmdListRecord->AddRef(); - } - + // insert all the deferred chunks immediately following the execute chunk. + m_ContextRecord->AppendFrom(cmdListRecord); cmdListRecord->AddResourceReferences(m_pDevice->GetResourceManager()); } + if(RestoreContextState) + { + // insert a chunk to let us know on replay that we finished the command list's + // chunks and we can restore the state + SCOPED_SERIALISE_CONTEXT(RESTORE_STATE_AFTER_EXEC); + m_pSerialiser->Serialise("context", m_ResourceID); + m_ContextRecord->AddChunk(scope.Get()); + } + m_CurrentPipelineState->MarkReferenced(this, false); } else if(m_State == WRITING_IDLE) @@ -5110,6 +5116,17 @@ HRESULT WrappedID3D11DeviceContext::FinishCommandList(BOOL RestoreDeferredContex RDCASSERT(r); m_ContextRecord->SwapChunks(r); + + // if we're supposed to restore, save the state to restore to now + if(RestoreDeferredContextState) + { + SCOPED_SERIALISE_CONTEXT(RESTORE_STATE_AFTER_FINISH); + m_pSerialiser->Serialise("context", m_ResourceID); + D3D11RenderState rs(*m_CurrentPipelineState); + rs.SetSerialiser(m_pSerialiser); + rs.Serialise(m_State, m_pDevice); + m_ContextRecord->AddChunk(scope.Get()); + } } else if(m_State == WRITING_CAPFRAME && !m_SuccessfulCapture) { diff --git a/renderdoc/driver/d3d11/d3d11_device.cpp b/renderdoc/driver/d3d11/d3d11_device.cpp index 0b9a59e2a..9e1daf86a 100644 --- a/renderdoc/driver/d3d11/d3d11_device.cpp +++ b/renderdoc/driver/d3d11/d3d11_device.cpp @@ -195,6 +195,7 @@ const char *D3D11ChunkNames[] = { "IDXGISwapChain::Present", "ID3D11DeviceContext::ExecuteCommandList", + "ID3D11DeviceContext::FinishCommandList", }; WRAPPED_POOL_INST(WrappedID3D11Device); diff --git a/renderdoc/serialise/serialiser.cpp b/renderdoc/serialise/serialiser.cpp index 23f1cb451..e1d15aab3 100644 --- a/renderdoc/serialise/serialiser.cpp +++ b/renderdoc/serialise/serialiser.cpp @@ -279,6 +279,25 @@ Chunk::Chunk(Serialiser *ser, uint32_t chunkType, bool temporary) #endif } +Chunk *Chunk::Duplicate() +{ + Chunk *ret = new Chunk(); + ret->m_DebugStr = m_DebugStr; + ret->m_Length = m_Length; + ret->m_ChunkType = m_ChunkType; + ret->m_Temporary = m_Temporary; + ret->m_AlignedData = m_AlignedData; + + if(m_AlignedData) + ret->m_Data = Serialiser::AllocAlignedBuffer(m_Length); + else + ret->m_Data = new byte[m_Length]; + + memcpy(ret->m_Data, m_Data, m_Length); + + return ret; +} + Chunk::~Chunk() { #if !defined(RELEASE) diff --git a/renderdoc/serialise/serialiser.h b/renderdoc/serialise/serialiser.h index a10324af7..885562214 100644 --- a/renderdoc/serialise/serialiser.h +++ b/renderdoc/serialise/serialiser.h @@ -113,7 +113,10 @@ public: // grab current contents of the serialiser into this chunk Chunk(Serialiser *ser, uint32_t chunkType, bool temp); + Chunk *Duplicate(); + private: + Chunk() {} // no copy semantics Chunk(const Chunk &); Chunk &operator=(const Chunk &); diff --git a/renderdocui/Code/Core.cs b/renderdocui/Code/Core.cs index 740e91956..2b0aec196 100644 --- a/renderdocui/Code/Core.cs +++ b/renderdocui/Code/Core.cs @@ -316,13 +316,13 @@ namespace renderdocui.Code for (int i = 1; i < draws.Length; i++) { - if ((draws[refdraw].flags & (DrawcallFlags.Copy | DrawcallFlags.Resolve | DrawcallFlags.SetMarker)) > 0) + if ((draws[refdraw].flags & (DrawcallFlags.Copy | DrawcallFlags.Resolve | DrawcallFlags.SetMarker | DrawcallFlags.CmdList)) > 0) { refdraw = i; continue; } - if ((draws[i].flags & (DrawcallFlags.Copy | DrawcallFlags.Resolve | DrawcallFlags.SetMarker)) > 0) + if ((draws[i].flags & (DrawcallFlags.Copy | DrawcallFlags.Resolve | DrawcallFlags.SetMarker | DrawcallFlags.CmdList)) > 0) continue; if (PassEquivalent(draws[i], draws[refdraw]))