From d951a4ea3250c1fdc0a1f07a81202157ad0ecd61 Mon Sep 17 00:00:00 2001 From: baldurk Date: Thu, 7 Dec 2017 17:06:08 +0000 Subject: [PATCH] When executing a command list in D3D11, state is cleared if not restored * On the immediate context after an ExecuteCommandList we were properly restoring the state if specified, but if the state isn't to be restored it must be cleared - otherwise we incorrectly inherit state from the deferred context. --- renderdoc/driver/d3d11/d3d11_common.h | 2 +- renderdoc/driver/d3d11/d3d11_context.cpp | 4 +-- renderdoc/driver/d3d11/d3d11_context.h | 4 +-- renderdoc/driver/d3d11/d3d11_context_wrap.cpp | 29 ++++++++++++++----- renderdoc/driver/d3d11/d3d11_stringise.cpp | 3 +- 5 files changed, 28 insertions(+), 14 deletions(-) diff --git a/renderdoc/driver/d3d11/d3d11_common.h b/renderdoc/driver/d3d11/d3d11_common.h index f2b7b09f1..4558ca7cf 100644 --- a/renderdoc/driver/d3d11/d3d11_common.h +++ b/renderdoc/driver/d3d11/d3d11_common.h @@ -390,7 +390,7 @@ enum class D3D11Chunk : uint32_t CreateRenderTargetView1, CreateUnorderedAccessView1, SwapchainPresent, - PostExecuteCommandListRestore, + PostExecuteCommandList, PostFinishCommandListSet, SwapDeviceContextState, Max, diff --git a/renderdoc/driver/d3d11/d3d11_context.cpp b/renderdoc/driver/d3d11/d3d11_context.cpp index ef3d7fb06..e1be7eaf1 100644 --- a/renderdoc/driver/d3d11/d3d11_context.cpp +++ b/renderdoc/driver/d3d11/d3d11_context.cpp @@ -811,8 +811,8 @@ bool WrappedID3D11DeviceContext::ProcessChunk(ReadSerialiser &ser, D3D11Chunk ch case D3D11Chunk::DiscardView: ret = Serialise_DiscardView(ser, NULL); break; case D3D11Chunk::DiscardView1: ret = Serialise_DiscardView1(ser, NULL, NULL, 0); break; - case D3D11Chunk::PostExecuteCommandListRestore: - ret = Serialise_PostExecuteCommandListRestore(ser); + case D3D11Chunk::PostExecuteCommandList: + ret = Serialise_PostExecuteCommandList(ser, FALSE); break; case D3D11Chunk::PostFinishCommandListSet: ret = Serialise_PostFinishCommandListSet(ser); break; diff --git a/renderdoc/driver/d3d11/d3d11_context.h b/renderdoc/driver/d3d11/d3d11_context.h index 8fc514874..d7915dfad 100644 --- a/renderdoc/driver/d3d11/d3d11_context.h +++ b/renderdoc/driver/d3d11/d3d11_context.h @@ -531,8 +531,8 @@ public: IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, ExecuteCommandList, \ ID3D11CommandList *pCommandList, BOOL RestoreContextState); \ \ - /* Fake function used to restore state after ExecuteCommandList */ \ - IMPLEMENT_FUNCTION_SERIALISED(void, PostExecuteCommandListRestore); \ + /* Fake function used to restore or clear state after ExecuteCommandList */ \ + IMPLEMENT_FUNCTION_SERIALISED(void, PostExecuteCommandList, BOOL RestoreContextState); \ \ IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, HSSetShaderResources, \ UINT StartSlot, UINT NumViews, \ diff --git a/renderdoc/driver/d3d11/d3d11_context_wrap.cpp b/renderdoc/driver/d3d11/d3d11_context_wrap.cpp index a99171f92..1659e02fc 100644 --- a/renderdoc/driver/d3d11/d3d11_context_wrap.cpp +++ b/renderdoc/driver/d3d11/d3d11_context_wrap.cpp @@ -4850,15 +4850,31 @@ bool WrappedID3D11DeviceContext::Serialise_ExecuteCommandList(SerialiserType &se } template -bool WrappedID3D11DeviceContext::Serialise_PostExecuteCommandListRestore(SerialiserType &ser) +bool WrappedID3D11DeviceContext::Serialise_PostExecuteCommandList(SerialiserType &ser, + BOOL RestoreContextState_) { + SERIALISE_ELEMENT_LOCAL(RestoreContextState, bool(RestoreContextState_ == TRUE)); + // this is a 'fake' call we insert after executing, to give us a chance to restore the state. if(IsReplayingAndReading()) { - if(m_DeferredSavedState) + if(RestoreContextState) { - m_DeferredSavedState->ApplyState(this); - SAFE_DELETE(m_DeferredSavedState); + if(m_DeferredSavedState) + { + m_DeferredSavedState->ApplyState(this); + SAFE_DELETE(m_DeferredSavedState); + } + else + { + RDCERR("Expected to have saved state from before execute saved, but didn't find one."); + } + } + else + { + // if we don't restore the state, then it's cleared. There's no inheritance down from the + // deferred context's state to the immediate context. + ClearState(); } } return true; @@ -4915,14 +4931,13 @@ void WrappedID3D11DeviceContext::ExecuteCommandList(ID3D11CommandList *pCommandL // still update dirty resources for subsequent captures wrapped->MarkDirtyResources(m_MissingTracks); - 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 USE_SCRATCH_SERIALISER(); - SCOPED_SERIALISE_CHUNK(D3D11Chunk::PostExecuteCommandListRestore); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::PostExecuteCommandList); SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); - Serialise_PostExecuteCommandListRestore(GET_SERIALISER); + Serialise_PostExecuteCommandList(GET_SERIALISER, RestoreContextState); m_ContextRecord->AddChunk(scope.Get()); } diff --git a/renderdoc/driver/d3d11/d3d11_stringise.cpp b/renderdoc/driver/d3d11/d3d11_stringise.cpp index 802844771..92e6db6a2 100644 --- a/renderdoc/driver/d3d11/d3d11_stringise.cpp +++ b/renderdoc/driver/d3d11/d3d11_stringise.cpp @@ -206,8 +206,7 @@ std::string DoStringise(const D3D11Chunk &el) STRINGISE_ENUM_CLASS_NAMED(CreateUnorderedAccessView1, "ID3D11Device3::CreateUnorderedAccessView1"); STRINGISE_ENUM_CLASS_NAMED(SwapchainPresent, "IDXGISwapChain::Present"); - STRINGISE_ENUM_CLASS_NAMED(PostExecuteCommandListRestore, - "ID3D11DeviceContext::ExecuteCommandList"); + STRINGISE_ENUM_CLASS_NAMED(PostExecuteCommandList, "ID3D11DeviceContext::ExecuteCommandList"); STRINGISE_ENUM_CLASS_NAMED(PostFinishCommandListSet, "ID3D11DeviceContext::FinishCommandList"); STRINGISE_ENUM_CLASS_NAMED(SwapDeviceContextState, "ID3D11DeviceContext1::SwapDeviceContextState");