From 50f2bae91e3668e209f5ee393bb56127b7b271dc Mon Sep 17 00:00:00 2001 From: baldurk Date: Wed, 27 Sep 2017 18:45:15 +0100 Subject: [PATCH] Update non-wrapping D3D11 context code --- renderdoc/driver/d3d11/d3d11_context.cpp | 934 ++++++------------ renderdoc/driver/d3d11/d3d11_context.h | 40 +- .../driver/d3d11/d3d11_context2_wrap.cpp | 4 +- renderdoc/driver/d3d11/d3d11_context_wrap.cpp | 12 +- renderdoc/driver/d3d11/d3d11_device.cpp | 2 +- 5 files changed, 320 insertions(+), 672 deletions(-) diff --git a/renderdoc/driver/d3d11/d3d11_context.cpp b/renderdoc/driver/d3d11/d3d11_context.cpp index 93427e487..4d6324312 100644 --- a/renderdoc/driver/d3d11/d3d11_context.cpp +++ b/renderdoc/driver/d3d11/d3d11_context.cpp @@ -36,7 +36,7 @@ WRAPPED_POOL_INST(WrappedID3D11CommandList); INT STDMETHODCALLTYPE WrappedID3DUserDefinedAnnotation::BeginEvent(LPCWSTR Name) { if(m_Context) - return m_Context->PushEvent(0, Name); + return m_Context->PushMarker(0, Name); return -1; } @@ -44,7 +44,7 @@ INT STDMETHODCALLTYPE WrappedID3DUserDefinedAnnotation::BeginEvent(LPCWSTR Name) INT STDMETHODCALLTYPE WrappedID3DUserDefinedAnnotation::EndEvent() { if(m_Context) - return m_Context->PopEvent(); + return m_Context->PopMarker(); return -1; } @@ -72,13 +72,23 @@ extern uint32_t NullCBOffsets[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] extern uint32_t NullCBCounts[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; WrappedID3D11DeviceContext::WrappedID3D11DeviceContext(WrappedID3D11Device *realDevice, - ID3D11DeviceContext *context, Serialiser *ser) - : RefCounter(context), m_pDevice(realDevice), m_pRealContext(context) + ID3D11DeviceContext *context) + : RefCounter(context), + m_pDevice(realDevice), + m_pRealContext(context), + m_ScratchSerialiser(new StreamWriter(1024), Ownership::Stream) { if(RenderDoc::Inst().GetCrashHandler()) RenderDoc::Inst().GetCrashHandler()->RegisterMemoryRegion(this, sizeof(WrappedID3D11DeviceContext)); + uint32_t flags = 0; + + if(RenderDoc::Inst().GetCaptureOptions().CaptureCallstacks) + flags |= WriteSerialiser::ChunkCallstack; + + m_ScratchSerialiser.SetChunkMetadataRecording(flags); + for(int i = 0; i < D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; i++) { NullCBOffsets[i] = 0; @@ -103,12 +113,6 @@ WrappedID3D11DeviceContext::WrappedID3D11DeviceContext(WrappedID3D11Device *real m_pRealContext3 = NULL; m_pRealContext->QueryInterface(__uuidof(ID3D11DeviceContext3), (void **)&m_pRealContext3); -#if ENABLED(RDOC_RELEASE) - const bool debugSerialiser = false; -#else - const bool debugSerialiser = true; -#endif - m_NeedUpdateSubWorkaround = false; { D3D11_FEATURE_DATA_THREADING caps = {FALSE, FALSE}; @@ -120,19 +124,13 @@ WrappedID3D11DeviceContext::WrappedID3D11DeviceContext(WrappedID3D11Device *real if(RenderDoc::Inst().IsReplayApp()) { - m_State = READING; - m_pSerialiser = ser; + m_State = CaptureState::LoadingReplaying; } else { - m_pSerialiser = new Serialiser(NULL, Serialiser::WRITING, debugSerialiser); - m_State = WRITING_IDLE; - - m_pSerialiser->SetDebugText(true); + m_State = CaptureState::BackgroundCapturing; } - m_OwnSerialiser = false; - // create a temporary and grab its resource ID m_ResourceID = ResourceIDGen::GetNewUniqueID(); @@ -149,6 +147,8 @@ WrappedID3D11DeviceContext::WrappedID3D11DeviceContext(WrappedID3D11Device *real m_ContextRecord->ignoreSerialise = true; } + m_ScratchSerialiser.SetUserData(GetResourceManager()); + m_SuccessfulCapture = true; m_FailureReason = CaptureSucceeded; m_EmptyCommandList = true; @@ -157,15 +157,15 @@ WrappedID3D11DeviceContext::WrappedID3D11DeviceContext(WrappedID3D11Device *real m_DrawcallStack.push_back(&m_ParentDrawcall); - m_CurEventID = 1; + m_CurEventID = 0; m_CurDrawcallID = 1; m_MarkerIndentLevel = 0; m_UserAnnotation.SetContext(this); - m_CurrentPipelineState = new D3D11RenderState((Serialiser *)NULL); + m_CurrentPipelineState = new D3D11RenderState(D3D11RenderState::Empty); m_DeferredSavedState = NULL; - m_DoStateVerify = m_State >= WRITING; + m_DoStateVerify = IsCaptureMode(m_State); if(context->GetType() == D3D11_DEVICE_CONTEXT_IMMEDIATE) { @@ -176,8 +176,8 @@ WrappedID3D11DeviceContext::WrappedID3D11DeviceContext(WrappedID3D11Device *real m_CurrentPipelineState->SetDevice(m_pDevice); m_pDevice->SoftRef(); - if(m_State >= WRITING && RenderDoc::Inst().GetCaptureOptions().CaptureAllCmdLists) - m_State = WRITING_CAPFRAME; + if(IsCaptureMode(m_State) && RenderDoc::Inst().GetCaptureOptions().CaptureAllCmdLists) + m_State = CaptureState::ActiveCapturing; } ReplayFakeContext(ResourceId()); @@ -196,10 +196,7 @@ WrappedID3D11DeviceContext::~WrappedID3D11DeviceContext() SAFE_RELEASE(it->second.query); } - if(m_State >= WRITING || m_OwnSerialiser) - { - SAFE_DELETE(m_pSerialiser); - } + SAFE_DELETE(m_FrameReader); SAFE_RELEASE(m_pRealContext1); SAFE_RELEASE(m_pRealContext2); @@ -220,27 +217,50 @@ void WrappedID3D11DeviceContext::GetDevice(ID3D11Device **ppDevice) (*ppDevice)->AddRef(); } -const char *WrappedID3D11DeviceContext::GetChunkName(D3D11ChunkType idx) +D3D11ResourceManager *WrappedID3D11DeviceContext::GetResourceManager() { - return m_pDevice->GetChunkName(idx); + return m_pDevice->GetResourceManager(); } -bool WrappedID3D11DeviceContext::Serialise_BeginCaptureFrame(bool applyInitialState) +std::string WrappedID3D11DeviceContext::GetChunkName(uint32_t idx) { - D3D11RenderState state(m_pSerialiser); + if((SystemChunk)idx < SystemChunk::FirstDriverChunk) + return ToStr((SystemChunk)idx); - if(m_State >= WRITING) + return ToStr((D3D11Chunk)idx); +} + +struct HiddenCounter +{ + ResourceId id; + uint64_t counterValue; +}; + +DECLARE_REFLECTION_STRUCT(HiddenCounter); + +template +void DoSerialise(SerialiserType &ser, HiddenCounter &el) +{ + SERIALISE_MEMBER(id); + SERIALISE_MEMBER(counterValue); +} + +template +bool WrappedID3D11DeviceContext::Serialise_BeginCaptureFrame(SerialiserType &ser, + bool applyInitialState) +{ + D3D11RenderState state(D3D11RenderState::Empty); + + if(ser.IsWriting()) { state.CopyState(*m_CurrentPipelineState); - state.SetSerialiser(m_pSerialiser); - state.MarkReferenced(this, true); } - state.Serialise(m_State, m_pDevice); + SERIALISE_ELEMENT(state); - if(m_State <= EXECUTING && applyInitialState) + if(IsReplayingAndReading() && applyInitialState) { m_DoStateVerify = false; { @@ -258,7 +278,9 @@ bool WrappedID3D11DeviceContext::Serialise_BeginCaptureFrame(bool applyInitialSt // used for a DrawAuto(). If the stream-out happens in frame we don't need to worry, // but if it references a buffer from before we need to have that counter available // on replay to 'fake' the DrawAuto() just as a Draw() with known values - if(m_State >= WRITING) + std::vector HiddenStreamOutCounters; + + if(ser.IsWriting()) { // this may break API guarantees, but we need to fetch the hidden counters // so we need to restart any queries for currently set SO targets. @@ -287,11 +309,8 @@ bool WrappedID3D11DeviceContext::Serialise_BeginCaptureFrame(bool applyInitialSt D3D11_QUERY_DATA_SO_STATISTICS numPrims; // readback all known counters - SERIALISE_ELEMENT(uint32_t, numStreamOutCounters, (uint32_t)m_StreamOutCounters.size()); for(auto it = m_StreamOutCounters.begin(); it != m_StreamOutCounters.end(); ++it) { - SERIALISE_ELEMENT(ResourceId, id, it->first); - RDCEraseEl(numPrims); HRESULT hr = S_FALSE; @@ -305,10 +324,10 @@ bool WrappedID3D11DeviceContext::Serialise_BeginCaptureFrame(bool applyInitialSt if(hr != S_OK) { numPrims.NumPrimitivesWritten = 0; - RDCERR("Couldn't retrieve hidden buffer counter for streamout on buffer %llu", id); + RDCERR("Couldn't retrieve hidden buffer counter for streamout on buffer %llu", it->first); } - SERIALISE_ELEMENT(uint64_t, hiddenCounter, (uint64_t)numPrims.NumPrimitivesWritten); + HiddenStreamOutCounters.push_back({it->first, (uint64_t)numPrims.NumPrimitivesWritten}); } // restart any counters we were forced to stop @@ -339,21 +358,20 @@ bool WrappedID3D11DeviceContext::Serialise_BeginCaptureFrame(bool applyInitialSt } } } - // version 5 added this set of data, we can assume for older logs there's just no counters - else if(m_pDevice->GetLogVersion() >= 0x000005) - { - // read in the known stream-out counters at the start of the frame. - // any stream-out that happens in the captured frame will be replayed - // and those counters will override this value when it comes to a - // DrawAuto() - SERIALISE_ELEMENT(uint32_t, numStreamOutCounters, 0); - for(uint32_t i = 0; i < numStreamOutCounters; i++) - { - SERIALISE_ELEMENT(ResourceId, id, ResourceId()); - SERIALISE_ELEMENT(uint64_t, hiddenCounter, 0); - if(m_pDevice->GetResourceManager()->HasLiveResource(id)) - m_StreamOutCounters[m_pDevice->GetResourceManager()->GetLiveID(id)].numPrims = hiddenCounter; + SERIALISE_ELEMENT(HiddenStreamOutCounters); + + // read in the known stream-out counters at the start of the frame. + // any stream-out that happens in the captured frame will be replayed + // and those counters will override this value when it comes to a + // DrawAuto() + if(IsReplayingAndReading()) + { + for(const HiddenCounter &c : HiddenStreamOutCounters) + { + if(m_pDevice->GetResourceManager()->HasLiveResource(c.id)) + m_StreamOutCounters[m_pDevice->GetResourceManager()->GetLiveID(c.id)].numPrims = + c.counterValue; } } @@ -408,10 +426,10 @@ void WrappedID3D11DeviceContext::VerifyState() void WrappedID3D11DeviceContext::BeginCaptureFrame() { - SCOPED_SERIALISE_CONTEXT(CONTEXT_CAPTURE_HEADER); - m_pSerialiser->Serialise("context", m_ResourceID); + WriteSerialiser &ser = m_ScratchSerialiser; + SCOPED_SERIALISE_CHUNK(D3D11Chunk::CaptureBegin); - Serialise_BeginCaptureFrame(false); + Serialise_BeginCaptureFrame(ser, false); { SCOPED_LOCK(m_AnnotLock); @@ -424,7 +442,7 @@ void WrappedID3D11DeviceContext::BeginCaptureFrame() void WrappedID3D11DeviceContext::AttemptCapture() { - m_State = WRITING_CAPFRAME; + m_State = CaptureState::ActiveCapturing; m_FailureReason = CaptureSucceeded; @@ -475,7 +493,7 @@ void WrappedID3D11DeviceContext::FinishCapture() if(GetType() != D3D11_DEVICE_CONTEXT_DEFERRED || !RenderDoc::Inst().GetCaptureOptions().CaptureAllCmdLists) { - m_State = WRITING_IDLE; + m_State = CaptureState::BackgroundCapturing; m_SuccessfulCapture = false; m_FailureReason = CaptureSucceeded; @@ -484,35 +502,22 @@ void WrappedID3D11DeviceContext::FinishCapture() void WrappedID3D11DeviceContext::EndCaptureFrame() { - SCOPED_SERIALISE_CONTEXT(CONTEXT_CAPTURE_FOOTER); - m_pSerialiser->Serialise("context", m_ResourceID); + WriteSerialiser &ser = m_ScratchSerialiser; + ser.SetDrawChunk(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::CaptureEnd); - bool HasCallstack = RenderDoc::Inst().GetCaptureOptions().CaptureCallstacks != 0; - m_pSerialiser->Serialise("HasCallstack", HasCallstack); - - if(HasCallstack) - { - Callstack::Stackwalk *call = Callstack::Collect(); - - RDCASSERT(call->NumLevels() < 0xff); - - size_t numLevels = call->NumLevels(); - uint64_t *stack = (uint64_t *)call->GetAddrs(); - - m_pSerialiser->SerialisePODArray("callstack", stack, numLevels); - - delete call; - } + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); m_ContextRecord->AddChunk(scope.Get()); } void WrappedID3D11DeviceContext::Present(UINT SyncInterval, UINT Flags) { - SCOPED_SERIALISE_CONTEXT(SWAP_PRESENT); - m_pSerialiser->Serialise("context", m_ResourceID); - m_pSerialiser->Serialise("SyncInterval", SyncInterval); - m_pSerialiser->Serialise("Flags", Flags); + WriteSerialiser &ser = m_ScratchSerialiser; + SCOPED_SERIALISE_CHUNK(D3D11Chunk::SwapchainPresent); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + SERIALISE_ELEMENT(SyncInterval); + SERIALISE_ELEMENT(Flags); m_ContextRecord->AddChunk(scope.Get()); } @@ -606,7 +611,7 @@ void WrappedID3D11DeviceContext::EndFrame() { DrainAnnotationQueue(); - if(m_State == WRITING_IDLE) + if(IsBackgroundCapturing(m_State)) m_pDevice->GetResourceManager()->FlushPendingDirty(); } @@ -615,144 +620,162 @@ bool WrappedID3D11DeviceContext::IsFL11_1() return m_pDevice->GetFeatureLevel() >= D3D_FEATURE_LEVEL_11_1; } -void WrappedID3D11DeviceContext::ProcessChunk(uint64_t offset, D3D11ChunkType chunk, bool forceExecute) +void WrappedID3D11DeviceContext::ProcessChunk(ReadSerialiser &ser, D3D11Chunk chunk) { - m_CurChunkOffset = offset; - ResourceId ctxId; - m_pSerialiser->Serialise("context", ctxId); - - // ctxId is now ignored - WrappedID3D11DeviceContext *context = this; - - LogState state = context->m_State; - - if(forceExecute) - context->m_State = EXECUTING; - else - context->m_State = m_State; + SERIALISE_ELEMENT(ctxId).Named("Context ID"); m_AddedDrawcall = false; switch(chunk) { - case SET_INPUT_LAYOUT: context->Serialise_IASetInputLayout(0x0); break; - case SET_VBUFFER: context->Serialise_IASetVertexBuffers(0, 0, 0x0, 0x0, 0x0); break; - case SET_IBUFFER: context->Serialise_IASetIndexBuffer(0, DXGI_FORMAT_UNKNOWN, 0); break; - case SET_TOPOLOGY: - context->Serialise_IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED); + case D3D11Chunk::IASetInputLayout: Serialise_IASetInputLayout(ser, 0x0); break; + case D3D11Chunk::IASetVertexBuffers: + Serialise_IASetVertexBuffers(ser, 0, 0, 0x0, 0x0, 0x0); + break; + case D3D11Chunk::IASetIndexBuffer: + Serialise_IASetIndexBuffer(ser, 0, DXGI_FORMAT_UNKNOWN, 0); + break; + case D3D11Chunk::IASetPrimitiveTopology: + Serialise_IASetPrimitiveTopology(ser, D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED); break; - case SET_VS_CBUFFERS: context->Serialise_VSSetConstantBuffers(0, 0, 0x0); break; - case SET_VS_RESOURCES: context->Serialise_VSSetShaderResources(0, 0, 0x0); break; - case SET_VS_SAMPLERS: context->Serialise_VSSetSamplers(0, 0, 0x0); break; - case SET_VS: context->Serialise_VSSetShader(0x0, 0x0, 0); break; + case D3D11Chunk::VSSetConstantBuffers: Serialise_VSSetConstantBuffers(ser, 0, 0, 0x0); break; + case D3D11Chunk::VSSetShaderResources: Serialise_VSSetShaderResources(ser, 0, 0, 0x0); break; + case D3D11Chunk::VSSetSamplers: Serialise_VSSetSamplers(ser, 0, 0, 0x0); break; + case D3D11Chunk::VSSetShader: Serialise_VSSetShader(ser, 0x0, 0x0, 0); break; - case SET_HS_CBUFFERS: context->Serialise_HSSetConstantBuffers(0, 0, 0x0); break; - case SET_HS_RESOURCES: context->Serialise_HSSetShaderResources(0, 0, 0x0); break; - case SET_HS_SAMPLERS: context->Serialise_HSSetSamplers(0, 0, 0x0); break; - case SET_HS: context->Serialise_HSSetShader(0x0, 0x0, 0); break; + case D3D11Chunk::HSSetConstantBuffers: Serialise_HSSetConstantBuffers(ser, 0, 0, 0x0); break; + case D3D11Chunk::HSSetShaderResources: Serialise_HSSetShaderResources(ser, 0, 0, 0x0); break; + case D3D11Chunk::HSSetSamplers: Serialise_HSSetSamplers(ser, 0, 0, 0x0); break; + case D3D11Chunk::HSSetShader: Serialise_HSSetShader(ser, 0x0, 0x0, 0); break; - case SET_DS_CBUFFERS: context->Serialise_DSSetConstantBuffers(0, 0, 0x0); break; - case SET_DS_RESOURCES: context->Serialise_DSSetShaderResources(0, 0, 0x0); break; - case SET_DS_SAMPLERS: context->Serialise_DSSetSamplers(0, 0, 0x0); break; - case SET_DS: context->Serialise_DSSetShader(0x0, 0x0, 0); break; + case D3D11Chunk::DSSetConstantBuffers: Serialise_DSSetConstantBuffers(ser, 0, 0, 0x0); break; + case D3D11Chunk::DSSetShaderResources: Serialise_DSSetShaderResources(ser, 0, 0, 0x0); break; + case D3D11Chunk::DSSetSamplers: Serialise_DSSetSamplers(ser, 0, 0, 0x0); break; + case D3D11Chunk::DSSetShader: Serialise_DSSetShader(ser, 0x0, 0x0, 0); break; - case SET_GS_CBUFFERS: context->Serialise_GSSetConstantBuffers(0, 0, 0x0); break; - case SET_GS_RESOURCES: context->Serialise_GSSetShaderResources(0, 0, 0x0); break; - case SET_GS_SAMPLERS: context->Serialise_GSSetSamplers(0, 0, 0x0); break; - case SET_GS: context->Serialise_GSSetShader(0x0, 0x0, 0); break; + case D3D11Chunk::GSSetConstantBuffers: Serialise_GSSetConstantBuffers(ser, 0, 0, 0x0); break; + case D3D11Chunk::GSSetShaderResources: Serialise_GSSetShaderResources(ser, 0, 0, 0x0); break; + case D3D11Chunk::GSSetSamplers: Serialise_GSSetSamplers(ser, 0, 0, 0x0); break; + case D3D11Chunk::GSSetShader: Serialise_GSSetShader(ser, 0x0, 0x0, 0); break; - case SET_SO_TARGETS: context->Serialise_SOSetTargets(0, 0x0, 0x0); break; + case D3D11Chunk::SOSetTargets: Serialise_SOSetTargets(ser, 0, 0x0, 0x0); break; - case SET_PS_CBUFFERS: context->Serialise_PSSetConstantBuffers(0, 0, 0x0); break; - case SET_PS_RESOURCES: context->Serialise_PSSetShaderResources(0, 0, 0x0); break; - case SET_PS_SAMPLERS: context->Serialise_PSSetSamplers(0, 0, 0x0); break; - case SET_PS: context->Serialise_PSSetShader(0x0, 0x0, 0); break; + case D3D11Chunk::PSSetConstantBuffers: Serialise_PSSetConstantBuffers(ser, 0, 0, 0x0); break; + case D3D11Chunk::PSSetShaderResources: Serialise_PSSetShaderResources(ser, 0, 0, 0x0); break; + case D3D11Chunk::PSSetSamplers: Serialise_PSSetSamplers(ser, 0, 0, 0x0); break; + case D3D11Chunk::PSSetShader: Serialise_PSSetShader(ser, 0x0, 0x0, 0); break; - case SET_CS_CBUFFERS: context->Serialise_CSSetConstantBuffers(0, 0, 0x0); break; - case SET_CS_RESOURCES: context->Serialise_CSSetShaderResources(0, 0, 0x0); break; - case SET_CS_UAVS: context->Serialise_CSSetUnorderedAccessViews(0, 0, 0x0, 0x0); break; - case SET_CS_SAMPLERS: context->Serialise_CSSetSamplers(0, 0, 0x0); break; - case SET_CS: context->Serialise_CSSetShader(0x0, 0x0, 0); break; - - case SET_VIEWPORTS: context->Serialise_RSSetViewports(0, 0x0); break; - case SET_SCISSORS: context->Serialise_RSSetScissorRects(0, 0x0); break; - case SET_RASTER: context->Serialise_RSSetState(0x0); break; - - case SET_RTARGET: context->Serialise_OMSetRenderTargets(0, 0x0, 0x0); break; - case SET_RTARGET_AND_UAVS: - context->Serialise_OMSetRenderTargetsAndUnorderedAccessViews(0, 0x0, 0x0, 0, 0, 0x0, 0x0); + case D3D11Chunk::CSSetConstantBuffers: Serialise_CSSetConstantBuffers(ser, 0, 0, 0x0); break; + case D3D11Chunk::CSSetShaderResources: Serialise_CSSetShaderResources(ser, 0, 0, 0x0); break; + case D3D11Chunk::CSSetUnorderedAccessViews: + Serialise_CSSetUnorderedAccessViews(ser, 0, 0, 0x0, 0x0); break; - case SET_BLEND: context->Serialise_OMSetBlendState(0x0, (FLOAT *)0x0, 0); break; - case SET_DEPTHSTENCIL: context->Serialise_OMSetDepthStencilState(0x0, 0); break; + case D3D11Chunk::CSSetSamplers: Serialise_CSSetSamplers(ser, 0, 0, 0x0); break; + case D3D11Chunk::CSSetShader: Serialise_CSSetShader(ser, 0x0, 0x0, 0); break; - case DRAW_INDEXED_INST: context->Serialise_DrawIndexedInstanced(0, 0, 0, 0, 0); break; - case DRAW_INST: context->Serialise_DrawInstanced(0, 0, 0, 0); break; - case DRAW_INDEXED: context->Serialise_DrawIndexed(0, 0, 0); break; - case DRAW: context->Serialise_Draw(0, 0); break; - case DRAW_AUTO: context->Serialise_DrawAuto(); break; - case DRAW_INDEXED_INST_INDIRECT: context->Serialise_DrawIndexedInstancedIndirect(0x0, 0); break; - case DRAW_INST_INDIRECT: context->Serialise_DrawInstancedIndirect(0x0, 0); break; + case D3D11Chunk::RSSetViewports: Serialise_RSSetViewports(ser, 0, 0x0); break; + case D3D11Chunk::RSSetScissorRects: Serialise_RSSetScissorRects(ser, 0, 0x0); break; + case D3D11Chunk::RSSetState: Serialise_RSSetState(ser, 0x0); break; - case MAP: context->Serialise_Map(0, 0, (D3D11_MAP)0, 0, 0); break; - case UNMAP: context->Serialise_Unmap(0, 0); break; - - case COPY_SUBRESOURCE_REGION: - context->Serialise_CopySubresourceRegion(0x0, 0, 0, 0, 0, 0x0, 0, 0x0); + case D3D11Chunk::OMSetRenderTargets: Serialise_OMSetRenderTargets(ser, 0, 0x0, 0x0); break; + case D3D11Chunk::OMSetRenderTargetsAndUnorderedAccessViews: + Serialise_OMSetRenderTargetsAndUnorderedAccessViews(ser, 0, 0x0, 0x0, 0, 0, 0x0, 0x0); break; - case COPY_RESOURCE: context->Serialise_CopyResource(0x0, 0x0); break; - case UPDATE_SUBRESOURCE: context->Serialise_UpdateSubresource(0x0, 0, 0x0, 0x0, 0, 0); break; - case COPY_STRUCTURE_COUNT: context->Serialise_CopyStructureCount(0x0, 0, 0x0); break; - case RESOLVE_SUBRESOURCE: - context->Serialise_ResolveSubresource(0x0, 0, 0x0, 0, DXGI_FORMAT_UNKNOWN); + case D3D11Chunk::OMSetBlendState: Serialise_OMSetBlendState(ser, 0x0, (FLOAT *)0x0, 0); break; + case D3D11Chunk::OMSetDepthStencilState: Serialise_OMSetDepthStencilState(ser, 0x0, 0); break; + + case D3D11Chunk::DrawIndexedInstanced: + Serialise_DrawIndexedInstanced(ser, 0, 0, 0, 0, 0); break; - case GENERATE_MIPS: context->Serialise_GenerateMips(0x0); break; - - case CLEAR_DSV: context->Serialise_ClearDepthStencilView(0x0, 0, 0.0f, 0); break; - case CLEAR_RTV: context->Serialise_ClearRenderTargetView(0x0, (FLOAT *)0x0); break; - case CLEAR_UAV_INT: context->Serialise_ClearUnorderedAccessViewUint(0x0, (UINT *)0x0); break; - case CLEAR_UAV_FLOAT: - context->Serialise_ClearUnorderedAccessViewFloat(0x0, (FLOAT *)0x0); + case D3D11Chunk::DrawInstanced: Serialise_DrawInstanced(ser, 0, 0, 0, 0); break; + case D3D11Chunk::DrawIndexed: Serialise_DrawIndexed(ser, 0, 0, 0); break; + case D3D11Chunk::Draw: Serialise_Draw(ser, 0, 0); break; + case D3D11Chunk::DrawAuto: Serialise_DrawAuto(ser); break; + case D3D11Chunk::DrawIndexedInstancedIndirect: + Serialise_DrawIndexedInstancedIndirect(ser, 0x0, 0); break; - case CLEAR_STATE: context->Serialise_ClearState(); break; + case D3D11Chunk::DrawInstancedIndirect: Serialise_DrawInstancedIndirect(ser, 0x0, 0); break; - case EXECUTE_CMD_LIST: context->Serialise_ExecuteCommandList(0x0, 0); break; - case DISPATCH: context->Serialise_Dispatch(0, 0, 0); break; - case DISPATCH_INDIRECT: context->Serialise_DispatchIndirect(0x0, 0); break; - case FINISH_CMD_LIST: context->Serialise_FinishCommandList(0, 0x0); break; - case FLUSH: context->Serialise_Flush(); break; + case D3D11Chunk::Map: Serialise_Map(ser, 0, 0, (D3D11_MAP)0, 0, 0); break; + case D3D11Chunk::Unmap: Serialise_Unmap(ser, 0, 0); break; - case SET_PREDICATION: context->Serialise_SetPredication(0x0, 0x0); break; - case SET_RESOURCE_MINLOD: context->Serialise_SetResourceMinLOD(0x0, 0); break; - - case BEGIN: context->Serialise_Begin(0x0); break; - case END: context->Serialise_End(0x0); break; - - case COPY_SUBRESOURCE_REGION1: - context->Serialise_CopySubresourceRegion1(0x0, 0, 0, 0, 0, 0x0, 0, 0x0, 0); + case D3D11Chunk::CopySubresourceRegion: + Serialise_CopySubresourceRegion(ser, 0x0, 0, 0, 0, 0, 0x0, 0, 0x0); break; - case UPDATE_SUBRESOURCE1: - context->Serialise_UpdateSubresource1(0x0, 0, 0x0, 0x0, 0, 0, 0); + case D3D11Chunk::CopyResource: Serialise_CopyResource(ser, 0x0, 0x0); break; + case D3D11Chunk::UpdateSubresource: + Serialise_UpdateSubresource(ser, 0x0, 0, 0x0, 0x0, 0, 0); break; - case CLEAR_VIEW: context->Serialise_ClearView(0x0, 0x0, 0x0, 0); break; + case D3D11Chunk::CopyStructureCount: Serialise_CopyStructureCount(ser, 0x0, 0, 0x0); break; + case D3D11Chunk::ResolveSubresource: + Serialise_ResolveSubresource(ser, 0x0, 0, 0x0, 0, DXGI_FORMAT_UNKNOWN); + break; + case D3D11Chunk::GenerateMips: Serialise_GenerateMips(ser, 0x0); break; - case SET_VS_CBUFFERS1: context->Serialise_VSSetConstantBuffers1(0, 0, 0x0, 0x0, 0x0); break; - case SET_HS_CBUFFERS1: context->Serialise_HSSetConstantBuffers1(0, 0, 0x0, 0x0, 0x0); break; - case SET_DS_CBUFFERS1: context->Serialise_DSSetConstantBuffers1(0, 0, 0x0, 0x0, 0x0); break; - case SET_GS_CBUFFERS1: context->Serialise_GSSetConstantBuffers1(0, 0, 0x0, 0x0, 0x0); break; - case SET_PS_CBUFFERS1: context->Serialise_PSSetConstantBuffers1(0, 0, 0x0, 0x0, 0x0); break; - case SET_CS_CBUFFERS1: context->Serialise_CSSetConstantBuffers1(0, 0, 0x0, 0x0, 0x0); break; + case D3D11Chunk::ClearDepthStencilView: + Serialise_ClearDepthStencilView(ser, 0x0, 0, 0.0f, 0); + break; + case D3D11Chunk::ClearRenderTargetView: + Serialise_ClearRenderTargetView(ser, 0x0, (FLOAT *)0x0); + break; + case D3D11Chunk::ClearUnorderedAccessViewUint: + Serialise_ClearUnorderedAccessViewUint(ser, 0x0, (UINT *)0x0); + break; + case D3D11Chunk::ClearUnorderedAccessViewFloat: + Serialise_ClearUnorderedAccessViewFloat(ser, 0x0, (FLOAT *)0x0); + break; + case D3D11Chunk::ClearState: Serialise_ClearState(ser); break; - case PUSH_EVENT: context->Serialise_PushEvent(0, L""); break; - case SET_MARKER: context->Serialise_SetMarker(0, L""); break; - case POP_EVENT: context->Serialise_PopEvent(); break; + case D3D11Chunk::ExecuteCommandList: Serialise_ExecuteCommandList(ser, 0x0, 0); break; + case D3D11Chunk::Dispatch: Serialise_Dispatch(ser, 0, 0, 0); break; + case D3D11Chunk::DispatchIndirect: Serialise_DispatchIndirect(ser, 0x0, 0); break; + case D3D11Chunk::FinishCommandList: Serialise_FinishCommandList(ser, 0, 0x0); break; + case D3D11Chunk::Flush: Serialise_Flush(ser); break; - case DISCARD_RESOURCE: context->Serialise_DiscardResource(NULL); break; - case DISCARD_VIEW: context->Serialise_DiscardView(NULL); break; - case DISCARD_VIEW1: context->Serialise_DiscardView1(NULL, NULL, 0); break; + case D3D11Chunk::SetPredication: Serialise_SetPredication(ser, 0x0, 0x0); break; + case D3D11Chunk::SetResourceMinLOD: Serialise_SetResourceMinLOD(ser, 0x0, 0); break; - case RESTORE_STATE_AFTER_EXEC: + case D3D11Chunk::Begin: Serialise_Begin(ser, 0x0); break; + case D3D11Chunk::End: Serialise_End(ser, 0x0); break; + + case D3D11Chunk::CopySubresourceRegion1: + Serialise_CopySubresourceRegion1(ser, 0x0, 0, 0, 0, 0, 0x0, 0, 0x0, 0); + break; + case D3D11Chunk::UpdateSubresource1: + Serialise_UpdateSubresource1(ser, 0x0, 0, 0x0, 0x0, 0, 0, 0); + break; + case D3D11Chunk::ClearView: Serialise_ClearView(ser, 0x0, 0x0, 0x0, 0); break; + + case D3D11Chunk::VSSetConstantBuffers1: + Serialise_VSSetConstantBuffers1(ser, 0, 0, 0x0, 0x0, 0x0); + break; + case D3D11Chunk::HSSetConstantBuffers1: + Serialise_HSSetConstantBuffers1(ser, 0, 0, 0x0, 0x0, 0x0); + break; + case D3D11Chunk::DSSetConstantBuffers1: + Serialise_DSSetConstantBuffers1(ser, 0, 0, 0x0, 0x0, 0x0); + break; + case D3D11Chunk::GSSetConstantBuffers1: + Serialise_GSSetConstantBuffers1(ser, 0, 0, 0x0, 0x0, 0x0); + break; + case D3D11Chunk::PSSetConstantBuffers1: + Serialise_PSSetConstantBuffers1(ser, 0, 0, 0x0, 0x0, 0x0); + break; + case D3D11Chunk::CSSetConstantBuffers1: + Serialise_CSSetConstantBuffers1(ser, 0, 0, 0x0, 0x0, 0x0); + break; + + case D3D11Chunk::PushMarker: Serialise_PushMarker(ser, 0, L""); break; + case D3D11Chunk::SetMarker: Serialise_SetMarker(ser, 0, L""); break; + case D3D11Chunk::PopMarker: Serialise_PopMarker(ser); break; + + case D3D11Chunk::DiscardResource: Serialise_DiscardResource(ser, NULL); break; + case D3D11Chunk::DiscardView: Serialise_DiscardView(ser, NULL); break; + case D3D11Chunk::DiscardView1: Serialise_DiscardView1(ser, NULL, NULL, 0); break; + + case D3D11Chunk::PostExecuteCommandListRestore: { // apply saved state. if(m_DeferredSavedState) @@ -763,51 +786,38 @@ void WrappedID3D11DeviceContext::ProcessChunk(uint64_t offset, D3D11ChunkType ch break; } - case RESTORE_STATE_AFTER_FINISH: + case D3D11Chunk::PostFinishCommandListSet: { - D3D11RenderState rs(m_pSerialiser); - rs.Serialise(m_State, m_pDevice); - rs.ApplyState(this); + D3D11RenderState RenderState(D3D11RenderState::Empty); + SERIALISE_ELEMENT(RenderState); + RenderState.ApplyState(this); break; } - case SWAP_DEVICE_STATE: Serialise_SwapDeviceContextState(NULL, NULL); break; + case D3D11Chunk::SwapDeviceContextState: + Serialise_SwapDeviceContextState(ser, NULL, NULL); + break; - case SWAP_PRESENT: + case D3D11Chunk::SwapchainPresent: { // we don't do anything with these parameters, they're just here to store // them for user benefits UINT SyncInterval = 0, Flags = 0; - m_pSerialiser->Serialise("SyncInterval", SyncInterval); - m_pSerialiser->Serialise("Flags", Flags); + SERIALISE_ELEMENT(SyncInterval); + SERIALISE_ELEMENT(Flags); m_PresentChunk = true; break; } - case CONTEXT_CAPTURE_FOOTER: + case D3D11Chunk::CaptureEnd: { - bool HasCallstack = false; - m_pSerialiser->Serialise("HasCallstack", HasCallstack); - - if(HasCallstack) - { - size_t numLevels = 0; - uint64_t *stack = NULL; - - m_pSerialiser->SerialisePODArray("callstack", stack, numLevels); - - m_pSerialiser->SetCallstack(stack, numLevels); - - SAFE_DELETE_ARRAY(stack); - } - - if(m_State == READING) + if(IsLoading(m_State)) { if(!m_PresentChunk) - AddEvent("IDXGISwapChain::Present()"); + AddEvent("End of Frame"); DrawcallDescription draw; - draw.name = "Present()"; + draw.name = "End of Frame"; draw.flags |= DrawFlags::Present; draw.copyDestination = m_pDevice->GetBackbufferResourceID(); @@ -819,33 +829,31 @@ void WrappedID3D11DeviceContext::ProcessChunk(uint64_t offset, D3D11ChunkType ch default: RDCERR("Unrecognised Chunk type %d", chunk); break; } - m_pSerialiser->PopContext(chunk); - - if(context->m_State == READING && chunk == SET_MARKER) + if(IsLoading(m_State) && m_CurEventID > 0) { - // no push/pop necessary - } - else if(context->m_State == READING && chunk == PUSH_EVENT) - { - // push down the drawcallstack to the latest drawcall - context->m_DrawcallStack.push_back(&context->m_DrawcallStack.back()->children.back()); - } - else if(context->m_State == READING && chunk == POP_EVENT) - { - // refuse to pop off further than the root drawcall (mismatched begin/end events e.g.) - if(context->m_DrawcallStack.size() > 1) - context->m_DrawcallStack.pop_back(); - } - else if(context->m_State == READING) - { - if(!m_AddedDrawcall) - context->AddEvent(m_pSerialiser->GetDebugStr()); + if(chunk == D3D11Chunk::SetMarker) + { + // no push/pop necessary + } + else if(chunk == D3D11Chunk::PushMarker) + { + // push down the drawcallstack to the latest drawcall + m_DrawcallStack.push_back(&m_DrawcallStack.back()->children.back()); + } + else if(chunk == D3D11Chunk::PopMarker) + { + // refuse to pop off further than the root drawcall (mismatched begin/end events e.g.) + if(m_DrawcallStack.size() > 1) + m_DrawcallStack.pop_back(); + } + else + { + if(!m_AddedDrawcall) + AddEvent(""); + } } m_AddedDrawcall = false; - - if(forceExecute) - context->m_State = state; } void WrappedID3D11DeviceContext::AddUsage(const DrawcallDescription &d) @@ -1011,15 +1019,11 @@ void WrappedID3D11DeviceContext::AddEvent(string description) apievent.eventDesc = description; - Callstack::Stackwalk *stack = m_pSerialiser->GetLastCallstack(); - if(stack) - { - apievent.callstack.assign(stack->GetAddrs(), sizeof(uint64_t) * stack->NumLevels()); - } + apievent.callstack = m_ChunkMetadata.callstack; m_CurEvents.push_back(apievent); - if(m_State == READING) + if(IsLoading(m_State)) m_Events.push_back(apievent); } @@ -1039,405 +1043,44 @@ void WrappedID3D11DeviceContext::ReplayFakeContext(ResourceId id) m_FakeContext = id; } -static void PadToAligned(Serialiser *dst, uint64_t alignment) -{ - uint64_t offs = dst->GetOffset(); - uint64_t alignedoffs = AlignUp(offs, alignment); - - // nothing to do - if(offs == alignedoffs) - return; - - uint16_t chunkIdx = 0; - dst->Serialise("", chunkIdx); - offs += sizeof(chunkIdx); - - uint8_t controlByte = 0; // control byte 0 indicates padding - dst->Serialise("", controlByte); - offs += sizeof(controlByte); - - offs++; // we will have to write out a byte indicating how much padding exists, so add 1 - alignedoffs = AlignUp(offs, alignment); - - uint8_t padLength = (alignedoffs - offs) & 0xff; - dst->Serialise("", padLength); - - // we might have padded with the control bytes, so only write some bytes if we need to - if(padLength > 0) - { - const byte zeroes[256] = {}; - dst->RawWriteBytes(zeroes, (size_t)padLength); - } -} - -static void CopyChunk(Serialiser *src, Serialiser *dst, uint64_t offsBegin) -{ - uint64_t offsEnd = src->GetOffset(); - - // this whole function is quite an abuse of the serialiser interface :(. - // It will all go away when I can break backwards compatibility and remove - // this code and greatly tidy up the interface. - - src->SetOffset(offsBegin); - - dst->RawWriteBytes(src->RawReadBytes(size_t(offsEnd - offsBegin)), size_t(offsEnd - offsBegin)); -} - -static void CopyUnmap(uint32_t d3dLogVersion, Serialiser *src, Serialiser *dst, Serialiser *tmp) -{ - ResourceId Resource; - uint32_t Subresource = 0; - D3D11_MAP MapType = D3D11_MAP_WRITE_DISCARD; - uint32_t MapFlags = 0; - uint32_t DiffStart = 0; - uint32_t DiffEnd = 0; - byte *buf = NULL; - size_t len = 0; - - tmp->Rewind(); - tmp->PushContext("", "", UNMAP, false); - - // context id - ignored but needed to match expected format - tmp->Serialise("", Resource); - - src->Serialise("", Resource); - tmp->Serialise("", Resource); - - src->Serialise("", Subresource); - tmp->Serialise("", Subresource); - - src->Serialise("", MapType); - tmp->Serialise("", MapType); - - src->Serialise("", MapFlags); - tmp->Serialise("", MapFlags); - - src->Serialise("", DiffStart); - tmp->Serialise("", DiffStart); - - src->Serialise("", DiffEnd); - tmp->Serialise("", DiffEnd); - - if(d3dLogVersion >= 0x000007) - src->AlignNextBuffer(32); - - src->SerialiseBuffer("", buf, len); - tmp->SerialiseBuffer("", buf, len); - - src->PopContext(UNMAP); - tmp->PopContext(UNMAP); - - SAFE_DELETE_ARRAY(buf); - - dst->RawWriteBytes(tmp->GetRawPtr(0), size_t(tmp->GetOffset())); -} - -static void CopyUpdateSubresource(uint32_t d3dLogVersion, Serialiser *src, Serialiser *dst, - Serialiser *tmp) -{ - ResourceId idx; - uint32_t flags = 0; - uint32_t DestSubresource = 0; - uint8_t isUpdate = true; - - uint8_t HasDestBox = 0; - D3D11_BOX box = {}; - uint32_t SourceRowPitch = 0; - uint32_t SourceDepthPitch = 0; - - uint32_t ResourceBufLen = 0; - - byte *buf = NULL; - size_t len = 0; - - tmp->Rewind(); - tmp->PushContext("", "", UPDATE_SUBRESOURCE1, false); - - // context id - ignored but needed to match expected format - tmp->Serialise("", idx); - - src->Serialise("", idx); - tmp->Serialise("", idx); - - src->Serialise("", flags); - tmp->Serialise("", flags); - - src->Serialise("", DestSubresource); - tmp->Serialise("", DestSubresource); - - src->Serialise("", isUpdate); - tmp->Serialise("", isUpdate); - - if(isUpdate) - { - src->Serialise("", HasDestBox); - tmp->Serialise("", HasDestBox); - - if(HasDestBox) - { - src->Serialise("", box); - tmp->Serialise("", box); - } - - src->Serialise("", SourceRowPitch); - tmp->Serialise("", SourceRowPitch); - - src->Serialise("", SourceDepthPitch); - tmp->Serialise("", SourceDepthPitch); - - src->Serialise("", ResourceBufLen); - tmp->Serialise("", ResourceBufLen); - - src->SerialiseBuffer("", buf, len); - tmp->SerialiseBuffer("", buf, len); - } - else - { - // shouldn't get in here, any chunks we're looking at are context chunks - // so they should be recorded as updates - - src->Serialise("", ResourceBufLen); - tmp->Serialise("", ResourceBufLen); - - if(d3dLogVersion >= 0x000007) - src->AlignNextBuffer(32); - - src->SerialiseBuffer("", buf, len); - tmp->SerialiseBuffer("", buf, len); - } - - src->PopContext(UPDATE_SUBRESOURCE1); - tmp->PopContext(UPDATE_SUBRESOURCE1); - - SAFE_DELETE_ARRAY(buf); - - dst->RawWriteBytes(tmp->GetRawPtr(0), size_t(tmp->GetOffset())); -} - -void WrappedID3D11DeviceContext::FlattenLog() -{ - Serialiser *src = m_pSerialiser; - Serialiser *dst = new Serialiser(NULL, Serialiser::WRITING, false); - - Serialiser *tmp = new Serialiser(NULL, Serialiser::WRITING, false); - - map deferred; - - uint64_t offsBegin = src->GetOffset(); - - D3D11ChunkType chunk = (D3D11ChunkType)src->PushContext(NULL, NULL, 1, false); - RDCASSERTEQUAL(chunk, CONTEXT_CAPTURE_HEADER); - src->SkipCurrentChunk(); - src->PopContext(chunk); - - CopyChunk(src, dst, offsBegin); - - for(;;) - { - offsBegin = src->GetOffset(); - - chunk = (D3D11ChunkType)src->PushContext(NULL, NULL, 1, false); - - ResourceId ctx; - src->Serialise("ctx", ctx); - - WrappedID3D11DeviceContext *context = - (WrappedID3D11DeviceContext *)m_pDevice->GetResourceManager()->GetLiveResource(ctx); - - // if it's a local chunk just copy it - if(context == this) - { - ResourceId cmdList; - uint8_t restore = 0; - - if(chunk == EXECUTE_CMD_LIST) - { - m_pSerialiser->Serialise("RestoreContextState", restore); - m_pSerialiser->Serialise("cmdList", cmdList); - } - - // these chunks need to be reserialised individually to ensure padding bytes in - // between all remain the same - if(chunk == UNMAP) - { - PadToAligned(dst, 64); - CopyUnmap(m_pDevice->GetLogVersion(), src, dst, tmp); - } - else if(chunk == UPDATE_SUBRESOURCE || chunk == UPDATE_SUBRESOURCE1) - { - PadToAligned(dst, 64); - CopyUpdateSubresource(m_pDevice->GetLogVersion(), src, dst, tmp); - } - else - { - src->SetOffset(offsBegin); - src->PushContext(NULL, NULL, 1, false); - src->SkipCurrentChunk(); - src->PopContext(chunk); - - CopyChunk(src, dst, offsBegin); - } - - if(chunk == EXECUTE_CMD_LIST) - { - Serialiser *def = deferred[cmdList]; - - if(def == NULL) - { - RDCERR("ExecuteCommandList found for command list we didn't Finish!"); - } - else - { - // when inserting, ensure the chunks stay aligned (this is harmless if they don't need - // alignment). Do this by inserting padding bytes, ugly but it works. - PadToAligned(dst, 64); - - // now insert the chunks to replay - dst->RawWriteBytes(deferred[cmdList]->GetRawPtr(0), (size_t)deferred[cmdList]->GetSize()); - - // if we have to restore the state, the above Execute.. will have - // saved it, so we just add a little chunk to let it pop it again - if(restore) - { - tmp->Rewind(); - tmp->PushContext("", "", RESTORE_STATE_AFTER_EXEC, false); - tmp->PopContext(RESTORE_STATE_AFTER_EXEC); - - dst->RawWriteBytes(tmp->GetRawPtr(0), size_t(tmp->GetOffset())); - } - - // again since we inserted chunks we need to align again - PadToAligned(dst, 64); - } - } - } - else - { - if(deferred[ctx] == NULL) - deferred[ctx] = new Serialiser(NULL, Serialiser::WRITING, false); - - ResourceId cmdList; - uint8_t restore = 0; - - if(chunk == FINISH_CMD_LIST) - { - m_pSerialiser->Serialise("RestoreDeferredContextState", restore); - m_pSerialiser->Serialise("cmdList", cmdList); - - if(restore != 0) - { - RDCWARN( - "RestoreDeferredContextState == TRUE was set for command list %llu. " - "On old captures this wasn't properly replayed and can't be fixed as-is, " - "re-capture with latest RenderDoc to solve this issue."); - } - } - - // these chunks need to be reserialised individually to ensure padding bytes in - // between all remain the same - if(chunk == UNMAP) - { - PadToAligned(deferred[ctx], 64); - CopyUnmap(m_pDevice->GetLogVersion(), src, deferred[ctx], tmp); - } - else if(chunk == UPDATE_SUBRESOURCE || chunk == UPDATE_SUBRESOURCE1) - { - PadToAligned(deferred[ctx], 64); - CopyUpdateSubresource(m_pDevice->GetLogVersion(), src, deferred[ctx], tmp); - } - else - { - src->SetOffset(offsBegin); - src->PushContext(NULL, NULL, 1, false); - src->SkipCurrentChunk(); - src->PopContext(chunk); - - CopyChunk(src, deferred[ctx], offsBegin); - } - - if(chunk == FINISH_CMD_LIST) - { - // here is where RestoreDeferredContextState is broken, this doesn't - // take into account the inherited state from previous recordings. - deferred[cmdList] = deferred[ctx]; - deferred[ctx] = new Serialiser(NULL, Serialiser::WRITING, false); - } - } - - if(chunk == CONTEXT_CAPTURE_FOOTER) - { - break; - } - } - - m_pSerialiser = new Serialiser((size_t)dst->GetSize(), dst->GetRawPtr(0), false); - m_OwnSerialiser = true; - - m_pSerialiser->SetDebugText(true); - m_pSerialiser->SetChunkNameLookup(&WrappedID3D11Device::GetChunkName); - - // tidy up the temporary serialisers - SAFE_DELETE(dst); - SAFE_DELETE(tmp); - - for(auto it = deferred.begin(); it != deferred.end(); ++it) - SAFE_DELETE(it->second); -} - -void WrappedID3D11DeviceContext::ReplayLog(LogState readType, uint32_t startEventID, +void WrappedID3D11DeviceContext::ReplayLog(CaptureState readType, uint32_t startEventID, uint32_t endEventID, bool partial) { m_State = readType; - if(readType == READING && m_pDevice->GetNumDeferredContexts() && - m_pDevice->GetLogVersion() < 0x00000A) + if(!m_FrameReader) { - RDCLOG("Flattening log file"); - - // flatten the log - FlattenLog(); - - RDCLOG("Flattened"); + RDCERR("Can't replay context capture without frame reader"); + return; } - if(readType != READING) - m_pSerialiser->SetDebugText(false); + m_FrameReader->SetOffset(0); + + ReadSerialiser ser(m_FrameReader, Ownership::Nothing); + + ser.SetStringDatabase(&m_StringDB); + ser.SetUserData(GetResourceManager()); + + if(IsLoading(m_State)) + ser.ConfigureStructuredExport(&GetChunkName, false); m_DoStateVerify = true; - if(readType == EXECUTING && m_pDevice->GetNumDeferredContexts() && - m_pDevice->GetLogVersion() < 0x00000A) - { - m_pSerialiser->SetOffset(0); - } + D3D11Chunk header = ser.ReadChunk(); + RDCASSERTEQUAL(header, D3D11Chunk::CaptureBegin); - D3D11ChunkType header = (D3D11ChunkType)m_pSerialiser->PushContext(NULL, NULL, 1, false); - RDCASSERTEQUAL(header, CONTEXT_CAPTURE_HEADER); + Serialise_BeginCaptureFrame(ser, !partial); - ResourceId id; - m_pSerialiser->Serialise("context", id); - - // id is now ignored - - Serialise_BeginCaptureFrame(!partial); - - m_pSerialiser->PopContext(header); + ser.EndChunk(); m_CurEvents.clear(); - if(m_State == EXECUTING) + if(IsActiveReplaying(m_State)) { APIEvent ev = GetEvent(startEventID); m_CurEventID = ev.eventID; - m_pSerialiser->SetOffset(ev.fileOffset); - } - else if(m_State == READING) - { - m_CurEventID = 1; - } + ser.GetReader()->SetOffset(ev.fileOffset); - if(m_State == EXECUTING) - { ClearMaps(); for(size_t i = 0; i < m_pDevice->GetNumDeferredContexts(); i++) { @@ -1445,14 +1088,18 @@ void WrappedID3D11DeviceContext::ReplayLog(LogState readType, uint32_t startEven defcontext->ClearMaps(); } } + else + { + m_CurEventID = 1; + } m_pDevice->GetResourceManager()->MarkInFrame(true); - uint64_t startOffset = m_pSerialiser->GetOffset(); + uint64_t startOffset = ser.GetReader()->GetOffset(); for(;;) { - if(m_State == EXECUTING && m_CurEventID > endEventID) + if(IsActiveReplaying(m_State) && m_CurEventID > endEventID) { // set event ID correctly as we haven't actually replayed the next one. m_CurEventID = endEventID; @@ -1460,24 +1107,26 @@ void WrappedID3D11DeviceContext::ReplayLog(LogState readType, uint32_t startEven break; } - uint64_t offset = m_pSerialiser->GetOffset(); + m_CurChunkOffset = ser.GetReader()->GetOffset(); - D3D11ChunkType chunktype = (D3D11ChunkType)m_pSerialiser->PushContext(NULL, NULL, 1, false); + D3D11Chunk chunktype = ser.ReadChunk(); - ProcessChunk(offset, chunktype, false); + m_ChunkMetadata = ser.ChunkMetadata(); - RenderDoc::Inst().SetProgress(FrameEventsRead, - float(offset - startOffset) / float(m_pSerialiser->GetSize())); + ProcessChunk(ser, chunktype); - // for now just abort after capture scope. Really we'd need to support multiple frames - // but for now this will do. - if(chunktype == CONTEXT_CAPTURE_FOOTER) + ser.EndChunk(); + + RenderDoc::Inst().SetProgress( + FrameEventsRead, float(m_CurChunkOffset - startOffset) / float(ser.GetReader()->GetSize())); + + if(chunktype == D3D11Chunk::CaptureEnd) break; m_CurEventID++; } - if(m_State == READING) + if(IsLoading(m_State)) { m_pDevice->GetFrameRecord().drawcallList = m_ParentDrawcall.children; m_pDevice->GetFrameRecord().frameInfo.debugMessages = m_pDevice->GetDebugMessages(); @@ -1561,8 +1210,6 @@ void WrappedID3D11DeviceContext::ReplayLog(LogState readType, uint32_t startEven m_pDevice->GetResourceManager()->MarkInFrame(false); - m_State = READING; - m_DoStateVerify = false; } @@ -1664,8 +1311,7 @@ HRESULT STDMETHODCALLTYPE WrappedID3D11DeviceContext::QueryInterface(REFIID riid } else { - string guid = ToStr(riid); - RDCWARN("Querying ID3D11DeviceContext for interface: %s", guid.c_str()); + RDCWARN("Querying ID3D11DeviceContext for interface: %s", ToStr(riid).c_str()); } return RefCounter::QueryInterface(riid, ppvObject); diff --git a/renderdoc/driver/d3d11/d3d11_context.h b/renderdoc/driver/d3d11/d3d11_context.h index 8f4a76cf6..02aa5c388 100644 --- a/renderdoc/driver/d3d11/d3d11_context.h +++ b/renderdoc/driver/d3d11/d3d11_context.h @@ -148,6 +148,11 @@ private: bool m_NeedUpdateSubWorkaround; + WriteSerialiser m_ScratchSerialiser; + std::set m_StringDB; + + StreamReader *m_FrameReader = NULL; + map m_MapResourceRecordAllocs; set m_MissingTracks; @@ -155,9 +160,7 @@ private: ResourceId m_ResourceID; D3D11ResourceRecord *m_ContextRecord; - bool m_OwnSerialiser; - Serialiser *m_pSerialiser; - LogState m_State; + CaptureState m_State; CaptureFailReason m_FailureReason; bool m_SuccessfulCapture; bool m_EmptyCommandList; @@ -192,6 +195,7 @@ private: Threading::CriticalSection m_AnnotLock; uint64_t m_CurChunkOffset; + SDChunkMetaData m_ChunkMetadata; uint32_t m_CurEventID, m_CurDrawcallID; DrawcallDescription m_ParentDrawcall; @@ -199,11 +203,11 @@ private: list m_DrawcallStack; - void FlattenLog(); + D3D11ResourceManager *GetResourceManager(); + static std::string GetChunkName(uint32_t idx); - const char *GetChunkName(D3D11Chunk idx); - - void Serialise_DebugMessages(); + template + void Serialise_DebugMessages(SerialiserType &ser); void DrainAnnotationQueue(); @@ -235,18 +239,16 @@ private: //////////////////////////////////////////////////////////////// // implement InterceptorSystem privately, since it is not thread safe (like all other context // functions) - IMPLEMENT_FUNCTION_SERIALISED(void, SetMarker(uint32_t col, const wchar_t *name)); - IMPLEMENT_FUNCTION_SERIALISED(int, PushEvent(uint32_t col, const wchar_t *name)); - IMPLEMENT_FUNCTION_SERIALISED(int, PopEvent()); + IMPLEMENT_FUNCTION_SERIALISED(void, SetMarker, uint32_t col, const wchar_t *name); + IMPLEMENT_FUNCTION_SERIALISED(int, PushMarker, uint32_t col, const wchar_t *name); + IMPLEMENT_FUNCTION_SERIALISED(int, PopMarker); public: - static const int AllocPoolCount = 2048; + static const int AllocPoolCount = 1024; static const int AllocPoolMaxByteSize = 3 * 1024 * 1024; ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11DeviceContext, AllocPoolCount, AllocPoolMaxByteSize); - WrappedID3D11DeviceContext(WrappedID3D11Device *realDevice, ID3D11DeviceContext *context, - Serialiser *ser); - void SetSerialiser(Serialiser *ser) { m_pSerialiser = ser; } + WrappedID3D11DeviceContext(WrappedID3D11Device *realDevice, ID3D11DeviceContext *context); virtual ~WrappedID3D11DeviceContext(); void VerifyState(); @@ -254,7 +256,8 @@ public: void BeginFrame(); void EndFrame(); - bool Serialise_BeginCaptureFrame(bool applyInitialState); + template + bool Serialise_BeginCaptureFrame(SerialiserType &ser, bool applyInitialState); void BeginCaptureFrame(); void EndCaptureFrame(); @@ -276,16 +279,15 @@ public: void FinishCapture(); D3D11RenderState *GetCurrentPipelineState() { return m_CurrentPipelineState; } - Serialiser *GetSerialiser() { return m_pSerialiser; } ResourceId GetResourceID() { return m_ResourceID; } ID3D11DeviceContext *GetReal() { return m_pRealContext; } ID3D11DeviceContext1 *GetReal1() { return m_pRealContext1; } bool IsFL11_1(); - void ProcessChunk(uint64_t offset, D3D11Chunk chunk, bool forceExecute); + void ProcessChunk(ReadSerialiser &ser, D3D11Chunk chunk); void ReplayFakeContext(ResourceId id); - void ReplayLog(LogState readType, uint32_t startEventID, uint32_t endEventID, bool partial); - + void ReplayLog(CaptureState readType, uint32_t startEventID, uint32_t endEventID, bool partial); + void SetFrameReader(StreamReader *reader) { m_FrameReader = reader; } void MarkResourceReferenced(ResourceId id, FrameRefType refType); vector GetUsage(ResourceId id) { return m_ResourceUses[id]; } diff --git a/renderdoc/driver/d3d11/d3d11_context2_wrap.cpp b/renderdoc/driver/d3d11/d3d11_context2_wrap.cpp index afb0ff6b2..81eb770b5 100644 --- a/renderdoc/driver/d3d11/d3d11_context2_wrap.cpp +++ b/renderdoc/driver/d3d11/d3d11_context2_wrap.cpp @@ -131,10 +131,10 @@ void WrappedID3D11DeviceContext::SetMarkerInt(LPCWSTR pLabel, INT Data) void WrappedID3D11DeviceContext::BeginEventInt(LPCWSTR pLabel, INT Data) { - PushEvent(0, pLabel); + PushMarker(0, pLabel); } void WrappedID3D11DeviceContext::EndEvent() { - PopEvent(); + PopMarker(); } diff --git a/renderdoc/driver/d3d11/d3d11_context_wrap.cpp b/renderdoc/driver/d3d11/d3d11_context_wrap.cpp index d20902c33..bc3253cc0 100644 --- a/renderdoc/driver/d3d11/d3d11_context_wrap.cpp +++ b/renderdoc/driver/d3d11/d3d11_context_wrap.cpp @@ -152,13 +152,13 @@ void WrappedID3D11DeviceContext::SetMarker(uint32_t col, const wchar_t *name) } } -int WrappedID3D11DeviceContext::PushEvent(uint32_t col, const wchar_t *name) +int WrappedID3D11DeviceContext::PushMarker(uint32_t col, const wchar_t *name) { if(m_State == WRITING_CAPFRAME) { SCOPED_SERIALISE_CONTEXT(PUSH_EVENT); m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_PushEvent(col, name); + Serialise_PushMarker(col, name); m_ContextRecord->AddChunk(scope.Get()); } @@ -166,13 +166,13 @@ int WrappedID3D11DeviceContext::PushEvent(uint32_t col, const wchar_t *name) return m_MarkerIndentLevel++; } -int WrappedID3D11DeviceContext::PopEvent() +int WrappedID3D11DeviceContext::PopMarker() { if(m_State == WRITING_CAPFRAME) { SCOPED_SERIALISE_CONTEXT(POP_EVENT); m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_PopEvent(); + Serialise_PopMarker(); m_ContextRecord->AddChunk(scope.Get()); } @@ -251,8 +251,8 @@ void WrappedID3D11DeviceContext::DrainAnnotationQueue() switch(a.m_Type) { case Annotation::ANNOT_SETMARKER: SetMarker(a.m_Col, a.m_Name.c_str()); break; - case Annotation::ANNOT_BEGINEVENT: PushEvent(a.m_Col, a.m_Name.c_str()); break; - case Annotation::ANNOT_ENDEVENT: PopEvent(); break; + case Annotation::ANNOT_BEGINEVENT: PushMarker(a.m_Col, a.m_Name.c_str()); break; + case Annotation::ANNOT_ENDEVENT: PopMarker(); break; } } } diff --git a/renderdoc/driver/d3d11/d3d11_device.cpp b/renderdoc/driver/d3d11/d3d11_device.cpp index d40eb6777..4083b4fb2 100644 --- a/renderdoc/driver/d3d11/d3d11_device.cpp +++ b/renderdoc/driver/d3d11/d3d11_device.cpp @@ -853,7 +853,7 @@ void WrappedID3D11Device::ProcessChunk(ReadSerialiser &ser, D3D11Chunk context) } else { - m_pImmediateContext->ProcessChunk(ser, context, true); + m_pImmediateContext->ProcessChunk(ser, context); } break; }