diff --git a/renderdoc/driver/d3d11/d3d11_common.h b/renderdoc/driver/d3d11/d3d11_common.h index 43304408e..a0d406c6b 100644 --- a/renderdoc/driver/d3d11/d3d11_common.h +++ b/renderdoc/driver/d3d11/d3d11_common.h @@ -348,6 +348,8 @@ enum D3D11ChunkType RESTORE_STATE_AFTER_EXEC, RESTORE_STATE_AFTER_FINISH, + SWAP_DEVICE_STATE, + NUM_D3D11_CHUNKS, }; diff --git a/renderdoc/driver/d3d11/d3d11_context.cpp b/renderdoc/driver/d3d11/d3d11_context.cpp index 09b1fa9e7..c1040c653 100644 --- a/renderdoc/driver/d3d11/d3d11_context.cpp +++ b/renderdoc/driver/d3d11/d3d11_context.cpp @@ -758,6 +758,8 @@ void WrappedID3D11DeviceContext::ProcessChunk(uint64_t offset, D3D11ChunkType ch break; } + case SWAP_DEVICE_STATE: Serialise_SwapDeviceContextState(NULL, NULL); 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_context1_wrap.cpp b/renderdoc/driver/d3d11/d3d11_context1_wrap.cpp index 166a773e7..3d1aaa2e1 100644 --- a/renderdoc/driver/d3d11/d3d11_context1_wrap.cpp +++ b/renderdoc/driver/d3d11/d3d11_context1_wrap.cpp @@ -1966,11 +1966,72 @@ void WrappedID3D11DeviceContext::DiscardView1(ID3D11View *pResourceView, const D } } +bool WrappedID3D11DeviceContext::Serialise_SwapDeviceContextState( + ID3DDeviceContextState *pState, ID3DDeviceContextState **ppPreviousState) +{ + D3D11RenderState state(m_pSerialiser); + + if(m_State >= WRITING) + { + state = *((WrappedID3DDeviceContextState *)pState)->state; + + state.SetSerialiser(m_pSerialiser); + + state.MarkReferenced(this, true); + } + + state.Serialise(m_State, m_pDevice); + + if(m_State <= EXECUTING) + { + m_DoStateVerify = false; + { + *m_CurrentPipelineState = state; + m_CurrentPipelineState->SetDevice(m_pDevice); + state.ApplyState(this); + } + m_DoStateVerify = true; + VerifyState(); + } + + return true; +} + void WrappedID3D11DeviceContext::SwapDeviceContextState(ID3DDeviceContextState *pState, ID3DDeviceContextState **ppPreviousState) { if(m_pRealContext1 == NULL) return; - RDCUNIMPLEMENTED("Not wrapping SwapDeviceContextState"); - m_pRealContext1->SwapDeviceContextState(pState, ppPreviousState); + + ID3DDeviceContextState *prev = NULL; + + m_pRealContext1->SwapDeviceContextState(UNWRAP(WrappedID3DDeviceContextState, pState), &prev); + + WrappedID3DDeviceContextState *wrapped = NULL; + + if(m_pDevice->GetResourceManager()->HasWrapper(prev)) + wrapped = (WrappedID3DDeviceContextState *)m_pDevice->GetResourceManager()->GetWrapper(prev); + else if(prev) + wrapped = new WrappedID3DDeviceContextState(prev, m_pDevice); + + if(wrapped) + *wrapped->state = *m_CurrentPipelineState; + + if(ppPreviousState) + *ppPreviousState = wrapped; + + *m_CurrentPipelineState = *((WrappedID3DDeviceContextState *)pState)->state; + + DrainAnnotationQueue(); + + m_EmptyCommandList = false; + + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SWAP_DEVICE_STATE); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_SwapDeviceContextState(pState, NULL); + + m_ContextRecord->AddChunk(scope.Get()); + } } diff --git a/renderdoc/driver/d3d11/d3d11_device.cpp b/renderdoc/driver/d3d11/d3d11_device.cpp index f07006727..5ab5538c5 100644 --- a/renderdoc/driver/d3d11/d3d11_device.cpp +++ b/renderdoc/driver/d3d11/d3d11_device.cpp @@ -196,6 +196,8 @@ const char *D3D11ChunkNames[] = { "ID3D11DeviceContext::ExecuteCommandList", "ID3D11DeviceContext::FinishCommandList", + + "ID3D11DeviceContext1::SwapDeviceContextState", }; WRAPPED_POOL_INST(WrappedID3D11Device); @@ -236,6 +238,8 @@ const uint32_t D3D11InitParams::D3D11_OLD_VERSIONS[D3D11InitParams::D3D11_NUM_SU // capture now. So on replay if deferred contexts are present, we go through a // flattening stpe. 0x000009, + // from 0xA to 0xB, we added the SwapDeviceContextState from ID3D11DeviceContext1 + 0x00000A, }; ReplayCreateStatus D3D11InitParams::Serialise() @@ -2453,6 +2457,15 @@ void WrappedID3D11Device::ReleaseSwapchainResources(WrappedIDXGISwapChain4 *swap GetImmediateContext()->GetCurrentPipelineState()->UnbindIUnknownForWrite(range); GetImmediateContext()->GetCurrentPipelineState()->UnbindIUnknownForRead(range, false, false); + { + SCOPED_LOCK(WrappedID3DDeviceContextState::m_Lock); + for(size_t i = 0; i < WrappedID3DDeviceContextState::m_List.size(); i++) + { + WrappedID3DDeviceContextState::m_List[i]->state->UnbindIUnknownForWrite(range); + WrappedID3DDeviceContextState::m_List[i]->state->UnbindIUnknownForRead(range, false, false); + } + } + wrapped11->ViewRelease(); } @@ -3579,6 +3592,9 @@ void WrappedID3D11Device::ReleaseResource(ID3D11DeviceChild *res) (type == Resource_CommandList && !cmdList->IsCaptured())) serialiseRelease = false; + if(type == Resource_DeviceState) + serialiseRelease = false; + if(type == Resource_CommandList && !cmdList->IsCaptured()) { record = GetResourceManager()->GetResourceRecord(idx); diff --git a/renderdoc/driver/d3d11/d3d11_device.h b/renderdoc/driver/d3d11/d3d11_device.h index cbb42099f..341e9b26f 100644 --- a/renderdoc/driver/d3d11/d3d11_device.h +++ b/renderdoc/driver/d3d11/d3d11_device.h @@ -62,10 +62,10 @@ struct D3D11InitParams : public RDCInitParams UINT NumFeatureLevels; D3D_FEATURE_LEVEL FeatureLevels[16]; - static const uint32_t D3D11_SERIALISE_VERSION = 0x000000A; + static const uint32_t D3D11_SERIALISE_VERSION = 0x000000B; // backwards compatibility for old logs described at the declaration of this array - static const uint32_t D3D11_NUM_SUPPORTED_OLD_VERSIONS = 6; + static const uint32_t D3D11_NUM_SUPPORTED_OLD_VERSIONS = 7; static const uint32_t D3D11_OLD_VERSIONS[D3D11_NUM_SUPPORTED_OLD_VERSIONS]; // version number internal to d3d11 stream diff --git a/renderdoc/driver/d3d11/d3d11_device1_wrap.cpp b/renderdoc/driver/d3d11/d3d11_device1_wrap.cpp index b255b6846..e684ea09d 100644 --- a/renderdoc/driver/d3d11/d3d11_device1_wrap.cpp +++ b/renderdoc/driver/d3d11/d3d11_device1_wrap.cpp @@ -25,6 +25,7 @@ #include "d3d11_device.h" #include "d3d11_context.h" +#include "d3d11_renderstate.h" #include "d3d11_resources.h" /////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -235,9 +236,27 @@ HRESULT WrappedID3D11Device::CreateDeviceContextState(UINT Flags, { if(m_pDevice1 == NULL) return E_NOINTERFACE; - RDCUNIMPLEMENTED("Not wrapping CreateDeviceContextState"); - return m_pDevice1->CreateDeviceContextState(Flags, pFeatureLevels, FeatureLevels, SDKVersion, - EmulatedInterface, pChosenFeatureLevel, ppContextState); + + if(ppContextState == NULL) + return m_pDevice1->CreateDeviceContextState(Flags, pFeatureLevels, FeatureLevels, SDKVersion, + EmulatedInterface, pChosenFeatureLevel, NULL); + + ID3DDeviceContextState *real = NULL; + HRESULT ret = m_pDevice1->CreateDeviceContextState(Flags, pFeatureLevels, FeatureLevels, SDKVersion, + EmulatedInterface, pChosenFeatureLevel, &real); + + if(SUCCEEDED(ret)) + { + SCOPED_LOCK(m_D3DLock); + + WrappedID3DDeviceContextState *wrapped = new WrappedID3DDeviceContextState(real, this); + + *wrapped->state = *m_pImmediateContext->GetCurrentPipelineState(); + + *ppContextState = wrapped; + } + + return ret; } HRESULT WrappedID3D11Device::OpenSharedResource1(HANDLE hResource, REFIID returnedInterface, diff --git a/renderdoc/driver/d3d11/d3d11_renderstate.cpp b/renderdoc/driver/d3d11/d3d11_renderstate.cpp index f2915369d..3c4f89c11 100644 --- a/renderdoc/driver/d3d11/d3d11_renderstate.cpp +++ b/renderdoc/driver/d3d11/d3d11_renderstate.cpp @@ -850,6 +850,10 @@ void D3D11RenderState::Clear() ReleaseRefs(); OM.BlendFactor[0] = OM.BlendFactor[1] = OM.BlendFactor[2] = OM.BlendFactor[3] = 1.0f; OM.SampleMask = 0xffffffff; + + for(size_t i = 0; i < ARRAY_COUNT(VS.CBCounts); i++) + VS.CBCounts[i] = HS.CBCounts[i] = DS.CBCounts[i] = GS.CBCounts[i] = PS.CBCounts[i] = + CS.CBCounts[i] = 4096; } void D3D11RenderState::ApplyState(WrappedID3D11DeviceContext *context) diff --git a/renderdoc/driver/d3d11/d3d11_resources.cpp b/renderdoc/driver/d3d11/d3d11_resources.cpp index 4642fb345..0b817432c 100644 --- a/renderdoc/driver/d3d11/d3d11_resources.cpp +++ b/renderdoc/driver/d3d11/d3d11_resources.cpp @@ -27,6 +27,7 @@ #include "3rdparty/lz4/lz4.h" #include "api/app/renderdoc_app.h" #include "driver/d3d11/d3d11_context.h" +#include "driver/d3d11/d3d11_renderstate.h" #include "driver/dxgi/dxgi_wrapped.h" WRAPPED_POOL_INST(WrappedID3D11Buffer); @@ -53,6 +54,7 @@ WRAPPED_POOL_INST(WrappedID3D11Query1); WRAPPED_POOL_INST(WrappedID3D11Predicate); WRAPPED_POOL_INST(WrappedID3D11ClassInstance); WRAPPED_POOL_INST(WrappedID3D11ClassLinkage); +WRAPPED_POOL_INST(WrappedID3DDeviceContextState); map WrappedTexture::m_TextureList; @@ -63,6 +65,8 @@ map map WrappedID3D11Buffer::m_BufferList; map WrappedShader::m_ShaderList; Threading::CriticalSection WrappedShader::m_ShaderListLock; +std::vector WrappedID3DDeviceContextState::m_List; +Threading::CriticalSection WrappedID3DDeviceContextState::m_Lock; const GUID RENDERDOC_ID3D11ShaderGUID_ShaderDebugMagicValue = RENDERDOC_ShaderDebugMagicValue_struct; @@ -359,6 +363,8 @@ ResourceId GetIDForResource(ID3D11DeviceChild *ptr) return ((WrappedID3D11DeviceContext *)ptr)->GetResourceID(); if(WrappedID3D11CommandList::IsAlloc(ptr)) return ((WrappedID3D11CommandList *)ptr)->GetResourceID(); + if(WrappedID3DDeviceContextState::IsAlloc(ptr)) + return ((WrappedID3DDeviceContextState *)ptr)->GetResourceID(); RDCERR("Unknown type for ptr 0x%p", ptr); @@ -423,6 +429,9 @@ ResourceType IdentifyTypeByPtr(IUnknown *ptr) if(WrappedID3D11CommandList::IsAlloc(ptr)) return Resource_CommandList; + if(WrappedID3DDeviceContextState::IsAlloc(ptr)) + return Resource_DeviceState; + RDCERR("Unknown type for ptr 0x%p", ptr); return Resource_Unknown; @@ -576,3 +585,28 @@ void RefCounter::ReleaseDeviceSoftref(WrappedID3D11Device *device) if(device) device->SoftRelease(); } + +WrappedID3DDeviceContextState::WrappedID3DDeviceContextState(ID3DDeviceContextState *real, + WrappedID3D11Device *device) + : WrappedDeviceChild11(real, device) +{ + state = new D3D11RenderState((Serialiser *)NULL); + + { + SCOPED_LOCK(WrappedID3DDeviceContextState::m_Lock); + WrappedID3DDeviceContextState::m_List.push_back(this); + } +} + +WrappedID3DDeviceContextState::~WrappedID3DDeviceContextState() +{ + SAFE_DELETE(state); + Shutdown(); + + { + SCOPED_LOCK(WrappedID3DDeviceContextState::m_Lock); + auto it = std::find(WrappedID3DDeviceContextState::m_List.begin(), + WrappedID3DDeviceContextState::m_List.end(), this); + WrappedID3DDeviceContextState::m_List.erase(it); + } +} diff --git a/renderdoc/driver/d3d11/d3d11_resources.h b/renderdoc/driver/d3d11/d3d11_resources.h index f201d5d9b..b79527de6 100644 --- a/renderdoc/driver/d3d11/d3d11_resources.h +++ b/renderdoc/driver/d3d11/d3d11_resources.h @@ -57,6 +57,7 @@ enum ResourceType Resource_DeviceContext, Resource_CommandList, + Resource_DeviceState, }; ResourceType IdentifyTypeByPtr(IUnknown *ptr); @@ -1279,3 +1280,16 @@ public: virtual UINT STDMETHODCALLTYPE GetContextFlags(void) { return m_pReal->GetContextFlags(); } }; + +class WrappedID3DDeviceContextState : public WrappedDeviceChild11 +{ +public: + ALLOCATE_WITH_WRAPPED_POOL(WrappedID3DDeviceContextState); + + static std::vector m_List; + static Threading::CriticalSection m_Lock; + D3D11RenderState *state; + + WrappedID3DDeviceContextState(ID3DDeviceContextState *real, WrappedID3D11Device *device); + virtual ~WrappedID3DDeviceContextState(); +};