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.
This commit is contained in:
baldurk
2017-12-07 17:06:08 +00:00
parent 2d0c5806bf
commit d951a4ea32
5 changed files with 28 additions and 14 deletions
+1 -1
View File
@@ -390,7 +390,7 @@ enum class D3D11Chunk : uint32_t
CreateRenderTargetView1,
CreateUnorderedAccessView1,
SwapchainPresent,
PostExecuteCommandListRestore,
PostExecuteCommandList,
PostFinishCommandListSet,
SwapDeviceContextState,
Max,
+2 -2
View File
@@ -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;
+2 -2
View File
@@ -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, \
+22 -7
View File
@@ -4850,15 +4850,31 @@ bool WrappedID3D11DeviceContext::Serialise_ExecuteCommandList(SerialiserType &se
}
template <typename SerialiserType>
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());
}
+1 -2
View File
@@ -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");