From 2895ff848c0422dc243301e6ed28baf84a91e7b7 Mon Sep 17 00:00:00 2001 From: baldurk Date: Thu, 8 Sep 2016 20:22:46 +0200 Subject: [PATCH] Don't mark resources dirty immediately from deferred context actions * Instead record the dirtied resources to be applied when executing the resulting command list. --- renderdoc/driver/d3d11/d3d11_context.cpp | 14 ++++- renderdoc/driver/d3d11/d3d11_context.h | 4 ++ .../driver/d3d11/d3d11_context1_wrap.cpp | 12 ++-- renderdoc/driver/d3d11/d3d11_context_wrap.cpp | 57 ++++++++++--------- renderdoc/driver/d3d11/d3d11_renderstate.cpp | 12 ++-- renderdoc/driver/d3d11/d3d11_renderstate.h | 2 +- renderdoc/driver/d3d11/d3d11_resources.h | 10 ++++ 7 files changed, 71 insertions(+), 40 deletions(-) diff --git a/renderdoc/driver/d3d11/d3d11_context.cpp b/renderdoc/driver/d3d11/d3d11_context.cpp index 32f48874e..be7efb471 100644 --- a/renderdoc/driver/d3d11/d3d11_context.cpp +++ b/renderdoc/driver/d3d11/d3d11_context.cpp @@ -375,6 +375,18 @@ void WrappedID3D11DeviceContext::MarkResourceReferenced(ResourceId id, FrameRefT } } +void WrappedID3D11DeviceContext::MarkDirtyResource(ResourceId id) +{ + if(m_pRealContext->GetType() == D3D11_DEVICE_CONTEXT_IMMEDIATE) + { + m_pDevice->GetResourceManager()->MarkDirtyResource(id); + } + else + { + m_DeferredDirty.insert(id); + } +} + void WrappedID3D11DeviceContext::VerifyState() { #if 0 @@ -567,7 +579,7 @@ void WrappedID3D11DeviceContext::CleanupCapture() for(auto it = m_MissingTracks.begin(); it != m_MissingTracks.end(); ++it) { if(m_pDevice->GetResourceManager()->HasResourceRecord(*it)) - m_pDevice->GetResourceManager()->MarkDirtyResource(*it); + MarkDirtyResource(*it); } m_MissingTracks.clear(); diff --git a/renderdoc/driver/d3d11/d3d11_context.h b/renderdoc/driver/d3d11/d3d11_context.h index 5e093b301..29a7b5d0e 100644 --- a/renderdoc/driver/d3d11/d3d11_context.h +++ b/renderdoc/driver/d3d11/d3d11_context.h @@ -169,6 +169,8 @@ private: } }; + set m_DeferredDirty; + set m_HighTrafficResources; map m_OpenMaps; @@ -305,6 +307,8 @@ public: void BeginCaptureFrame(); void EndCaptureFrame(); + void MarkDirtyResource(ResourceId id); + // insert a fake chunk just to store these parameters void Present(UINT SyncInterval, UINT Flags); diff --git a/renderdoc/driver/d3d11/d3d11_context1_wrap.cpp b/renderdoc/driver/d3d11/d3d11_context1_wrap.cpp index f3ed8f7bc..4859ea343 100644 --- a/renderdoc/driver/d3d11/d3d11_context1_wrap.cpp +++ b/renderdoc/driver/d3d11/d3d11_context1_wrap.cpp @@ -329,7 +329,7 @@ void WrappedID3D11DeviceContext::UpdateSubresource1(ID3D11Resource *pDstResource else { // just mark dirty - m_pDevice->GetResourceManager()->MarkDirtyResource(GetIDForResource(pDstResource)); + MarkDirtyResource(GetIDForResource(pDstResource)); } m_pRealContext1->UpdateSubresource1(m_pDevice->GetResourceManager()->UnwrapResource(pDstResource), @@ -412,7 +412,7 @@ void WrappedID3D11DeviceContext::CopySubresourceRegion1(ID3D11Resource *pDstReso m_pDevice->GetResourceManager()->GetResourceRecord(GetIDForResource(pDstResource)); RDCASSERT(record); - m_pDevice->GetResourceManager()->MarkDirtyResource(GetIDForResource(pDstResource)); + MarkDirtyResource(GetIDForResource(pDstResource)); } m_pRealContext1->CopySubresourceRegion1( @@ -533,7 +533,7 @@ void WrappedID3D11DeviceContext::ClearView(ID3D11View *pView, const FLOAT Color[ ID3D11Resource *viewRes = NULL; pView->GetResource(&viewRes); - m_pDevice->GetResourceManager()->MarkDirtyResource(GetIDForResource(viewRes)); + MarkDirtyResource(GetIDForResource(viewRes)); SAFE_RELEASE(viewRes); } @@ -1584,7 +1584,7 @@ void WrappedID3D11DeviceContext::DiscardResource(ID3D11Resource *pResource) } else if(m_State >= WRITING) { - m_pDevice->GetResourceManager()->MarkDirtyResource(GetIDForResource(pResource)); + MarkDirtyResource(GetIDForResource(pResource)); } } @@ -1703,7 +1703,7 @@ void WrappedID3D11DeviceContext::DiscardView(ID3D11View *pResourceView) ID3D11Resource *viewRes = NULL; pResourceView->GetResource(&viewRes); - m_pDevice->GetResourceManager()->MarkDirtyResource(GetIDForResource(viewRes)); + MarkDirtyResource(GetIDForResource(viewRes)); SAFE_RELEASE(viewRes); } @@ -1819,7 +1819,7 @@ void WrappedID3D11DeviceContext::DiscardView1(ID3D11View *pResourceView, const D ID3D11Resource *viewRes = NULL; pResourceView->GetResource(&viewRes); - m_pDevice->GetResourceManager()->MarkDirtyResource(GetIDForResource(viewRes)); + MarkDirtyResource(GetIDForResource(viewRes)); SAFE_RELEASE(viewRes); } diff --git a/renderdoc/driver/d3d11/d3d11_context_wrap.cpp b/renderdoc/driver/d3d11/d3d11_context_wrap.cpp index 79082164f..0ba9ca8ac 100644 --- a/renderdoc/driver/d3d11/d3d11_context_wrap.cpp +++ b/renderdoc/driver/d3d11/d3d11_context_wrap.cpp @@ -2353,7 +2353,7 @@ void WrappedID3D11DeviceContext::SOSetTargets(UINT NumBuffers, ID3D11Buffer *con if(m_State == WRITING_CAPFRAME) m_MissingTracks.insert(GetIDForResource(ppSOTargets[i])); if(m_State == WRITING_IDLE) - m_pDevice->GetResourceManager()->MarkDirtyResource(GetIDForResource(ppSOTargets[i])); + MarkDirtyResource(GetIDForResource(ppSOTargets[i])); } bufs[i] = UNWRAP(WrappedID3D11Buffer, ppSOTargets[i]); } @@ -3232,7 +3232,7 @@ void WrappedID3D11DeviceContext::OMSetRenderTargets(UINT NumViews, // to avoid having to track "possibly" dirty resources. // Besides, it's unlikely an application will set an output then not draw to it if(m_State == WRITING_IDLE) - m_pDevice->GetResourceManager()->MarkDirtyResource(GetIDForResource(res)); + MarkDirtyResource(GetIDForResource(res)); SAFE_RELEASE(res); } @@ -3246,7 +3246,7 @@ void WrappedID3D11DeviceContext::OMSetRenderTargets(UINT NumViews, pDepthStencilView->GetResource(&res); if(m_State == WRITING_IDLE) - m_pDevice->GetResourceManager()->MarkDirtyResource(GetIDForResource(res)); + MarkDirtyResource(GetIDForResource(res)); SAFE_RELEASE(res); } @@ -3467,7 +3467,7 @@ void WrappedID3D11DeviceContext::OMSetRenderTargetsAndUnorderedAccessViews( // to avoid having to track "possibly" dirty resources. // Besides, it's unlikely an application will set an output then not draw to it if(m_State == WRITING_IDLE) - m_pDevice->GetResourceManager()->MarkDirtyResource(GetIDForResource(res)); + MarkDirtyResource(GetIDForResource(res)); SAFE_RELEASE(res); } @@ -3481,7 +3481,7 @@ void WrappedID3D11DeviceContext::OMSetRenderTargetsAndUnorderedAccessViews( ID3D11Resource *res = NULL; ppUnorderedAccessViews[i]->GetResource(&res); if(m_State == WRITING_IDLE) - m_pDevice->GetResourceManager()->MarkDirtyResource(GetIDForResource(res)); + MarkDirtyResource(GetIDForResource(res)); SAFE_RELEASE(res); } @@ -3494,7 +3494,7 @@ void WrappedID3D11DeviceContext::OMSetRenderTargetsAndUnorderedAccessViews( pDepthStencilView->GetResource(&res); if(m_State == WRITING_IDLE) - m_pDevice->GetResourceManager()->MarkDirtyResource(GetIDForResource(res)); + MarkDirtyResource(GetIDForResource(res)); SAFE_RELEASE(res); } @@ -3786,7 +3786,7 @@ void WrappedID3D11DeviceContext::DrawIndexedInstanced(UINT IndexCountPerInstance } else if(m_State == WRITING_IDLE) { - m_CurrentPipelineState->MarkDirty(m_pDevice->GetResourceManager()); + m_CurrentPipelineState->MarkDirty(this); } } @@ -3857,7 +3857,7 @@ void WrappedID3D11DeviceContext::DrawInstanced(UINT VertexCountPerInstance, UINT } else if(m_State == WRITING_IDLE) { - m_CurrentPipelineState->MarkDirty(m_pDevice->GetResourceManager()); + m_CurrentPipelineState->MarkDirty(this); } } @@ -3920,7 +3920,7 @@ void WrappedID3D11DeviceContext::DrawIndexed(UINT IndexCount, UINT StartIndexLoc } else if(m_State == WRITING_IDLE) { - m_CurrentPipelineState->MarkDirty(m_pDevice->GetResourceManager()); + m_CurrentPipelineState->MarkDirty(this); } } @@ -3979,7 +3979,7 @@ void WrappedID3D11DeviceContext::Draw(UINT VertexCount, UINT StartVertexLocation } else if(m_State == WRITING_IDLE) { - m_CurrentPipelineState->MarkDirty(m_pDevice->GetResourceManager()); + m_CurrentPipelineState->MarkDirty(this); } } @@ -4087,7 +4087,7 @@ void WrappedID3D11DeviceContext::DrawAuto() } else if(m_State == WRITING_IDLE) { - m_CurrentPipelineState->MarkDirty(m_pDevice->GetResourceManager()); + m_CurrentPipelineState->MarkDirty(this); } } @@ -4180,7 +4180,7 @@ void WrappedID3D11DeviceContext::DrawIndexedInstancedIndirect(ID3D11Buffer *pBuf } else if(m_State == WRITING_IDLE) { - m_CurrentPipelineState->MarkDirty(m_pDevice->GetResourceManager()); + m_CurrentPipelineState->MarkDirty(this); } if(pBufferForArgs && m_State >= WRITING_CAPFRAME) @@ -4263,7 +4263,7 @@ void WrappedID3D11DeviceContext::DrawInstancedIndirect(ID3D11Buffer *pBufferForA } else if(m_State == WRITING_IDLE) { - m_CurrentPipelineState->MarkDirty(m_pDevice->GetResourceManager()); + m_CurrentPipelineState->MarkDirty(this); } if(pBufferForArgs && m_State >= WRITING_CAPFRAME) @@ -4620,7 +4620,7 @@ void WrappedID3D11DeviceContext::CSSetUnorderedAccessViews( ppUnorderedAccessViews[i]->GetResource(&res); if(m_State == WRITING_IDLE) - m_pDevice->GetResourceManager()->MarkDirtyResource(GetIDForResource(res)); + MarkDirtyResource(GetIDForResource(res)); SAFE_RELEASE(res); } @@ -4865,7 +4865,11 @@ void WrappedID3D11DeviceContext::ExecuteCommandList(ID3D11CommandList *pCommandL } else if(m_State == WRITING_IDLE) { - m_CurrentPipelineState->MarkDirty(m_pDevice->GetResourceManager()); + m_CurrentPipelineState->MarkDirty(this); + + WrappedID3D11CommandList *wrapped = (WrappedID3D11CommandList *)pCommandList; + + wrapped->MarkDirtyResources(m_pDevice->GetResourceManager()); } if(!RestoreContextState) @@ -4950,7 +4954,7 @@ void WrappedID3D11DeviceContext::Dispatch(UINT ThreadGroupCountX, UINT ThreadGro } else if(m_State == WRITING_IDLE) { - m_CurrentPipelineState->MarkDirty(m_pDevice->GetResourceManager()); + m_CurrentPipelineState->MarkDirty(this); } } @@ -5030,7 +5034,7 @@ void WrappedID3D11DeviceContext::DispatchIndirect(ID3D11Buffer *pBufferForArgs, } else if(m_State == WRITING_IDLE) { - m_CurrentPipelineState->MarkDirty(m_pDevice->GetResourceManager()); + m_CurrentPipelineState->MarkDirty(this); } if(pBufferForArgs && m_State >= WRITING_CAPFRAME) @@ -5120,6 +5124,7 @@ HRESULT WrappedID3D11DeviceContext::FinishCommandList(BOOL RestoreDeferredContex RDCASSERT(r); m_ContextRecord->SwapChunks(r); + wrapped->SetDirtyResources(m_DeferredDirty); // if we're supposed to restore, save the state to restore to now if(RestoreDeferredContextState) @@ -5201,7 +5206,7 @@ void WrappedID3D11DeviceContext::Flush() } else if(m_State == WRITING_IDLE) { - m_CurrentPipelineState->MarkDirty(m_pDevice->GetResourceManager()); + m_CurrentPipelineState->MarkDirty(this); } m_pRealContext->Flush(); @@ -5334,7 +5339,7 @@ void WrappedID3D11DeviceContext::CopySubresourceRegion(ID3D11Resource *pDstResou if(m_pDevice->GetResourceManager()->IsResourceDirty(GetIDForResource(pSrcResource))) { - m_pDevice->GetResourceManager()->MarkDirtyResource(GetIDForResource(pDstResource)); + MarkDirtyResource(GetIDForResource(pDstResource)); } else if(WrappedID3D11Buffer::IsAlloc(pDstResource) && WrappedID3D11Buffer::IsAlloc(pSrcResource)) { @@ -5365,7 +5370,7 @@ void WrappedID3D11DeviceContext::CopySubresourceRegion(ID3D11Resource *pDstResou { // GPU dirty. Just let initial state handle this. - m_pDevice->GetResourceManager()->MarkDirtyResource(GetIDForResource(pDstResource)); + MarkDirtyResource(GetIDForResource(pDstResource)); } } @@ -5478,7 +5483,7 @@ void WrappedID3D11DeviceContext::CopyResource(ID3D11Resource *pDstResource, if(m_pDevice->GetResourceManager()->IsResourceDirty(GetIDForResource(pSrcResource))) { - m_pDevice->GetResourceManager()->MarkDirtyResource(GetIDForResource(pDstResource)); + MarkDirtyResource(GetIDForResource(pDstResource)); } else if(WrappedID3D11Buffer::IsAlloc(pDstResource) && WrappedID3D11Buffer::IsAlloc(pSrcResource)) { @@ -5891,7 +5896,7 @@ void WrappedID3D11DeviceContext::CopyStructureCount(ID3D11Buffer *pDstBuffer, ID3D11Resource *res = NULL; pSrcView->GetResource(&res); - m_pDevice->GetResourceManager()->MarkDirtyResource(GetIDForResource(pDstBuffer)); + MarkDirtyResource(GetIDForResource(pDstBuffer)); SAFE_RELEASE(res); } @@ -6014,7 +6019,7 @@ void WrappedID3D11DeviceContext::ResolveSubresource(ID3D11Resource *pDstResource record->AddParent(srcRecord); if(m_pDevice->GetResourceManager()->IsResourceDirty(GetIDForResource(pSrcResource))) - m_pDevice->GetResourceManager()->MarkDirtyResource(GetIDForResource(pDstResource)); + MarkDirtyResource(GetIDForResource(pDstResource)); SCOPED_SERIALISE_CONTEXT(RESOLVE_SUBRESOURCE); m_pSerialiser->Serialise("context", m_ResourceID); @@ -6134,7 +6139,7 @@ void WrappedID3D11DeviceContext::GenerateMips(ID3D11ShaderResourceView *pShaderR ID3D11Resource *res = NULL; pShaderResourceView->GetResource(&res); ResourceId id = GetIDForResource(res); - m_pDevice->GetResourceManager()->MarkDirtyResource(id); + MarkDirtyResource(id); SAFE_RELEASE(res); } @@ -7521,7 +7526,7 @@ HRESULT WrappedID3D11DeviceContext::Map(ID3D11Resource *pResource, UINT Subresou directMap = true; m_HighTrafficResources.insert(id); if(m_State != WRITING_CAPFRAME) - m_pDevice->GetResourceManager()->MarkDirtyResource(id); + MarkDirtyResource(id); } if(directMap && m_State == WRITING_IDLE) @@ -7576,7 +7581,7 @@ HRESULT WrappedID3D11DeviceContext::Map(ID3D11Resource *pResource, UINT Subresou if(record->UpdateCount > 60 && RenderDoc::Inst().GetCaptureOptions().VerifyMapWrites == 0) { m_HighTrafficResources.insert(Id); - m_pDevice->GetResourceManager()->MarkDirtyResource(Id); + MarkDirtyResource(Id); return ret; } diff --git a/renderdoc/driver/d3d11/d3d11_renderstate.cpp b/renderdoc/driver/d3d11/d3d11_renderstate.cpp index ff6a94c42..6840d1b1f 100644 --- a/renderdoc/driver/d3d11/d3d11_renderstate.cpp +++ b/renderdoc/driver/d3d11/d3d11_renderstate.cpp @@ -158,7 +158,7 @@ void D3D11RenderState::ReleaseRefs() RDCEraseEl(CSUAVs); } -void D3D11RenderState::MarkDirty(D3D11ResourceManager *manager) const +void D3D11RenderState::MarkDirty(WrappedID3D11DeviceContext *ctx) const { for(UINT i = 0; i < D3D11_1_UAV_SLOT_COUNT; i++) { @@ -166,13 +166,13 @@ void D3D11RenderState::MarkDirty(D3D11ResourceManager *manager) const if(CSUAVs[i]) { CSUAVs[i]->GetResource(&res); - manager->MarkDirtyResource(GetIDForResource(res)); + ctx->MarkDirtyResource(GetIDForResource(res)); SAFE_RELEASE(res); } } for(UINT i = 0; i < D3D11_SO_BUFFER_SLOT_COUNT; i++) - manager->MarkDirtyResource(GetIDForResource(SO.Buffers[i])); + ctx->MarkDirtyResource(GetIDForResource(SO.Buffers[i])); for(UINT i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) { @@ -180,7 +180,7 @@ void D3D11RenderState::MarkDirty(D3D11ResourceManager *manager) const if(OM.RenderTargets[i]) { OM.RenderTargets[i]->GetResource(&res); - manager->MarkDirtyResource(GetIDForResource(res)); + ctx->MarkDirtyResource(GetIDForResource(res)); SAFE_RELEASE(res); } } @@ -191,7 +191,7 @@ void D3D11RenderState::MarkDirty(D3D11ResourceManager *manager) const if(OM.UAVs[i]) { OM.UAVs[i]->GetResource(&res); - manager->MarkDirtyResource(GetIDForResource(res)); + ctx->MarkDirtyResource(GetIDForResource(res)); SAFE_RELEASE(res); } } @@ -201,7 +201,7 @@ void D3D11RenderState::MarkDirty(D3D11ResourceManager *manager) const if(OM.DepthView) { OM.DepthView->GetResource(&res); - manager->MarkDirtyResource(GetIDForResource(res)); + ctx->MarkDirtyResource(GetIDForResource(res)); SAFE_RELEASE(res); } } diff --git a/renderdoc/driver/d3d11/d3d11_renderstate.h b/renderdoc/driver/d3d11/d3d11_renderstate.h index e32c103a6..0a1e7c465 100644 --- a/renderdoc/driver/d3d11/d3d11_renderstate.h +++ b/renderdoc/driver/d3d11/d3d11_renderstate.h @@ -517,7 +517,7 @@ struct D3D11RenderState } void SetDevice(WrappedID3D11Device *device) { m_pDevice = device; } void MarkReferenced(WrappedID3D11DeviceContext *ctx, bool initial) const; - void MarkDirty(D3D11ResourceManager *manager) const; + void MarkDirty(WrappedID3D11DeviceContext *ctx) const; private: void AddRefs(); diff --git a/renderdoc/driver/d3d11/d3d11_resources.h b/renderdoc/driver/d3d11/d3d11_resources.h index 0ed004938..a12bb15de 100644 --- a/renderdoc/driver/d3d11/d3d11_resources.h +++ b/renderdoc/driver/d3d11/d3d11_resources.h @@ -1242,6 +1242,9 @@ class WrappedID3D11CommandList : public WrappedDeviceChild11 WrappedID3D11DeviceContext *m_pContext; bool m_Successful; // indicates whether we have all of the commands serialised for this command // list + + set m_Dirty; + public: ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11CommandList); @@ -1259,6 +1262,13 @@ public: WrappedID3D11DeviceContext *GetContext() { return m_pContext; } bool IsCaptured() { return m_Successful; } + void SetDirtyResources(set dirty) { m_Dirty.swap(dirty); } + void MarkDirtyResources(D3D11ResourceManager *manager) + { + for(auto it = m_Dirty.begin(); it != m_Dirty.end(); ++it) + manager->MarkDirtyResource(*it); + } + ////////////////////////////// // implement ID3D11CommandList