From 2fe0193b499df84098da45e8f7ac513215275275 Mon Sep 17 00:00:00 2001 From: baldurk Date: Thu, 28 Sep 2017 12:18:37 +0100 Subject: [PATCH] Update D3D11 context wrapping to new serialisation scheme --- renderdoc/driver/d3d11/d3d11_context.cpp | 38 +- renderdoc/driver/d3d11/d3d11_context.h | 26 +- renderdoc/driver/d3d11/d3d11_context_wrap.cpp | 5343 +++++++---------- renderdoc/driver/d3d11/d3d11_renderstate.cpp | 11 +- renderdoc/driver/d3d11/d3d11_renderstate.h | 7 +- renderdoc/driver/d3d11/d3d11_resources.h | 4 +- 6 files changed, 2334 insertions(+), 3095 deletions(-) diff --git a/renderdoc/driver/d3d11/d3d11_context.cpp b/renderdoc/driver/d3d11/d3d11_context.cpp index 4d6324312..e8b910b42 100644 --- a/renderdoc/driver/d3d11/d3d11_context.cpp +++ b/renderdoc/driver/d3d11/d3d11_context.cpp @@ -776,23 +776,10 @@ void WrappedID3D11DeviceContext::ProcessChunk(ReadSerialiser &ser, D3D11Chunk ch case D3D11Chunk::DiscardView1: Serialise_DiscardView1(ser, NULL, NULL, 0); break; case D3D11Chunk::PostExecuteCommandListRestore: - { - // apply saved state. - if(m_DeferredSavedState) - { - m_DeferredSavedState->ApplyState(this); - SAFE_DELETE(m_DeferredSavedState); - } + Serialise_PostExecuteCommandListRestore(ser); break; - } - case D3D11Chunk::PostFinishCommandListSet: - { - D3D11RenderState RenderState(D3D11RenderState::Empty); - SERIALISE_ELEMENT(RenderState); - RenderState.ApplyState(this); - break; - } + case D3D11Chunk::PostFinishCommandListSet: Serialise_PostFinishCommandListSet(ser); break; case D3D11Chunk::SwapDeviceContextState: Serialise_SwapDeviceContextState(ser, NULL, NULL); @@ -814,7 +801,7 @@ void WrappedID3D11DeviceContext::ProcessChunk(ReadSerialiser &ser, D3D11Chunk ch if(IsLoading(m_State)) { if(!m_PresentChunk) - AddEvent("End of Frame"); + AddEvent(); DrawcallDescription draw; draw.name = "End of Frame"; @@ -849,7 +836,7 @@ void WrappedID3D11DeviceContext::ProcessChunk(ReadSerialiser &ser, D3D11Chunk ch else { if(!m_AddedDrawcall) - AddEvent(""); + AddEvent(); } } @@ -1010,14 +997,15 @@ void WrappedID3D11DeviceContext::AddDrawcall(const DrawcallDescription &d, bool RDCERR("Somehow lost drawcall stack!"); } -void WrappedID3D11DeviceContext::AddEvent(string description) +void WrappedID3D11DeviceContext::AddEvent() { APIEvent apievent; apievent.fileOffset = m_CurChunkOffset; apievent.eventID = m_CurEventID; - apievent.eventDesc = description; + // TODO structured data? + apievent.eventDesc = "TODO"; apievent.callstack = m_ChunkMetadata.callstack; @@ -1328,7 +1316,7 @@ void WrappedID3D11DeviceContext::RecordIndexBindStats(ID3D11Buffer *Buffer) indices.nulls += (Buffer == NULL); } -void WrappedID3D11DeviceContext::RecordVertexBindStats(UINT NumBuffers, ID3D11Buffer *Buffers[]) +void WrappedID3D11DeviceContext::RecordVertexBindStats(UINT NumBuffers, ID3D11Buffer *const Buffers[]) { FrameStatistics &stats = m_pDevice->GetFrameStats(); VertexBindStats &vertices = stats.vertices; @@ -1355,7 +1343,7 @@ void WrappedID3D11DeviceContext::RecordLayoutBindStats(ID3D11InputLayout *Layout } void WrappedID3D11DeviceContext::RecordConstantStats(ShaderStage stage, UINT NumBuffers, - ID3D11Buffer *Buffers[]) + ID3D11Buffer *const Buffers[]) { FrameStatistics &stats = m_pDevice->GetFrameStats(); RDCASSERT(size_t(stage) < ARRAY_COUNT(stats.constants)); @@ -1385,7 +1373,7 @@ void WrappedID3D11DeviceContext::RecordConstantStats(ShaderStage stage, UINT Num } void WrappedID3D11DeviceContext::RecordResourceStats(ShaderStage stage, UINT NumResources, - ID3D11ShaderResourceView *Resources[]) + ID3D11ShaderResourceView *const Resources[]) { FrameStatistics &stats = m_pDevice->GetFrameStats(); RDCASSERT(size_t(stage) < ARRAY_COUNT(stats.resources)); @@ -1426,7 +1414,7 @@ void WrappedID3D11DeviceContext::RecordResourceStats(ShaderStage stage, UINT Num } void WrappedID3D11DeviceContext::RecordSamplerStats(ShaderStage stage, UINT NumSamplers, - ID3D11SamplerState *Samplers[]) + ID3D11SamplerState *const Samplers[]) { FrameStatistics &stats = m_pDevice->GetFrameStats(); RDCASSERT(size_t(stage) < ARRAY_COUNT(stats.samplers)); @@ -1517,8 +1505,8 @@ void WrappedID3D11DeviceContext::RecordShaderStats(ShaderStage stage, ID3D11Devi shaders.redundants += (Current == Shader); } -void WrappedID3D11DeviceContext::RecordBlendStats(ID3D11BlendState *Blend, FLOAT BlendFactor[4], - UINT SampleMask) +void WrappedID3D11DeviceContext::RecordBlendStats(ID3D11BlendState *Blend, + const FLOAT BlendFactor[4], UINT SampleMask) { FrameStatistics &stats = m_pDevice->GetFrameStats(); BlendStats &blends = stats.blends; diff --git a/renderdoc/driver/d3d11/d3d11_context.h b/renderdoc/driver/d3d11/d3d11_context.h index 3228f2e8e..868c33797 100644 --- a/renderdoc/driver/d3d11/d3d11_context.h +++ b/renderdoc/driver/d3d11/d3d11_context.h @@ -213,21 +213,21 @@ private: void AddUsage(const DrawcallDescription &d); - void AddEvent(string description); + void AddEvent(); void AddDrawcall(const DrawcallDescription &d, bool hasEvents); void RecordIndexBindStats(ID3D11Buffer *Buffer); - void RecordVertexBindStats(UINT NumBuffers, ID3D11Buffer *Buffers[]); + void RecordVertexBindStats(UINT NumBuffers, ID3D11Buffer *const Buffers[]); void RecordLayoutBindStats(ID3D11InputLayout *Layout); - void RecordConstantStats(ShaderStage stage, UINT NumBuffers, ID3D11Buffer *Buffers[]); + void RecordConstantStats(ShaderStage stage, UINT NumBuffers, ID3D11Buffer *const Buffers[]); void RecordResourceStats(ShaderStage stage, UINT NumResources, - ID3D11ShaderResourceView *Resources[]); - void RecordSamplerStats(ShaderStage stage, UINT NumSamplers, ID3D11SamplerState *Samplers[]); + ID3D11ShaderResourceView *const Resources[]); + void RecordSamplerStats(ShaderStage stage, UINT NumSamplers, ID3D11SamplerState *const Samplers[]); void RecordUpdateStats(ID3D11Resource *res, uint32_t Size, bool Server); void RecordDrawStats(bool instanced, bool indirect, UINT InstanceCount); void RecordDispatchStats(bool indirect); void RecordShaderStats(ShaderStage stage, ID3D11DeviceChild *Current, ID3D11DeviceChild *Shader); - void RecordBlendStats(ID3D11BlendState *Blend, FLOAT BlendFactor[4], UINT SampleMask); + void RecordBlendStats(ID3D11BlendState *Blend, const FLOAT BlendFactor[4], UINT SampleMask); void RecordDepthStencilStats(ID3D11DepthStencilState *DepthStencil, UINT StencilRef); void RecordRasterizationStats(ID3D11RasterizerState *Rasterizer); void RecordViewportStats(UINT NumViewports, const D3D11_VIEWPORT *viewports); @@ -242,9 +242,9 @@ private: // this is defined as a macro so that we can re-use it to explicitly instantiate these functions as // templates in the wrapper definition file. -#define SERIALISED_ID3D11CONTEXT_MARKER_FUNCTIONS() \ - IMPLEMENT_FUNCTION_SERIALISED(void, SetMarker, uint32_t col, const wchar_t *name); \ - IMPLEMENT_FUNCTION_SERIALISED(int, PushMarker, uint32_t col, const wchar_t *name); \ +#define SERIALISED_ID3D11CONTEXT_MARKER_FUNCTIONS() \ + IMPLEMENT_FUNCTION_SERIALISED(void, SetMarker, uint32_t Color, const wchar_t *MarkerName); \ + IMPLEMENT_FUNCTION_SERIALISED(int, PushMarker, uint32_t Color, const wchar_t *MarkerName); \ IMPLEMENT_FUNCTION_SERIALISED(int, PopMarker); SERIALISED_ID3D11CONTEXT_MARKER_FUNCTIONS(); @@ -522,6 +522,9 @@ 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); \ + \ IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, HSSetShaderResources, \ UINT StartSlot, UINT NumViews, \ ID3D11ShaderResourceView *const *ppShaderResourceViews); \ @@ -713,7 +716,10 @@ public: \ IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, FinishCommandList, \ BOOL RestoreDeferredContextState, \ - ID3D11CommandList **ppCommandList); + ID3D11CommandList **ppCommandList); \ + \ + /* Fake function used to restore state after FinishCommandList */ \ + IMPLEMENT_FUNCTION_SERIALISED(void, PostFinishCommandListSet); SERIALISED_ID3D11CONTEXT_FUNCTIONS(); diff --git a/renderdoc/driver/d3d11/d3d11_context_wrap.cpp b/renderdoc/driver/d3d11/d3d11_context_wrap.cpp index ba24c5ac2..27af7822f 100644 --- a/renderdoc/driver/d3d11/d3d11_context_wrap.cpp +++ b/renderdoc/driver/d3d11/d3d11_context_wrap.cpp @@ -39,126 +39,119 @@ uint32_t NullCBCounts[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; #pragma region D3DPERF -bool WrappedID3D11DeviceContext::Serialise_SetMarker(uint32_t col, const wchar_t *name_) +template +bool WrappedID3D11DeviceContext::Serialise_SetMarker(SerialiserType &ser, uint32_t Color, + const wchar_t *MarkerNameW) { - SERIALISE_ELEMENT(uint32_t, colour, col); + SERIALISE_ELEMENT(Color); + SERIALISE_ELEMENT_LOCAL(MarkerName, StringFormat::Wide2UTF8(MarkerNameW ? MarkerNameW : L"")); - string name; - - if(m_State >= WRITING) + if(IsReplayingAndReading()) { - wstring wname = name_ ? name_ : L""; - name = StringFormat::Wide2UTF8(wname); - } + D3D11MarkerRegion::Set(MarkerName); - m_pSerialiser->Serialise("Name", name); + if(IsLoading(m_State)) + { + DrawcallDescription draw; + draw.name = MarkerName; + draw.flags |= DrawFlags::SetMarker; - if(m_State <= EXECUTING) - D3D11MarkerRegion::Set(name); + byte alpha = (Color >> 24) & 0xff; + byte red = (Color >> 16) & 0xff; + byte green = (Color >> 8) & 0xff; + byte blue = (Color >> 0) & 0xff; - if(m_State == READING) - { - DrawcallDescription draw; - draw.name = name; - draw.flags |= DrawFlags::SetMarker; + draw.markerColor[0] = float(red) / 255.0f; + draw.markerColor[1] = float(green) / 255.0f; + draw.markerColor[2] = float(blue) / 255.0f; + draw.markerColor[3] = float(alpha) / 255.0f; - byte alpha = (colour >> 24) & 0xff; - byte red = (colour >> 16) & 0xff; - byte green = (colour >> 8) & 0xff; - byte blue = (colour >> 0) & 0xff; - - draw.markerColor[0] = float(red) / 255.0f; - draw.markerColor[1] = float(green) / 255.0f; - draw.markerColor[2] = float(blue) / 255.0f; - draw.markerColor[3] = float(alpha) / 255.0f; - - AddDrawcall(draw, false); + AddDrawcall(draw, false); + } } return true; } -bool WrappedID3D11DeviceContext::Serialise_PushEvent(uint32_t col, const wchar_t *name_) +template +bool WrappedID3D11DeviceContext::Serialise_PushMarker(SerialiserType &ser, uint32_t Color, + const wchar_t *MarkerNameW) { - SERIALISE_ELEMENT(uint32_t, colour, col); + SERIALISE_ELEMENT(Color); + SERIALISE_ELEMENT_LOCAL(MarkerName, StringFormat::Wide2UTF8(MarkerNameW ? MarkerNameW : L"")); - string name; - - if(m_State >= WRITING) + if(IsReplayingAndReading()) { - wstring wname = name_ ? name_ : L""; - name = StringFormat::Wide2UTF8(wname); - } - - m_pSerialiser->Serialise("Name", name); - - if(m_State <= EXECUTING) - { - D3D11MarkerRegion::Begin(name); + D3D11MarkerRegion::Begin(MarkerName); m_pDevice->ReplayPushEvent(); - } - if(m_State == READING) - { - DrawcallDescription draw; - draw.name = name; - draw.flags |= DrawFlags::PushMarker; + if(IsLoading(m_State)) + { + DrawcallDescription draw; + draw.name = MarkerName; + draw.flags |= DrawFlags::PushMarker; - byte alpha = (colour >> 24) & 0xff; - byte red = (colour >> 16) & 0xff; - byte green = (colour >> 8) & 0xff; - byte blue = (colour >> 0) & 0xff; + byte alpha = (Color >> 24) & 0xff; + byte red = (Color >> 16) & 0xff; + byte green = (Color >> 8) & 0xff; + byte blue = (Color >> 0) & 0xff; - draw.markerColor[0] = float(red) / 255.0f; - draw.markerColor[1] = float(green) / 255.0f; - draw.markerColor[2] = float(blue) / 255.0f; - draw.markerColor[3] = float(alpha) / 255.0f; + draw.markerColor[0] = float(red) / 255.0f; + draw.markerColor[1] = float(green) / 255.0f; + draw.markerColor[2] = float(blue) / 255.0f; + draw.markerColor[3] = float(alpha) / 255.0f; - AddDrawcall(draw, false); + AddDrawcall(draw, false); + } } return true; } -bool WrappedID3D11DeviceContext::Serialise_PopEvent() +template +bool WrappedID3D11DeviceContext::Serialise_PopMarker(SerialiserType &ser) { - if(m_State <= EXECUTING) + if(IsReplayingAndReading()) { D3D11MarkerRegion::End(); m_pDevice->ReplayPopEvent(); - } - if(m_State == READING && !m_CurEvents.empty()) - { - DrawcallDescription draw; - draw.name = "API Calls"; - draw.flags |= DrawFlags::SetMarker | DrawFlags::APICalls; + if(IsLoading(m_State) && !m_CurEvents.empty()) + { + DrawcallDescription draw; + draw.name = "API Calls"; + draw.flags |= DrawFlags::SetMarker | DrawFlags::APICalls; - AddDrawcall(draw, true); + AddDrawcall(draw, true); + } } return true; } -void WrappedID3D11DeviceContext::SetMarker(uint32_t col, const wchar_t *name) +void WrappedID3D11DeviceContext::SetMarker(uint32_t Color, const wchar_t *MarkerName) { - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(SET_MARKER); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_SetMarker(col, name); + USE_SCRATCH_SERIALISER(); + GET_SERIALISER.SetDrawChunk(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::SetMarker); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_SetMarker(GET_SERIALISER, Color, MarkerName); m_ContextRecord->AddChunk(scope.Get()); } } -int WrappedID3D11DeviceContext::PushMarker(uint32_t col, const wchar_t *name) +int WrappedID3D11DeviceContext::PushMarker(uint32_t Color, const wchar_t *MarkerName) { - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(PUSH_EVENT); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_PushMarker(col, name); + USE_SCRATCH_SERIALISER(); + GET_SERIALISER.SetDrawChunk(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::PushMarker); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_PushMarker(GET_SERIALISER, Color, MarkerName); m_ContextRecord->AddChunk(scope.Get()); } @@ -168,11 +161,13 @@ int WrappedID3D11DeviceContext::PushMarker(uint32_t col, const wchar_t *name) int WrappedID3D11DeviceContext::PopMarker() { - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(POP_EVENT); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_PopMarker(); + USE_SCRATCH_SERIALISER(); + GET_SERIALISER.SetDrawChunk(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::PopMarker); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_PopMarker(GET_SERIALISER); m_ContextRecord->AddChunk(scope.Get()); } @@ -227,7 +222,7 @@ int WrappedID3D11DeviceContext::ThreadSafe_EndEvent() void WrappedID3D11DeviceContext::DrainAnnotationQueue() { - if(m_State != WRITING_CAPFRAME) + if(!IsActiveCapturing(m_State)) return; m_AnnotLock.Lock(); @@ -239,7 +234,7 @@ void WrappedID3D11DeviceContext::DrainAnnotationQueue() return; } - vector annotations; + std::vector annotations; annotations.swap(m_AnnotationQueue); m_AnnotLock.Unlock(); @@ -328,11 +323,13 @@ void WrappedID3D11DeviceContext::IAGetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY RDCASSERT(*pTopology == m_CurrentPipelineState->IA.Topo); } -bool WrappedID3D11DeviceContext::Serialise_IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY Topology_) +template +bool WrappedID3D11DeviceContext::Serialise_IASetPrimitiveTopology(SerialiserType &ser, + D3D11_PRIMITIVE_TOPOLOGY Topology) { - SERIALISE_ELEMENT(D3D11_PRIMITIVE_TOPOLOGY, Topology, Topology_); + SERIALISE_ELEMENT(Topology); - if(m_State <= EXECUTING) + if(IsReplayingAndReading()) { m_CurrentPipelineState->Change(m_CurrentPipelineState->IA.Topo, Topology); m_pRealContext->IASetPrimitiveTopology(Topology); @@ -348,11 +345,12 @@ void WrappedID3D11DeviceContext::IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(SET_TOPOLOGY); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_IASetPrimitiveTopology(Topology); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::IASetPrimitiveTopology); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_IASetPrimitiveTopology(GET_SERIALISER, Topology); m_ContextRecord->AddChunk(scope.Get()); } @@ -362,18 +360,15 @@ void WrappedID3D11DeviceContext::IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY VerifyState(); } -bool WrappedID3D11DeviceContext::Serialise_IASetInputLayout(ID3D11InputLayout *pInputLayout) +template +bool WrappedID3D11DeviceContext::Serialise_IASetInputLayout(SerialiserType &ser, + ID3D11InputLayout *pInputLayout) { - SERIALISE_ELEMENT(ResourceId, InputLayout, GetIDForResource(pInputLayout)); + SERIALISE_ELEMENT(pInputLayout); - if(m_State <= EXECUTING) + if(IsReplayingAndReading()) { - pInputLayout = NULL; - if(m_pDevice->GetResourceManager()->HasLiveResource(InputLayout)) - pInputLayout = - (ID3D11InputLayout *)m_pDevice->GetResourceManager()->GetLiveResource(InputLayout); - - if(m_State == READING) + if(IsLoading(m_State)) RecordLayoutBindStats(pInputLayout); m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->IA.Layout, pInputLayout); @@ -390,11 +385,12 @@ void WrappedID3D11DeviceContext::IASetInputLayout(ID3D11InputLayout *pInputLayou m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(SET_INPUT_LAYOUT); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_IASetInputLayout(pInputLayout); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::IASetInputLayout); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_IASetInputLayout(GET_SERIALISER, pInputLayout); MarkResourceReferenced(GetIDForResource(pInputLayout), eFrameRef_Read); @@ -406,55 +402,40 @@ void WrappedID3D11DeviceContext::IASetInputLayout(ID3D11InputLayout *pInputLayou VerifyState(); } -bool WrappedID3D11DeviceContext::Serialise_IASetVertexBuffers(UINT StartSlot_, UINT NumBuffers_, +template +bool WrappedID3D11DeviceContext::Serialise_IASetVertexBuffers(SerialiserType &ser, UINT StartSlot, + UINT NumBuffers, ID3D11Buffer *const *ppVertexBuffers, const UINT *pStrides, const UINT *pOffsets) { - SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); - SERIALISE_ELEMENT(uint32_t, NumBuffers, NumBuffers_); + SERIALISE_ELEMENT(StartSlot); + SERIALISE_ELEMENT_ARRAY(ppVertexBuffers, NumBuffers); + SERIALISE_ELEMENT_ARRAY(pStrides, NumBuffers); + SERIALISE_ELEMENT_ARRAY(pOffsets, NumBuffers); + // serialise NumBuffers here, because if any of the above were NULL it would be set to 0 + SERIALISE_ELEMENT(NumBuffers); - SERIALISE_ELEMENT_ARR(uint32_t, Strides, pStrides, NumBuffers); - SERIALISE_ELEMENT_ARR(uint32_t, Offsets, pOffsets, NumBuffers); - - ID3D11Buffer *Buffers[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT]; - - for(UINT i = 0; i < NumBuffers; i++) + if(IsReplayingAndReading()) { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppVertexBuffers[i])); + if(IsLoading(m_State)) + RecordVertexBindStats(NumBuffers, ppVertexBuffers); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Buffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Buffers[i] = NULL; - } - - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->IA.VBs, Buffers, StartSlot, - NumBuffers); - } - - for(UINT i = 0; i < NumBuffers; i++) - if(m_State <= EXECUTING) - Buffers[i] = UNWRAP(WrappedID3D11Buffer, Buffers[i]); - - if(m_State <= EXECUTING) - { - if(m_State == READING) - RecordVertexBindStats(NumBuffers, Buffers); - - m_CurrentPipelineState->Change(m_CurrentPipelineState->IA.Strides, Strides, StartSlot, + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->IA.VBs, ppVertexBuffers, + StartSlot, NumBuffers); + m_CurrentPipelineState->Change(m_CurrentPipelineState->IA.Strides, pStrides, StartSlot, NumBuffers); - m_CurrentPipelineState->Change(m_CurrentPipelineState->IA.Offsets, Offsets, StartSlot, + m_CurrentPipelineState->Change(m_CurrentPipelineState->IA.Offsets, pOffsets, StartSlot, NumBuffers); - m_pRealContext->IASetVertexBuffers(StartSlot, NumBuffers, Buffers, Strides, Offsets); + + ID3D11Buffer *bufs[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT]; + for(UINT i = 0; i < NumBuffers; i++) + bufs[i] = UNWRAP(WrappedID3D11Buffer, ppVertexBuffers[i]); + + m_pRealContext->IASetVertexBuffers(StartSlot, NumBuffers, bufs, pStrides, pOffsets); VerifyState(); } - SAFE_DELETE_ARRAY(Strides); - SAFE_DELETE_ARRAY(Offsets); - return true; } @@ -466,11 +447,13 @@ void WrappedID3D11DeviceContext::IASetVertexBuffers(UINT StartSlot, UINT NumBuff m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(SET_VBUFFER); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_IASetVertexBuffers(StartSlot, NumBuffers, ppVertexBuffers, pStrides, pOffsets); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::IASetVertexBuffers); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_IASetVertexBuffers(GET_SERIALISER, StartSlot, NumBuffers, ppVertexBuffers, pStrides, + pOffsets); m_ContextRecord->AddChunk(scope.Get()); } @@ -483,7 +466,7 @@ void WrappedID3D11DeviceContext::IASetVertexBuffers(UINT StartSlot, UINT NumBuff ID3D11Buffer *bufs[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT]; for(UINT i = 0; i < NumBuffers; i++) { - if(ppVertexBuffers[i] && m_State >= WRITING_CAPFRAME) + if(ppVertexBuffers[i] && IsActiveCapturing(m_State)) MarkResourceReferenced(GetIDForResource(ppVertexBuffers[i]), eFrameRef_Read); bufs[i] = UNWRAP(WrappedID3D11Buffer, ppVertexBuffers[i]); } @@ -492,20 +475,18 @@ void WrappedID3D11DeviceContext::IASetVertexBuffers(UINT StartSlot, UINT NumBuff VerifyState(); } -bool WrappedID3D11DeviceContext::Serialise_IASetIndexBuffer(ID3D11Buffer *pIndexBuffer, - DXGI_FORMAT Format_, UINT Offset_) +template +bool WrappedID3D11DeviceContext::Serialise_IASetIndexBuffer(SerialiserType &ser, + ID3D11Buffer *pIndexBuffer, + DXGI_FORMAT Format, UINT Offset) { - SERIALISE_ELEMENT(ResourceId, Buffer, GetIDForResource(pIndexBuffer)); - SERIALISE_ELEMENT(DXGI_FORMAT, Format, Format_); - SERIALISE_ELEMENT(uint32_t, Offset, Offset_); + SERIALISE_ELEMENT(pIndexBuffer); + SERIALISE_ELEMENT(Format); + SERIALISE_ELEMENT(Offset); - if(m_State <= EXECUTING) + if(IsReplayingAndReading()) { - pIndexBuffer = NULL; - if(m_pDevice->GetResourceManager()->HasLiveResource(Buffer)) - pIndexBuffer = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetLiveResource(Buffer); - - if(m_State == READING) + if(IsLoading(m_State)) RecordIndexBindStats(pIndexBuffer); m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->IA.IndexBuffer, pIndexBuffer); @@ -525,16 +506,17 @@ void WrappedID3D11DeviceContext::IASetIndexBuffer(ID3D11Buffer *pIndexBuffer, DX m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(SET_IBUFFER); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_IASetIndexBuffer(pIndexBuffer, Format, Offset); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::IASetIndexBuffer); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_IASetIndexBuffer(GET_SERIALISER, pIndexBuffer, Format, Offset); m_ContextRecord->AddChunk(scope.Get()); } - if(pIndexBuffer && m_State >= WRITING_CAPFRAME) + if(pIndexBuffer && IsActiveCapturing(m_State)) MarkResourceReferenced(GetIDForResource(pIndexBuffer), eFrameRef_Read); m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->IA.IndexBuffer, pIndexBuffer); @@ -627,7 +609,7 @@ void WrappedID3D11DeviceContext::VSGetShader(ID3D11VertexShader **ppVertexShader *ppVertexShader = (ID3D11VertexShader *)m_pDevice->GetResourceManager()->GetWrapper(realShader); SAFE_ADDREF(*ppVertexShader); - RDCASSERT(*ppVertexShader == m_CurrentPipelineState->VS.Shader); + RDCASSERT(*ppVertexShader == m_CurrentPipelineState->VS.Object); } if(ppClassInstances) @@ -648,40 +630,31 @@ void WrappedID3D11DeviceContext::VSGetShader(ID3D11VertexShader **ppVertexShader } } -bool WrappedID3D11DeviceContext::Serialise_VSSetConstantBuffers(UINT StartSlot_, UINT NumBuffers_, +template +bool WrappedID3D11DeviceContext::Serialise_VSSetConstantBuffers(SerialiserType &ser, UINT StartSlot, + UINT NumBuffers, ID3D11Buffer *const *ppConstantBuffers) { - SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); - SERIALISE_ELEMENT(uint32_t, NumBuffers, NumBuffers_); + SERIALISE_ELEMENT(StartSlot); + SERIALISE_ELEMENT_ARRAY(ppConstantBuffers, NumBuffers); - ID3D11Buffer *Buffers[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; - - for(UINT i = 0; i < NumBuffers; i++) + if(IsReplayingAndReading()) { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppConstantBuffers[i])); + if(IsLoading(m_State)) + RecordConstantStats(ShaderStage::Vertex, NumBuffers, ppConstantBuffers); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Buffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Buffers[i] = NULL; - } - - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->VS.ConstantBuffers, Buffers, - StartSlot, NumBuffers); + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->VS.ConstantBuffers, + ppConstantBuffers, StartSlot, NumBuffers); m_CurrentPipelineState->Change(m_CurrentPipelineState->VS.CBOffsets, NullCBOffsets, StartSlot, NumBuffers); m_CurrentPipelineState->Change(m_CurrentPipelineState->VS.CBCounts, NullCBCounts, StartSlot, NumBuffers); + ID3D11Buffer *bufs[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {0}; for(UINT i = 0; i < NumBuffers; i++) - Buffers[i] = UNWRAP(WrappedID3D11Buffer, Buffers[i]); + bufs[i] = UNWRAP(WrappedID3D11Buffer, ppConstantBuffers[i]); - if(m_State == READING) - RecordConstantStats(ShaderStage::Vertex, NumBuffers, Buffers); - - m_pRealContext->VSSetConstantBuffers(StartSlot, NumBuffers, Buffers); + m_pRealContext->VSSetConstantBuffers(StartSlot, NumBuffers, bufs); VerifyState(); } @@ -695,11 +668,12 @@ void WrappedID3D11DeviceContext::VSSetConstantBuffers(UINT StartSlot, UINT NumBu m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(SET_VS_CBUFFERS); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_VSSetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::VSSetConstantBuffers); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_VSSetConstantBuffers(GET_SERIALISER, StartSlot, NumBuffers, ppConstantBuffers); m_ContextRecord->AddChunk(scope.Get()); } @@ -714,7 +688,7 @@ void WrappedID3D11DeviceContext::VSSetConstantBuffers(UINT StartSlot, UINT NumBu ID3D11Buffer *bufs[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {0}; for(UINT i = 0; i < NumBuffers; i++) { - if(ppConstantBuffers[i] && m_State >= WRITING_CAPFRAME) + if(ppConstantBuffers[i] && IsActiveCapturing(m_State)) MarkResourceReferenced(GetIDForResource(ppConstantBuffers[i]), eFrameRef_Read); bufs[i] = UNWRAP(WrappedID3D11Buffer, ppConstantBuffers[i]); @@ -724,41 +698,30 @@ void WrappedID3D11DeviceContext::VSSetConstantBuffers(UINT StartSlot, UINT NumBu VerifyState(); } +template bool WrappedID3D11DeviceContext::Serialise_VSSetShaderResources( - UINT StartSlot_, UINT NumViews_, ID3D11ShaderResourceView *const *ppShaderResourceViews) + SerialiserType &ser, UINT StartSlot, UINT NumViews, + ID3D11ShaderResourceView *const *ppShaderResourceViews) { - SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); - SERIALISE_ELEMENT(uint32_t, NumViews, NumViews_); + SERIALISE_ELEMENT(StartSlot); + SERIALISE_ELEMENT_ARRAY(ppShaderResourceViews, NumViews); - ID3D11ShaderResourceView **Views = new ID3D11ShaderResourceView *[NumViews]; - - for(UINT i = 0; i < NumViews; i++) + if(IsReplayingAndReading()) { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppShaderResourceViews[i])); + if(IsLoading(m_State)) + RecordResourceStats(ShaderStage::Vertex, NumViews, ppShaderResourceViews); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Views[i] = (ID3D11ShaderResourceView *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Views[i] = NULL; - } - - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->VS.SRVs, Views, StartSlot, - NumViews); + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->VS.SRVs, ppShaderResourceViews, + StartSlot, NumViews); + ID3D11ShaderResourceView *SRVs[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; for(UINT i = 0; i < NumViews; i++) - Views[i] = UNWRAP(WrappedID3D11ShaderResourceView1, Views[i]); + SRVs[i] = UNWRAP(WrappedID3D11ShaderResourceView1, ppShaderResourceViews[i]); - if(m_State == READING) - RecordResourceStats(ShaderStage::Vertex, NumViews, Views); - - m_pRealContext->VSSetShaderResources(StartSlot, NumViews, Views); + m_pRealContext->VSSetShaderResources(StartSlot, NumViews, SRVs); VerifyState(); } - SAFE_DELETE_ARRAY(Views); - return true; } @@ -769,11 +732,12 @@ void WrappedID3D11DeviceContext::VSSetShaderResources( m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(SET_VS_RESOURCES); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_VSSetShaderResources(StartSlot, NumViews, ppShaderResourceViews); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::VSSetShaderResources); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_VSSetShaderResources(GET_SERIALISER, StartSlot, NumViews, ppShaderResourceViews); m_ContextRecord->AddChunk(scope.Get()); } @@ -784,7 +748,7 @@ void WrappedID3D11DeviceContext::VSSetShaderResources( ID3D11ShaderResourceView *SRVs[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; for(UINT i = 0; i < NumViews; i++) { - if(ppShaderResourceViews[i] && m_State >= WRITING_CAPFRAME) + if(ppShaderResourceViews[i] && IsActiveCapturing(m_State)) { MarkResourceReferenced(GetIDForResource(ppShaderResourceViews[i]), eFrameRef_Read); MarkResourceReferenced(GetViewResourceResID(ppShaderResourceViews[i]), eFrameRef_Read); @@ -797,41 +761,30 @@ void WrappedID3D11DeviceContext::VSSetShaderResources( VerifyState(); } -bool WrappedID3D11DeviceContext::Serialise_VSSetSamplers(UINT StartSlot_, UINT NumSamplers_, +template +bool WrappedID3D11DeviceContext::Serialise_VSSetSamplers(SerialiserType &ser, UINT StartSlot, + UINT NumSamplers, ID3D11SamplerState *const *ppSamplers) { - SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); - SERIALISE_ELEMENT(uint32_t, NumSamplers, NumSamplers_); + SERIALISE_ELEMENT(StartSlot); + SERIALISE_ELEMENT_ARRAY(ppSamplers, NumSamplers); - ID3D11SamplerState **Samplers = new ID3D11SamplerState *[NumSamplers]; - - for(UINT i = 0; i < NumSamplers; i++) + if(IsReplayingAndReading()) { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppSamplers[i])); + if(IsLoading(m_State)) + RecordSamplerStats(ShaderStage::Vertex, NumSamplers, ppSamplers); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Samplers[i] = (ID3D11SamplerState *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Samplers[i] = NULL; - } - - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->VS.Samplers, Samplers, StartSlot, - NumSamplers); + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->VS.Samplers, ppSamplers, + StartSlot, NumSamplers); + ID3D11SamplerState *samps[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT]; for(UINT i = 0; i < NumSamplers; i++) - Samplers[i] = UNWRAP(WrappedID3D11SamplerState, Samplers[i]); + samps[i] = UNWRAP(WrappedID3D11SamplerState, ppSamplers[i]); - if(m_State == READING) - RecordSamplerStats(ShaderStage::Vertex, NumSamplers, Samplers); - - m_pRealContext->VSSetSamplers(StartSlot, NumSamplers, Samplers); + m_pRealContext->VSSetSamplers(StartSlot, NumSamplers, samps); VerifyState(); } - SAFE_DELETE_ARRAY(Samplers); - return true; } @@ -842,11 +795,12 @@ void WrappedID3D11DeviceContext::VSSetSamplers(UINT StartSlot, UINT NumSamplers, m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(SET_VS_SAMPLERS); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_VSSetSamplers(StartSlot, NumSamplers, ppSamplers); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::VSSetSamplers); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_VSSetSamplers(GET_SERIALISER, StartSlot, NumSamplers, ppSamplers); m_ContextRecord->AddChunk(scope.Get()); } @@ -862,49 +816,35 @@ void WrappedID3D11DeviceContext::VSSetSamplers(UINT StartSlot, UINT NumSamplers, VerifyState(); } -bool WrappedID3D11DeviceContext::Serialise_VSSetShader(ID3D11VertexShader *pShader, +template +bool WrappedID3D11DeviceContext::Serialise_VSSetShader(SerialiserType &ser, + ID3D11VertexShader *pShader, ID3D11ClassInstance *const *ppClassInstances, - UINT NumClassInstances_) + UINT NumClassInstances) { - SERIALISE_ELEMENT(ResourceId, Shader, GetIDForResource(pShader)); - SERIALISE_ELEMENT(uint32_t, NumClassInstances, NumClassInstances_); + SERIALISE_ELEMENT(pShader); + SERIALISE_ELEMENT_ARRAY(ppClassInstances, NumClassInstances); - ID3D11ClassInstance **Instances = new ID3D11ClassInstance *[NumClassInstances]; - - for(UINT i = 0; i < NumClassInstances; i++) + if(IsReplayingAndReading()) { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppClassInstances[i])); + if(IsLoading(m_State)) + RecordShaderStats(ShaderStage::Vertex, m_CurrentPipelineState->VS.Object, pShader); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Instances[i] = (ID3D11ClassInstance *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Instances[i] = NULL; - } - - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->VS.Instances, Instances, 0, + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->VS.Instances, ppClassInstances, 0, NumClassInstances); m_CurrentPipelineState->Change(m_CurrentPipelineState->VS.NumInstances, NumClassInstances); + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->VS.Object, + (ID3D11DeviceChild *)pShader); + ID3D11ClassInstance *insts[D3D11_SHADER_MAX_INTERFACES] = {0}; for(UINT i = 0; i < NumClassInstances; i++) - Instances[i] = UNWRAP(WrappedID3D11ClassInstance, Instances[i]); + insts[i] = UNWRAP(WrappedID3D11ClassInstance, ppClassInstances[i]); - ID3D11DeviceChild *pSH = NULL; - if(m_pDevice->GetResourceManager()->HasLiveResource(Shader)) - pSH = (ID3D11DeviceChild *)m_pDevice->GetResourceManager()->GetLiveResource(Shader); - - if(m_State == READING) - RecordShaderStats(ShaderStage::Vertex, m_CurrentPipelineState->VS.Shader, pSH); - - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->VS.Shader, pSH); - m_pRealContext->VSSetShader(UNWRAP(WrappedID3D11Shader, pSH), Instances, + m_pRealContext->VSSetShader(UNWRAP(WrappedID3D11Shader, pShader), insts, NumClassInstances); VerifyState(); } - SAFE_DELETE_ARRAY(Instances); - return true; } @@ -916,18 +856,19 @@ void WrappedID3D11DeviceContext::VSSetShader(ID3D11VertexShader *pVertexShader, m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(SET_VS); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_VSSetShader(pVertexShader, ppClassInstances, NumClassInstances); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::VSSetShader); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_VSSetShader(GET_SERIALISER, pVertexShader, ppClassInstances, NumClassInstances); MarkResourceReferenced(GetIDForResource(pVertexShader), eFrameRef_Read); m_ContextRecord->AddChunk(scope.Get()); } - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->VS.Shader, + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->VS.Object, (ID3D11DeviceChild *)pVertexShader); m_CurrentPipelineState->Change(m_CurrentPipelineState->VS.NumInstances, NumClassInstances); m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->VS.Instances, ppClassInstances, 0, @@ -1026,7 +967,7 @@ void WrappedID3D11DeviceContext::HSGetShader(ID3D11HullShader **ppHullShader, *ppHullShader = (ID3D11HullShader *)m_pDevice->GetResourceManager()->GetWrapper(realShader); SAFE_ADDREF(*ppHullShader); - RDCASSERT(*ppHullShader == m_CurrentPipelineState->HS.Shader); + RDCASSERT(*ppHullShader == m_CurrentPipelineState->HS.Object); } if(ppClassInstances) @@ -1047,46 +988,34 @@ void WrappedID3D11DeviceContext::HSGetShader(ID3D11HullShader **ppHullShader, } } -bool WrappedID3D11DeviceContext::Serialise_HSSetConstantBuffers(UINT StartSlot_, UINT NumBuffers_, +template +bool WrappedID3D11DeviceContext::Serialise_HSSetConstantBuffers(SerialiserType &ser, UINT StartSlot, + UINT NumBuffers, ID3D11Buffer *const *ppConstantBuffers) { - SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); - SERIALISE_ELEMENT(uint32_t, NumBuffers, NumBuffers_); + SERIALISE_ELEMENT(StartSlot); + SERIALISE_ELEMENT_ARRAY(ppConstantBuffers, NumBuffers); - ID3D11Buffer **Buffers = new ID3D11Buffer *[NumBuffers]; - - for(UINT i = 0; i < NumBuffers; i++) + if(IsReplayingAndReading()) { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppConstantBuffers[i])); + if(IsLoading(m_State)) + RecordConstantStats(ShaderStage::Hull, NumBuffers, ppConstantBuffers); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Buffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Buffers[i] = NULL; - } - - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->HS.ConstantBuffers, Buffers, - StartSlot, NumBuffers); + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->HS.ConstantBuffers, + ppConstantBuffers, StartSlot, NumBuffers); m_CurrentPipelineState->Change(m_CurrentPipelineState->HS.CBOffsets, NullCBOffsets, StartSlot, NumBuffers); m_CurrentPipelineState->Change(m_CurrentPipelineState->HS.CBCounts, NullCBCounts, StartSlot, NumBuffers); + ID3D11Buffer *bufs[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {0}; for(UINT i = 0; i < NumBuffers; i++) - Buffers[i] = UNWRAP(WrappedID3D11Buffer, Buffers[i]); + bufs[i] = UNWRAP(WrappedID3D11Buffer, ppConstantBuffers[i]); - if(m_State == READING) - RecordConstantStats(ShaderStage::Hull, NumBuffers, Buffers); - - if(m_State <= EXECUTING) - m_pRealContext->HSSetConstantBuffers(StartSlot, NumBuffers, Buffers); + m_pRealContext->HSSetConstantBuffers(StartSlot, NumBuffers, bufs); VerifyState(); } - SAFE_DELETE_ARRAY(Buffers); - return true; } @@ -1097,11 +1026,12 @@ void WrappedID3D11DeviceContext::HSSetConstantBuffers(UINT StartSlot, UINT NumBu m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(SET_HS_CBUFFERS); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_HSSetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::HSSetConstantBuffers); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_HSSetConstantBuffers(GET_SERIALISER, StartSlot, NumBuffers, ppConstantBuffers); m_ContextRecord->AddChunk(scope.Get()); } @@ -1116,7 +1046,7 @@ void WrappedID3D11DeviceContext::HSSetConstantBuffers(UINT StartSlot, UINT NumBu ID3D11Buffer *bufs[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; for(UINT i = 0; i < NumBuffers; i++) { - if(ppConstantBuffers[i] && m_State >= WRITING_CAPFRAME) + if(ppConstantBuffers[i] && IsActiveCapturing(m_State)) MarkResourceReferenced(GetIDForResource(ppConstantBuffers[i]), eFrameRef_Read); bufs[i] = UNWRAP(WrappedID3D11Buffer, ppConstantBuffers[i]); @@ -1126,41 +1056,30 @@ void WrappedID3D11DeviceContext::HSSetConstantBuffers(UINT StartSlot, UINT NumBu VerifyState(); } +template bool WrappedID3D11DeviceContext::Serialise_HSSetShaderResources( - UINT StartSlot_, UINT NumViews_, ID3D11ShaderResourceView *const *ppShaderResourceViews) + SerialiserType &ser, UINT StartSlot, UINT NumViews, + ID3D11ShaderResourceView *const *ppShaderResourceViews) { - SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); - SERIALISE_ELEMENT(uint32_t, NumViews, NumViews_); + SERIALISE_ELEMENT(StartSlot); + SERIALISE_ELEMENT_ARRAY(ppShaderResourceViews, NumViews); - ID3D11ShaderResourceView **Views = new ID3D11ShaderResourceView *[NumViews]; - - for(UINT i = 0; i < NumViews; i++) + if(IsReplayingAndReading()) { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppShaderResourceViews[i])); + if(IsLoading(m_State)) + RecordResourceStats(ShaderStage::Hull, NumViews, ppShaderResourceViews); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Views[i] = (ID3D11ShaderResourceView *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Views[i] = NULL; - } - - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->HS.SRVs, Views, StartSlot, - NumViews); + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->HS.SRVs, ppShaderResourceViews, + StartSlot, NumViews); + ID3D11ShaderResourceView *SRVs[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; for(UINT i = 0; i < NumViews; i++) - Views[i] = UNWRAP(WrappedID3D11ShaderResourceView1, Views[i]); + SRVs[i] = UNWRAP(WrappedID3D11ShaderResourceView1, ppShaderResourceViews[i]); - if(m_State == READING) - RecordResourceStats(ShaderStage::Hull, NumViews, Views); - - m_pRealContext->HSSetShaderResources(StartSlot, NumViews, Views); + m_pRealContext->HSSetShaderResources(StartSlot, NumViews, SRVs); VerifyState(); } - SAFE_DELETE_ARRAY(Views); - return true; } @@ -1171,11 +1090,12 @@ void WrappedID3D11DeviceContext::HSSetShaderResources( m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(SET_HS_RESOURCES); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_HSSetShaderResources(StartSlot, NumViews, ppShaderResourceViews); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::HSSetShaderResources); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_HSSetShaderResources(GET_SERIALISER, StartSlot, NumViews, ppShaderResourceViews); m_ContextRecord->AddChunk(scope.Get()); } @@ -1186,7 +1106,7 @@ void WrappedID3D11DeviceContext::HSSetShaderResources( ID3D11ShaderResourceView *SRVs[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; for(UINT i = 0; i < NumViews; i++) { - if(ppShaderResourceViews[i] && m_State >= WRITING_CAPFRAME) + if(ppShaderResourceViews[i] && IsActiveCapturing(m_State)) { MarkResourceReferenced(GetIDForResource(ppShaderResourceViews[i]), eFrameRef_Read); MarkResourceReferenced(GetViewResourceResID(ppShaderResourceViews[i]), eFrameRef_Read); @@ -1199,41 +1119,30 @@ void WrappedID3D11DeviceContext::HSSetShaderResources( VerifyState(); } -bool WrappedID3D11DeviceContext::Serialise_HSSetSamplers(UINT StartSlot_, UINT NumSamplers_, +template +bool WrappedID3D11DeviceContext::Serialise_HSSetSamplers(SerialiserType &ser, UINT StartSlot, + UINT NumSamplers, ID3D11SamplerState *const *ppSamplers) { - SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); - SERIALISE_ELEMENT(uint32_t, NumSamplers, NumSamplers_); + SERIALISE_ELEMENT(StartSlot); + SERIALISE_ELEMENT_ARRAY(ppSamplers, NumSamplers); - ID3D11SamplerState **Samplers = new ID3D11SamplerState *[NumSamplers]; - - for(UINT i = 0; i < NumSamplers; i++) + if(IsReplayingAndReading()) { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppSamplers[i])); + if(IsLoading(m_State)) + RecordSamplerStats(ShaderStage::Hull, NumSamplers, ppSamplers); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Samplers[i] = (ID3D11SamplerState *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Samplers[i] = NULL; - } - - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->HS.Samplers, Samplers, StartSlot, - NumSamplers); + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->HS.Samplers, ppSamplers, + StartSlot, NumSamplers); + ID3D11SamplerState *samps[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT]; for(UINT i = 0; i < NumSamplers; i++) - Samplers[i] = UNWRAP(WrappedID3D11SamplerState, Samplers[i]); + samps[i] = UNWRAP(WrappedID3D11SamplerState, ppSamplers[i]); - if(m_State == READING) - RecordSamplerStats(ShaderStage::Hull, NumSamplers, Samplers); - - m_pRealContext->HSSetSamplers(StartSlot, NumSamplers, Samplers); + m_pRealContext->HSSetSamplers(StartSlot, NumSamplers, samps); VerifyState(); } - SAFE_DELETE_ARRAY(Samplers); - return true; } @@ -1244,11 +1153,12 @@ void WrappedID3D11DeviceContext::HSSetSamplers(UINT StartSlot, UINT NumSamplers, m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(SET_HS_SAMPLERS); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_HSSetSamplers(StartSlot, NumSamplers, ppSamplers); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::HSSetSamplers); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_HSSetSamplers(GET_SERIALISER, StartSlot, NumSamplers, ppSamplers); m_ContextRecord->AddChunk(scope.Get()); } @@ -1264,49 +1174,34 @@ void WrappedID3D11DeviceContext::HSSetSamplers(UINT StartSlot, UINT NumSamplers, VerifyState(); } -bool WrappedID3D11DeviceContext::Serialise_HSSetShader(ID3D11HullShader *pShader, +template +bool WrappedID3D11DeviceContext::Serialise_HSSetShader(SerialiserType &ser, ID3D11HullShader *pShader, ID3D11ClassInstance *const *ppClassInstances, - UINT NumClassInstances_) + UINT NumClassInstances) { - SERIALISE_ELEMENT(ResourceId, Shader, GetIDForResource(pShader)); - SERIALISE_ELEMENT(uint32_t, NumClassInstances, NumClassInstances_); + SERIALISE_ELEMENT(pShader); + SERIALISE_ELEMENT_ARRAY(ppClassInstances, NumClassInstances); - ID3D11ClassInstance **Instances = new ID3D11ClassInstance *[NumClassInstances]; - - for(UINT i = 0; i < NumClassInstances; i++) + if(IsReplayingAndReading()) { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppClassInstances[i])); + if(IsLoading(m_State)) + RecordShaderStats(ShaderStage::Hull, m_CurrentPipelineState->HS.Object, pShader); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Instances[i] = (ID3D11ClassInstance *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Instances[i] = NULL; - } - - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->HS.Instances, Instances, 0, + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->HS.Instances, ppClassInstances, 0, NumClassInstances); m_CurrentPipelineState->Change(m_CurrentPipelineState->HS.NumInstances, NumClassInstances); + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->HS.Object, + (ID3D11DeviceChild *)pShader); + ID3D11ClassInstance *insts[D3D11_SHADER_MAX_INTERFACES] = {0}; for(UINT i = 0; i < NumClassInstances; i++) - Instances[i] = UNWRAP(WrappedID3D11ClassInstance, Instances[i]); + insts[i] = UNWRAP(WrappedID3D11ClassInstance, ppClassInstances[i]); - ID3D11DeviceChild *pSH = NULL; - if(m_pDevice->GetResourceManager()->HasLiveResource(Shader)) - pSH = (ID3D11DeviceChild *)m_pDevice->GetResourceManager()->GetLiveResource(Shader); - - if(m_State == READING) - RecordShaderStats(ShaderStage::Hull, m_CurrentPipelineState->HS.Shader, pSH); - - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->HS.Shader, pSH); - m_pRealContext->HSSetShader(UNWRAP(WrappedID3D11Shader, pSH), Instances, + m_pRealContext->HSSetShader(UNWRAP(WrappedID3D11Shader, pShader), insts, NumClassInstances); VerifyState(); } - SAFE_DELETE_ARRAY(Instances); - return true; } @@ -1318,18 +1213,19 @@ void WrappedID3D11DeviceContext::HSSetShader(ID3D11HullShader *pHullShader, m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(SET_HS); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_HSSetShader(pHullShader, ppClassInstances, NumClassInstances); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::HSSetShader); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_HSSetShader(GET_SERIALISER, pHullShader, ppClassInstances, NumClassInstances); MarkResourceReferenced(GetIDForResource(pHullShader), eFrameRef_Read); m_ContextRecord->AddChunk(scope.Get()); } - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->HS.Shader, + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->HS.Object, (ID3D11DeviceChild *)pHullShader); m_CurrentPipelineState->Change(m_CurrentPipelineState->HS.NumInstances, NumClassInstances); m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->HS.Instances, ppClassInstances, 0, @@ -1428,7 +1324,7 @@ void WrappedID3D11DeviceContext::DSGetShader(ID3D11DomainShader **ppDomainShader *ppDomainShader = (ID3D11DomainShader *)m_pDevice->GetResourceManager()->GetWrapper(realShader); SAFE_ADDREF(*ppDomainShader); - RDCASSERT(*ppDomainShader == m_CurrentPipelineState->DS.Shader); + RDCASSERT(*ppDomainShader == m_CurrentPipelineState->DS.Object); } if(ppClassInstances) @@ -1449,45 +1345,34 @@ void WrappedID3D11DeviceContext::DSGetShader(ID3D11DomainShader **ppDomainShader } } -bool WrappedID3D11DeviceContext::Serialise_DSSetConstantBuffers(UINT StartSlot_, UINT NumBuffers_, +template +bool WrappedID3D11DeviceContext::Serialise_DSSetConstantBuffers(SerialiserType &ser, UINT StartSlot, + UINT NumBuffers, ID3D11Buffer *const *ppConstantBuffers) { - SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); - SERIALISE_ELEMENT(uint32_t, NumBuffers, NumBuffers_); + SERIALISE_ELEMENT(StartSlot); + SERIALISE_ELEMENT_ARRAY(ppConstantBuffers, NumBuffers); - ID3D11Buffer **Buffers = new ID3D11Buffer *[NumBuffers]; - - for(UINT i = 0; i < NumBuffers; i++) + if(IsReplayingAndReading()) { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppConstantBuffers[i])); + if(IsLoading(m_State)) + RecordConstantStats(ShaderStage::Domain, NumBuffers, ppConstantBuffers); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Buffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Buffers[i] = NULL; - } - - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->DS.ConstantBuffers, Buffers, - StartSlot, NumBuffers); + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->DS.ConstantBuffers, + ppConstantBuffers, StartSlot, NumBuffers); m_CurrentPipelineState->Change(m_CurrentPipelineState->DS.CBOffsets, NullCBOffsets, StartSlot, NumBuffers); m_CurrentPipelineState->Change(m_CurrentPipelineState->DS.CBCounts, NullCBCounts, StartSlot, NumBuffers); + ID3D11Buffer *bufs[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {0}; for(UINT i = 0; i < NumBuffers; i++) - Buffers[i] = UNWRAP(WrappedID3D11Buffer, Buffers[i]); + bufs[i] = UNWRAP(WrappedID3D11Buffer, ppConstantBuffers[i]); - if(m_State == READING) - RecordConstantStats(ShaderStage::Domain, NumBuffers, Buffers); - - m_pRealContext->DSSetConstantBuffers(StartSlot, NumBuffers, Buffers); + m_pRealContext->DSSetConstantBuffers(StartSlot, NumBuffers, bufs); VerifyState(); } - SAFE_DELETE_ARRAY(Buffers); - return true; } @@ -1498,11 +1383,12 @@ void WrappedID3D11DeviceContext::DSSetConstantBuffers(UINT StartSlot, UINT NumBu m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(SET_DS_CBUFFERS); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_DSSetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::DSSetConstantBuffers); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_DSSetConstantBuffers(GET_SERIALISER, StartSlot, NumBuffers, ppConstantBuffers); m_ContextRecord->AddChunk(scope.Get()); } @@ -1517,7 +1403,7 @@ void WrappedID3D11DeviceContext::DSSetConstantBuffers(UINT StartSlot, UINT NumBu ID3D11Buffer *bufs[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; for(UINT i = 0; i < NumBuffers; i++) { - if(ppConstantBuffers[i] && m_State >= WRITING_CAPFRAME) + if(ppConstantBuffers[i] && IsActiveCapturing(m_State)) MarkResourceReferenced(GetIDForResource(ppConstantBuffers[i]), eFrameRef_Read); bufs[i] = UNWRAP(WrappedID3D11Buffer, ppConstantBuffers[i]); @@ -1527,41 +1413,30 @@ void WrappedID3D11DeviceContext::DSSetConstantBuffers(UINT StartSlot, UINT NumBu VerifyState(); } +template bool WrappedID3D11DeviceContext::Serialise_DSSetShaderResources( - UINT StartSlot_, UINT NumViews_, ID3D11ShaderResourceView *const *ppShaderResourceViews) + SerialiserType &ser, UINT StartSlot, UINT NumViews, + ID3D11ShaderResourceView *const *ppShaderResourceViews) { - SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); - SERIALISE_ELEMENT(uint32_t, NumViews, NumViews_); + SERIALISE_ELEMENT(StartSlot); + SERIALISE_ELEMENT_ARRAY(ppShaderResourceViews, NumViews); - ID3D11ShaderResourceView **Views = new ID3D11ShaderResourceView *[NumViews]; - - for(UINT i = 0; i < NumViews; i++) + if(IsReplayingAndReading()) { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppShaderResourceViews[i])); + if(IsLoading(m_State)) + RecordResourceStats(ShaderStage::Domain, NumViews, ppShaderResourceViews); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Views[i] = (ID3D11ShaderResourceView *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Views[i] = NULL; - } - - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->DS.SRVs, Views, StartSlot, - NumViews); + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->DS.SRVs, ppShaderResourceViews, + StartSlot, NumViews); + ID3D11ShaderResourceView *SRVs[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; for(UINT i = 0; i < NumViews; i++) - Views[i] = UNWRAP(WrappedID3D11ShaderResourceView1, Views[i]); + SRVs[i] = UNWRAP(WrappedID3D11ShaderResourceView1, ppShaderResourceViews[i]); - if(m_State == READING) - RecordResourceStats(ShaderStage::Domain, NumViews, Views); - - m_pRealContext->DSSetShaderResources(StartSlot, NumViews, Views); + m_pRealContext->DSSetShaderResources(StartSlot, NumViews, SRVs); VerifyState(); } - SAFE_DELETE_ARRAY(Views); - return true; } @@ -1572,11 +1447,12 @@ void WrappedID3D11DeviceContext::DSSetShaderResources( m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(SET_DS_RESOURCES); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_DSSetShaderResources(StartSlot, NumViews, ppShaderResourceViews); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::DSSetShaderResources); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_DSSetShaderResources(GET_SERIALISER, StartSlot, NumViews, ppShaderResourceViews); m_ContextRecord->AddChunk(scope.Get()); } @@ -1587,7 +1463,7 @@ void WrappedID3D11DeviceContext::DSSetShaderResources( ID3D11ShaderResourceView *SRVs[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; for(UINT i = 0; i < NumViews; i++) { - if(ppShaderResourceViews[i] && m_State >= WRITING_CAPFRAME) + if(ppShaderResourceViews[i] && IsActiveCapturing(m_State)) { MarkResourceReferenced(GetIDForResource(ppShaderResourceViews[i]), eFrameRef_Read); MarkResourceReferenced(GetViewResourceResID(ppShaderResourceViews[i]), eFrameRef_Read); @@ -1600,41 +1476,30 @@ void WrappedID3D11DeviceContext::DSSetShaderResources( VerifyState(); } -bool WrappedID3D11DeviceContext::Serialise_DSSetSamplers(UINT StartSlot_, UINT NumSamplers_, +template +bool WrappedID3D11DeviceContext::Serialise_DSSetSamplers(SerialiserType &ser, UINT StartSlot, + UINT NumSamplers, ID3D11SamplerState *const *ppSamplers) { - SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); - SERIALISE_ELEMENT(uint32_t, NumSamplers, NumSamplers_); + SERIALISE_ELEMENT(StartSlot); + SERIALISE_ELEMENT_ARRAY(ppSamplers, NumSamplers); - ID3D11SamplerState **Samplers = new ID3D11SamplerState *[NumSamplers]; - - for(UINT i = 0; i < NumSamplers; i++) + if(IsReplayingAndReading()) { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppSamplers[i])); + if(IsLoading(m_State)) + RecordSamplerStats(ShaderStage::Domain, NumSamplers, ppSamplers); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Samplers[i] = (ID3D11SamplerState *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Samplers[i] = NULL; - } - - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->DS.Samplers, Samplers, StartSlot, - NumSamplers); + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->DS.Samplers, ppSamplers, + StartSlot, NumSamplers); + ID3D11SamplerState *samps[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT]; for(UINT i = 0; i < NumSamplers; i++) - Samplers[i] = UNWRAP(WrappedID3D11SamplerState, Samplers[i]); + samps[i] = UNWRAP(WrappedID3D11SamplerState, ppSamplers[i]); - if(m_State == READING) - RecordSamplerStats(ShaderStage::Domain, NumSamplers, Samplers); - - m_pRealContext->DSSetSamplers(StartSlot, NumSamplers, Samplers); + m_pRealContext->DSSetSamplers(StartSlot, NumSamplers, samps); VerifyState(); } - SAFE_DELETE_ARRAY(Samplers); - return true; } @@ -1645,11 +1510,12 @@ void WrappedID3D11DeviceContext::DSSetSamplers(UINT StartSlot, UINT NumSamplers, m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(SET_DS_SAMPLERS); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_DSSetSamplers(StartSlot, NumSamplers, ppSamplers); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::DSSetSamplers); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_DSSetSamplers(GET_SERIALISER, StartSlot, NumSamplers, ppSamplers); m_ContextRecord->AddChunk(scope.Get()); } @@ -1665,49 +1531,35 @@ void WrappedID3D11DeviceContext::DSSetSamplers(UINT StartSlot, UINT NumSamplers, VerifyState(); } -bool WrappedID3D11DeviceContext::Serialise_DSSetShader(ID3D11DomainShader *pShader, +template +bool WrappedID3D11DeviceContext::Serialise_DSSetShader(SerialiserType &ser, + ID3D11DomainShader *pShader, ID3D11ClassInstance *const *ppClassInstances, - UINT NumClassInstances_) + UINT NumClassInstances) { - SERIALISE_ELEMENT(ResourceId, Shader, GetIDForResource(pShader)); - SERIALISE_ELEMENT(uint32_t, NumClassInstances, NumClassInstances_); + SERIALISE_ELEMENT(pShader); + SERIALISE_ELEMENT_ARRAY(ppClassInstances, NumClassInstances); - ID3D11ClassInstance **Instances = new ID3D11ClassInstance *[NumClassInstances]; - - for(UINT i = 0; i < NumClassInstances; i++) + if(IsReplayingAndReading()) { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppClassInstances[i])); + if(IsLoading(m_State)) + RecordShaderStats(ShaderStage::Domain, m_CurrentPipelineState->DS.Object, pShader); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Instances[i] = (ID3D11ClassInstance *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Instances[i] = NULL; - } - - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->DS.Instances, Instances, 0, + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->DS.Instances, ppClassInstances, 0, NumClassInstances); m_CurrentPipelineState->Change(m_CurrentPipelineState->DS.NumInstances, NumClassInstances); + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->DS.Object, + (ID3D11DeviceChild *)pShader); + ID3D11ClassInstance *insts[D3D11_SHADER_MAX_INTERFACES] = {0}; for(UINT i = 0; i < NumClassInstances; i++) - Instances[i] = UNWRAP(WrappedID3D11ClassInstance, Instances[i]); + insts[i] = UNWRAP(WrappedID3D11ClassInstance, ppClassInstances[i]); - ID3D11DeviceChild *pSH = NULL; - if(m_pDevice->GetResourceManager()->HasLiveResource(Shader)) - pSH = (ID3D11DeviceChild *)m_pDevice->GetResourceManager()->GetLiveResource(Shader); - - if(m_State == READING) - RecordShaderStats(ShaderStage::Domain, m_CurrentPipelineState->DS.Shader, pSH); - - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->DS.Shader, pSH); - m_pRealContext->DSSetShader(UNWRAP(WrappedID3D11Shader, pSH), Instances, + m_pRealContext->DSSetShader(UNWRAP(WrappedID3D11Shader, pShader), insts, NumClassInstances); VerifyState(); } - SAFE_DELETE_ARRAY(Instances); - return true; } @@ -1719,18 +1571,19 @@ void WrappedID3D11DeviceContext::DSSetShader(ID3D11DomainShader *pDomainShader, m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(SET_DS); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_DSSetShader(pDomainShader, ppClassInstances, NumClassInstances); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::DSSetShader); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_DSSetShader(GET_SERIALISER, pDomainShader, ppClassInstances, NumClassInstances); MarkResourceReferenced(GetIDForResource(pDomainShader), eFrameRef_Read); m_ContextRecord->AddChunk(scope.Get()); } - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->DS.Shader, + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->DS.Object, (ID3D11DeviceChild *)pDomainShader); m_CurrentPipelineState->Change(m_CurrentPipelineState->DS.NumInstances, NumClassInstances); m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->DS.Instances, ppClassInstances, 0, @@ -1830,7 +1683,7 @@ void WrappedID3D11DeviceContext::GSGetShader(ID3D11GeometryShader **ppGeometrySh (ID3D11GeometryShader *)m_pDevice->GetResourceManager()->GetWrapper(realShader); SAFE_ADDREF(*ppGeometryShader); - RDCASSERT(*ppGeometryShader == m_CurrentPipelineState->GS.Shader); + RDCASSERT(*ppGeometryShader == m_CurrentPipelineState->GS.Object); } if(ppClassInstances) @@ -1851,45 +1704,34 @@ void WrappedID3D11DeviceContext::GSGetShader(ID3D11GeometryShader **ppGeometrySh } } -bool WrappedID3D11DeviceContext::Serialise_GSSetConstantBuffers(UINT StartSlot_, UINT NumBuffers_, +template +bool WrappedID3D11DeviceContext::Serialise_GSSetConstantBuffers(SerialiserType &ser, UINT StartSlot, + UINT NumBuffers, ID3D11Buffer *const *ppConstantBuffers) { - SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); - SERIALISE_ELEMENT(uint32_t, NumBuffers, NumBuffers_); + SERIALISE_ELEMENT(StartSlot); + SERIALISE_ELEMENT_ARRAY(ppConstantBuffers, NumBuffers); - ID3D11Buffer **Buffers = new ID3D11Buffer *[NumBuffers]; - - for(UINT i = 0; i < NumBuffers; i++) + if(IsReplayingAndReading()) { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppConstantBuffers[i])); + if(IsLoading(m_State)) + RecordConstantStats(ShaderStage::Geometry, NumBuffers, ppConstantBuffers); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Buffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Buffers[i] = NULL; - } - - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->GS.ConstantBuffers, Buffers, - StartSlot, NumBuffers); + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->GS.ConstantBuffers, + ppConstantBuffers, StartSlot, NumBuffers); m_CurrentPipelineState->Change(m_CurrentPipelineState->GS.CBOffsets, NullCBOffsets, StartSlot, NumBuffers); m_CurrentPipelineState->Change(m_CurrentPipelineState->GS.CBCounts, NullCBCounts, StartSlot, NumBuffers); + ID3D11Buffer *bufs[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {0}; for(UINT i = 0; i < NumBuffers; i++) - Buffers[i] = UNWRAP(WrappedID3D11Buffer, Buffers[i]); + bufs[i] = UNWRAP(WrappedID3D11Buffer, ppConstantBuffers[i]); - if(m_State == READING) - RecordConstantStats(ShaderStage::Geometry, NumBuffers, Buffers); - - m_pRealContext->GSSetConstantBuffers(StartSlot, NumBuffers, Buffers); + m_pRealContext->GSSetConstantBuffers(StartSlot, NumBuffers, bufs); VerifyState(); } - SAFE_DELETE_ARRAY(Buffers); - return true; } @@ -1900,11 +1742,12 @@ void WrappedID3D11DeviceContext::GSSetConstantBuffers(UINT StartSlot, UINT NumBu m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(SET_GS_CBUFFERS); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_GSSetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::GSSetConstantBuffers); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_GSSetConstantBuffers(GET_SERIALISER, StartSlot, NumBuffers, ppConstantBuffers); m_ContextRecord->AddChunk(scope.Get()); } @@ -1919,7 +1762,7 @@ void WrappedID3D11DeviceContext::GSSetConstantBuffers(UINT StartSlot, UINT NumBu ID3D11Buffer *bufs[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; for(UINT i = 0; i < NumBuffers; i++) { - if(ppConstantBuffers[i] && m_State >= WRITING_CAPFRAME) + if(ppConstantBuffers[i] && IsActiveCapturing(m_State)) MarkResourceReferenced(GetIDForResource(ppConstantBuffers[i]), eFrameRef_Read); bufs[i] = UNWRAP(WrappedID3D11Buffer, ppConstantBuffers[i]); @@ -1929,41 +1772,30 @@ void WrappedID3D11DeviceContext::GSSetConstantBuffers(UINT StartSlot, UINT NumBu VerifyState(); } +template bool WrappedID3D11DeviceContext::Serialise_GSSetShaderResources( - UINT StartSlot_, UINT NumViews_, ID3D11ShaderResourceView *const *ppShaderResourceViews) + SerialiserType &ser, UINT StartSlot, UINT NumViews, + ID3D11ShaderResourceView *const *ppShaderResourceViews) { - SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); - SERIALISE_ELEMENT(uint32_t, NumViews, NumViews_); + SERIALISE_ELEMENT(StartSlot); + SERIALISE_ELEMENT_ARRAY(ppShaderResourceViews, NumViews); - ID3D11ShaderResourceView **Views = new ID3D11ShaderResourceView *[NumViews]; - - for(UINT i = 0; i < NumViews; i++) + if(IsReplayingAndReading()) { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppShaderResourceViews[i])); + if(IsLoading(m_State)) + RecordResourceStats(ShaderStage::Geometry, NumViews, ppShaderResourceViews); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Views[i] = (ID3D11ShaderResourceView *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Views[i] = NULL; - } - - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->GS.SRVs, Views, StartSlot, - NumViews); + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->GS.SRVs, ppShaderResourceViews, + StartSlot, NumViews); + ID3D11ShaderResourceView *SRVs[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; for(UINT i = 0; i < NumViews; i++) - Views[i] = UNWRAP(WrappedID3D11ShaderResourceView1, Views[i]); + SRVs[i] = UNWRAP(WrappedID3D11ShaderResourceView1, ppShaderResourceViews[i]); - if(m_State == READING) - RecordResourceStats(ShaderStage::Geometry, NumViews, Views); - - m_pRealContext->GSSetShaderResources(StartSlot, NumViews, Views); + m_pRealContext->GSSetShaderResources(StartSlot, NumViews, SRVs); VerifyState(); } - SAFE_DELETE_ARRAY(Views); - return true; } @@ -1974,11 +1806,12 @@ void WrappedID3D11DeviceContext::GSSetShaderResources( m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(SET_GS_RESOURCES); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_GSSetShaderResources(StartSlot, NumViews, ppShaderResourceViews); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::GSSetShaderResources); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_GSSetShaderResources(GET_SERIALISER, StartSlot, NumViews, ppShaderResourceViews); m_ContextRecord->AddChunk(scope.Get()); } @@ -1989,7 +1822,7 @@ void WrappedID3D11DeviceContext::GSSetShaderResources( ID3D11ShaderResourceView *SRVs[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; for(UINT i = 0; i < NumViews; i++) { - if(ppShaderResourceViews[i] && m_State >= WRITING_CAPFRAME) + if(ppShaderResourceViews[i] && IsActiveCapturing(m_State)) { MarkResourceReferenced(GetIDForResource(ppShaderResourceViews[i]), eFrameRef_Read); MarkResourceReferenced(GetViewResourceResID(ppShaderResourceViews[i]), eFrameRef_Read); @@ -2002,41 +1835,30 @@ void WrappedID3D11DeviceContext::GSSetShaderResources( VerifyState(); } -bool WrappedID3D11DeviceContext::Serialise_GSSetSamplers(UINT StartSlot_, UINT NumSamplers_, +template +bool WrappedID3D11DeviceContext::Serialise_GSSetSamplers(SerialiserType &ser, UINT StartSlot, + UINT NumSamplers, ID3D11SamplerState *const *ppSamplers) { - SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); - SERIALISE_ELEMENT(uint32_t, NumSamplers, NumSamplers_); + SERIALISE_ELEMENT(StartSlot); + SERIALISE_ELEMENT_ARRAY(ppSamplers, NumSamplers); - ID3D11SamplerState **Samplers = new ID3D11SamplerState *[NumSamplers]; - - for(UINT i = 0; i < NumSamplers; i++) + if(IsReplayingAndReading()) { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppSamplers[i])); + if(IsLoading(m_State)) + RecordSamplerStats(ShaderStage::Geometry, NumSamplers, ppSamplers); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Samplers[i] = (ID3D11SamplerState *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Samplers[i] = NULL; - } - - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->GS.Samplers, Samplers, StartSlot, - NumSamplers); + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->GS.Samplers, ppSamplers, + StartSlot, NumSamplers); + ID3D11SamplerState *samps[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT]; for(UINT i = 0; i < NumSamplers; i++) - Samplers[i] = UNWRAP(WrappedID3D11SamplerState, Samplers[i]); + samps[i] = UNWRAP(WrappedID3D11SamplerState, ppSamplers[i]); - if(m_State == READING) - RecordSamplerStats(ShaderStage::Geometry, NumSamplers, Samplers); - - m_pRealContext->GSSetSamplers(StartSlot, NumSamplers, Samplers); + m_pRealContext->GSSetSamplers(StartSlot, NumSamplers, samps); VerifyState(); } - SAFE_DELETE_ARRAY(Samplers); - return true; } @@ -2047,11 +1869,12 @@ void WrappedID3D11DeviceContext::GSSetSamplers(UINT StartSlot, UINT NumSamplers, m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(SET_GS_SAMPLERS); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_GSSetSamplers(StartSlot, NumSamplers, ppSamplers); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::GSSetSamplers); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_GSSetSamplers(GET_SERIALISER, StartSlot, NumSamplers, ppSamplers); m_ContextRecord->AddChunk(scope.Get()); } @@ -2067,49 +1890,35 @@ void WrappedID3D11DeviceContext::GSSetSamplers(UINT StartSlot, UINT NumSamplers, VerifyState(); } -bool WrappedID3D11DeviceContext::Serialise_GSSetShader(ID3D11GeometryShader *pShader, +template +bool WrappedID3D11DeviceContext::Serialise_GSSetShader(SerialiserType &ser, + ID3D11GeometryShader *pShader, ID3D11ClassInstance *const *ppClassInstances, - UINT NumClassInstances_) + UINT NumClassInstances) { - SERIALISE_ELEMENT(ResourceId, Shader, GetIDForResource(pShader)); - SERIALISE_ELEMENT(uint32_t, NumClassInstances, NumClassInstances_); + SERIALISE_ELEMENT(pShader); + SERIALISE_ELEMENT_ARRAY(ppClassInstances, NumClassInstances); - ID3D11ClassInstance **Instances = new ID3D11ClassInstance *[NumClassInstances]; - - for(UINT i = 0; i < NumClassInstances; i++) + if(IsReplayingAndReading()) { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppClassInstances[i])); + if(IsLoading(m_State)) + RecordShaderStats(ShaderStage::Geometry, m_CurrentPipelineState->GS.Object, pShader); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Instances[i] = (ID3D11ClassInstance *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Instances[i] = NULL; - } - - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->GS.Instances, Instances, 0, + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->GS.Instances, ppClassInstances, 0, NumClassInstances); m_CurrentPipelineState->Change(m_CurrentPipelineState->GS.NumInstances, NumClassInstances); + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->GS.Object, + (ID3D11DeviceChild *)pShader); + ID3D11ClassInstance *insts[D3D11_SHADER_MAX_INTERFACES] = {0}; for(UINT i = 0; i < NumClassInstances; i++) - Instances[i] = UNWRAP(WrappedID3D11ClassInstance, Instances[i]); + insts[i] = UNWRAP(WrappedID3D11ClassInstance, ppClassInstances[i]); - ID3D11DeviceChild *pSH = NULL; - if(m_pDevice->GetResourceManager()->HasLiveResource(Shader)) - pSH = (ID3D11DeviceChild *)m_pDevice->GetResourceManager()->GetLiveResource(Shader); - - if(m_State == READING) - RecordShaderStats(ShaderStage::Geometry, m_CurrentPipelineState->GS.Shader, pSH); - - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->GS.Shader, pSH); - m_pRealContext->GSSetShader(UNWRAP(WrappedID3D11Shader, pSH), Instances, + m_pRealContext->GSSetShader(UNWRAP(WrappedID3D11Shader, pShader), insts, NumClassInstances); VerifyState(); } - SAFE_DELETE_ARRAY(Instances); - return true; } @@ -2121,18 +1930,19 @@ void WrappedID3D11DeviceContext::GSSetShader(ID3D11GeometryShader *pShader, m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(SET_GS); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_GSSetShader(pShader, ppClassInstances, NumClassInstances); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::GSSetShader); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_GSSetShader(GET_SERIALISER, pShader, ppClassInstances, NumClassInstances); MarkResourceReferenced(GetIDForResource(pShader), eFrameRef_Read); m_ContextRecord->AddChunk(scope.Get()); } - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->GS.Shader, + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->GS.Object, (ID3D11DeviceChild *)pShader); m_CurrentPipelineState->Change(m_CurrentPipelineState->GS.NumInstances, NumClassInstances); m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->GS.Instances, ppClassInstances, 0, @@ -2170,45 +1980,32 @@ void WrappedID3D11DeviceContext::SOGetTargets(UINT NumBuffers, ID3D11Buffer **pp } } -bool WrappedID3D11DeviceContext::Serialise_SOSetTargets(UINT NumBuffers_, +template +bool WrappedID3D11DeviceContext::Serialise_SOSetTargets(SerialiserType &ser, UINT NumBuffers, ID3D11Buffer *const *ppSOTargets, const UINT *pOffsets) { - SERIALISE_ELEMENT(uint32_t, NumBuffers, NumBuffers_); + SERIALISE_ELEMENT_ARRAY(ppSOTargets, NumBuffers); + SERIALISE_ELEMENT_ARRAY(pOffsets, NumBuffers); + // serialise NumBuffers here, because if either of the above were NULL it would be set to 0 + SERIALISE_ELEMENT(NumBuffers); - UINT DefaultOffsets[] = { - ~0U, ~0U, ~0U, ~0U, ~0U, ~0U, ~0U, ~0U, - }; - RDCCOMPILE_ASSERT(ARRAY_COUNT(DefaultOffsets) >= D3D11_SO_STREAM_COUNT, - "Insufficiently sized array of default offsets"); - - SERIALISE_ELEMENT_ARR(uint32_t, Offsets, pOffsets ? pOffsets : DefaultOffsets, NumBuffers); - - ID3D11Buffer **Buffers = new ID3D11Buffer *[NumBuffers]; - - for(UINT i = 0; i < NumBuffers; i++) + if(IsReplayingAndReading()) { - SERIALISE_ELEMENT(ResourceId, id, ppSOTargets ? GetIDForResource(ppSOTargets[i]) : ResourceId()); - - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Buffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Buffers[i] = NULL; - } - - if(m_State <= EXECUTING) - { - ID3D11Buffer *setbufs[4] = {0}; - UINT setoffs[4] = {0}; + // "If less than four [buffers] are defined by the call, the remaining buffer slots are set to + // NULL." + ID3D11Buffer *setbufs[D3D11_SO_STREAM_COUNT] = {0}; + UINT setoffs[D3D11_SO_STREAM_COUNT] = {0}; for(UINT b = 0; b < NumBuffers; b++) { - setbufs[b] = Buffers[b]; - setoffs[b] = Offsets[b]; + setbufs[b] = ppSOTargets ? ppSOTargets[b] : NULL; + // passing NULL for pOffsets seems to act like -1 => append + setoffs[b] = pOffsets ? pOffsets[b] : ~0U; } // end stream-out queries for outgoing targets - for(UINT b = 0; b < 4; b++) + for(UINT b = 0; b < D3D11_SO_STREAM_COUNT; b++) { ID3D11Buffer *buf = m_CurrentPipelineState->SO.Buffers[b]; @@ -2222,7 +2019,7 @@ bool WrappedID3D11DeviceContext::Serialise_SOSetTargets(UINT NumBuffers_, } // start new queries for incoming targets - for(UINT b = 0; b < 4; b++) + for(UINT b = 0; b < D3D11_SO_STREAM_COUNT; b++) { ID3D11Buffer *buf = setbufs[b]; @@ -2249,23 +2046,18 @@ bool WrappedID3D11DeviceContext::Serialise_SOSetTargets(UINT NumBuffers_, } } - m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->SO.Buffers, setbufs, 0, 4); - m_CurrentPipelineState->Change(m_CurrentPipelineState->SO.Offsets, setoffs, 0, 4); - } + m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->SO.Buffers, setbufs, 0, + D3D11_SO_STREAM_COUNT); + m_CurrentPipelineState->Change(m_CurrentPipelineState->SO.Offsets, setoffs, 0, + D3D11_SO_STREAM_COUNT); - for(UINT i = 0; i < NumBuffers; i++) - if(m_State <= EXECUTING) - Buffers[i] = UNWRAP(WrappedID3D11Buffer, Buffers[i]); + for(UINT i = 0; i < NumBuffers; i++) + setbufs[i] = UNWRAP(WrappedID3D11Buffer, setbufs[i]); - if(m_State <= EXECUTING) - { - m_pRealContext->SOSetTargets(NumBuffers, Buffers, Offsets); + m_pRealContext->SOSetTargets(NumBuffers, setbufs, setoffs); VerifyState(); } - SAFE_DELETE_ARRAY(Buffers); - SAFE_DELETE_ARRAY(Offsets); - return true; } @@ -2276,17 +2068,20 @@ void WrappedID3D11DeviceContext::SOSetTargets(UINT NumBuffers, ID3D11Buffer *con m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(SET_SO_TARGETS); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_SOSetTargets(NumBuffers, ppSOTargets, pOffsets); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::SOSetTargets); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_SOSetTargets(GET_SERIALISER, NumBuffers, ppSOTargets, pOffsets); m_ContextRecord->AddChunk(scope.Get()); } - ID3D11Buffer *setbufs[4] = {0}; - UINT setoffs[4] = {0}; + // "If less than four [buffers] are defined by the call, the remaining buffer slots are set to + // NULL." + ID3D11Buffer *setbufs[D3D11_SO_STREAM_COUNT] = {0}; + UINT setoffs[D3D11_SO_STREAM_COUNT] = {0}; for(UINT b = 0; b < NumBuffers; b++) { @@ -2296,7 +2091,7 @@ void WrappedID3D11DeviceContext::SOSetTargets(UINT NumBuffers, ID3D11Buffer *con } // end stream-out queries for outgoing targets - for(UINT b = 0; b < 4; b++) + for(UINT b = 0; b < D3D11_SO_STREAM_COUNT; b++) { ID3D11Buffer *buf = m_CurrentPipelineState->SO.Buffers[b]; @@ -2310,7 +2105,7 @@ void WrappedID3D11DeviceContext::SOSetTargets(UINT NumBuffers, ID3D11Buffer *con } // start new queries for incoming targets - for(UINT b = 0; b < 4; b++) + for(UINT b = 0; b < D3D11_SO_STREAM_COUNT; b++) { ID3D11Buffer *buf = setbufs[b]; @@ -2337,10 +2132,10 @@ void WrappedID3D11DeviceContext::SOSetTargets(UINT NumBuffers, ID3D11Buffer *con } } - // "If less than four [buffers] are defined by the call, the remaining buffer slots are set to - // NULL." - m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->SO.Buffers, setbufs, 0, 4); - m_CurrentPipelineState->Change(m_CurrentPipelineState->SO.Offsets, setoffs, 0, 4); + m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->SO.Buffers, setbufs, 0, + D3D11_SO_STREAM_COUNT); + m_CurrentPipelineState->Change(m_CurrentPipelineState->SO.Offsets, setoffs, 0, + D3D11_SO_STREAM_COUNT); ID3D11Buffer *bufs[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT] = {0}; for(UINT i = 0; i < NumBuffers; i++) @@ -2350,13 +2145,13 @@ void WrappedID3D11DeviceContext::SOSetTargets(UINT NumBuffers, ID3D11Buffer *con // technically this isn't dirty until the draw call, but let's be conservative // 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_CAPFRAME) + if(IsActiveCapturing(m_State)) { MarkResourceReferenced(GetIDForResource(ppSOTargets[i]), eFrameRef_Write); m_MissingTracks.insert(GetIDForResource(ppSOTargets[i])); } - else if(m_State == WRITING_IDLE) + else if(IsBackgroundCapturing(m_State)) { MarkDirtyResource(GetIDForResource(ppSOTargets[i])); } @@ -2413,34 +2208,20 @@ void WrappedID3D11DeviceContext::RSGetState(ID3D11RasterizerState **ppRasterizer } } -bool WrappedID3D11DeviceContext::Serialise_RSSetViewports(UINT NumViewports_, +template +bool WrappedID3D11DeviceContext::Serialise_RSSetViewports(SerialiserType &ser, UINT NumViewports, const D3D11_VIEWPORT *pViewports) { - SERIALISE_ELEMENT(uint32_t, NumViewports, NumViewports_); + SERIALISE_ELEMENT_ARRAY(pViewports, NumViewports); - D3D11_VIEWPORT views[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE]; - - for(UINT i = 0; i < NumViewports; i++) + if(IsReplayingAndReading()) { - D3D11_VIEWPORT view; + if(IsLoading(m_State)) + RecordViewportStats(NumViewports, pViewports); - if(pViewports) - view = pViewports[i]; - - m_pSerialiser->SerialisePODArray<6>((string("Viewport[") + ToStr(i) + "]").c_str(), - (FLOAT *)&view); - - views[i] = view; - } - - if(m_State <= EXECUTING) - { - if(m_State == READING) - RecordViewportStats(NumViewports, views); - - m_CurrentPipelineState->Change(m_CurrentPipelineState->RS.Viewports, views, 0, NumViewports); + m_CurrentPipelineState->Change(m_CurrentPipelineState->RS.Viewports, pViewports, 0, NumViewports); m_CurrentPipelineState->Change(m_CurrentPipelineState->RS.NumViews, NumViewports); - m_pRealContext->RSSetViewports(NumViewports, views); + m_pRealContext->RSSetViewports(NumViewports, pViewports); VerifyState(); } @@ -2453,11 +2234,12 @@ void WrappedID3D11DeviceContext::RSSetViewports(UINT NumViewports, const D3D11_V m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(SET_VIEWPORTS); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_RSSetViewports(NumViewports, pViewports); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::RSSetViewports); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_RSSetViewports(GET_SERIALISER, NumViewports, pViewports); m_ContextRecord->AddChunk(scope.Get()); } @@ -2469,24 +2251,23 @@ void WrappedID3D11DeviceContext::RSSetViewports(UINT NumViewports, const D3D11_V VerifyState(); } -bool WrappedID3D11DeviceContext::Serialise_RSSetScissorRects(UINT NumRects_, const D3D11_RECT *pRects_) +template +bool WrappedID3D11DeviceContext::Serialise_RSSetScissorRects(SerialiserType &ser, UINT NumRects, + const D3D11_RECT *pRects) { - SERIALISE_ELEMENT(uint32_t, NumRects, NumRects_); - SERIALISE_ELEMENT_ARR(D3D11_RECT, Rects, pRects_, NumRects); + SERIALISE_ELEMENT_ARRAY(pRects, NumRects); - if(m_State <= EXECUTING) + if(IsReplayingAndReading()) { - if(m_State == READING) - RecordScissorStats(NumRects, Rects); + if(IsLoading(m_State)) + RecordScissorStats(NumRects, pRects); - m_CurrentPipelineState->Change(m_CurrentPipelineState->RS.Scissors, Rects, 0, NumRects); + m_CurrentPipelineState->Change(m_CurrentPipelineState->RS.Scissors, pRects, 0, NumRects); m_CurrentPipelineState->Change(m_CurrentPipelineState->RS.NumScissors, NumRects); - RSSetScissorRects(NumRects, Rects); + m_pRealContext->RSSetScissorRects(NumRects, pRects); VerifyState(); } - SAFE_DELETE_ARRAY(Rects); - return true; } @@ -2496,11 +2277,12 @@ void WrappedID3D11DeviceContext::RSSetScissorRects(UINT NumRects, const D3D11_RE m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(SET_SCISSORS); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_RSSetScissorRects(NumRects, pRects); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::RSSetScissorRects); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_RSSetScissorRects(GET_SERIALISER, NumRects, pRects); m_ContextRecord->AddChunk(scope.Get()); } @@ -2512,24 +2294,19 @@ void WrappedID3D11DeviceContext::RSSetScissorRects(UINT NumRects, const D3D11_RE VerifyState(); } -bool WrappedID3D11DeviceContext::Serialise_RSSetState(ID3D11RasterizerState *pRasterizerState) +template +bool WrappedID3D11DeviceContext::Serialise_RSSetState(SerialiserType &ser, + ID3D11RasterizerState *pRasterizerState) { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(pRasterizerState)); + SERIALISE_ELEMENT(pRasterizerState); - if(m_State <= EXECUTING) + if(IsReplayingAndReading()) { - ID3D11DeviceChild *live = NULL; - if(m_pDevice->GetResourceManager()->HasLiveResource(id)) - live = m_pDevice->GetResourceManager()->GetLiveResource(id); + if(IsLoading(m_State)) + RecordRasterizationStats(pRasterizerState); - if(m_State == READING) - RecordRasterizationStats((ID3D11RasterizerState *)live); - - { - ID3D11RasterizerState *state = (ID3D11RasterizerState *)live; - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->RS.State, state); - m_pRealContext->RSSetState(UNWRAP(WrappedID3D11RasterizerState2, state)); - } + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->RS.State, pRasterizerState); + m_pRealContext->RSSetState(UNWRAP(WrappedID3D11RasterizerState2, pRasterizerState)); VerifyState(); } @@ -2542,11 +2319,12 @@ void WrappedID3D11DeviceContext::RSSetState(ID3D11RasterizerState *pRasterizerSt m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(SET_RASTER); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_RSSetState(pRasterizerState); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::RSSetState); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_RSSetState(GET_SERIALISER, pRasterizerState); m_ContextRecord->AddChunk(scope.Get()); } @@ -2642,7 +2420,7 @@ void WrappedID3D11DeviceContext::PSGetShader(ID3D11PixelShader **ppPixelShader, *ppPixelShader = (ID3D11PixelShader *)m_pDevice->GetResourceManager()->GetWrapper(realShader); SAFE_ADDREF(*ppPixelShader); - RDCASSERT(*ppPixelShader == m_CurrentPipelineState->PS.Shader); + RDCASSERT(*ppPixelShader == m_CurrentPipelineState->PS.Object); } if(ppClassInstances) @@ -2663,40 +2441,31 @@ void WrappedID3D11DeviceContext::PSGetShader(ID3D11PixelShader **ppPixelShader, } } -bool WrappedID3D11DeviceContext::Serialise_PSSetConstantBuffers(UINT StartSlot_, UINT NumBuffers_, +template +bool WrappedID3D11DeviceContext::Serialise_PSSetConstantBuffers(SerialiserType &ser, UINT StartSlot, + UINT NumBuffers, ID3D11Buffer *const *ppConstantBuffers) { - SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); - SERIALISE_ELEMENT(uint32_t, NumBuffers, NumBuffers_); + SERIALISE_ELEMENT(StartSlot); + SERIALISE_ELEMENT_ARRAY(ppConstantBuffers, NumBuffers); - ID3D11Buffer *Buffers[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; - - for(UINT i = 0; i < NumBuffers; i++) + if(IsReplayingAndReading()) { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppConstantBuffers[i])); + if(IsLoading(m_State)) + RecordConstantStats(ShaderStage::Pixel, NumBuffers, ppConstantBuffers); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Buffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Buffers[i] = NULL; - } - - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->PS.ConstantBuffers, Buffers, - StartSlot, NumBuffers); + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->PS.ConstantBuffers, + ppConstantBuffers, StartSlot, NumBuffers); m_CurrentPipelineState->Change(m_CurrentPipelineState->PS.CBOffsets, NullCBOffsets, StartSlot, NumBuffers); m_CurrentPipelineState->Change(m_CurrentPipelineState->PS.CBCounts, NullCBCounts, StartSlot, NumBuffers); + ID3D11Buffer *bufs[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {0}; for(UINT i = 0; i < NumBuffers; i++) - Buffers[i] = UNWRAP(WrappedID3D11Buffer, Buffers[i]); + bufs[i] = UNWRAP(WrappedID3D11Buffer, ppConstantBuffers[i]); - if(m_State == READING) - RecordConstantStats(ShaderStage::Pixel, NumBuffers, Buffers); - - m_pRealContext->PSSetConstantBuffers(StartSlot, NumBuffers, Buffers); + m_pRealContext->PSSetConstantBuffers(StartSlot, NumBuffers, bufs); VerifyState(); } @@ -2710,11 +2479,12 @@ void WrappedID3D11DeviceContext::PSSetConstantBuffers(UINT StartSlot, UINT NumBu m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(SET_PS_CBUFFERS); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_PSSetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::PSSetConstantBuffers); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_PSSetConstantBuffers(GET_SERIALISER, StartSlot, NumBuffers, ppConstantBuffers); m_ContextRecord->AddChunk(scope.Get()); } @@ -2729,7 +2499,7 @@ void WrappedID3D11DeviceContext::PSSetConstantBuffers(UINT StartSlot, UINT NumBu ID3D11Buffer *bufs[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; for(UINT i = 0; i < NumBuffers; i++) { - if(ppConstantBuffers[i] && m_State >= WRITING_CAPFRAME) + if(ppConstantBuffers[i] && IsActiveCapturing(m_State)) MarkResourceReferenced(GetIDForResource(ppConstantBuffers[i]), eFrameRef_Read); bufs[i] = UNWRAP(WrappedID3D11Buffer, ppConstantBuffers[i]); @@ -2739,36 +2509,27 @@ void WrappedID3D11DeviceContext::PSSetConstantBuffers(UINT StartSlot, UINT NumBu VerifyState(); } +template bool WrappedID3D11DeviceContext::Serialise_PSSetShaderResources( - UINT StartSlot_, UINT NumViews_, ID3D11ShaderResourceView *const *ppShaderResourceViews) + SerialiserType &ser, UINT StartSlot, UINT NumViews, + ID3D11ShaderResourceView *const *ppShaderResourceViews) { - SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); - SERIALISE_ELEMENT(uint32_t, NumViews, NumViews_); + SERIALISE_ELEMENT(StartSlot); + SERIALISE_ELEMENT_ARRAY(ppShaderResourceViews, NumViews); - ID3D11ShaderResourceView *Views[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; - - for(UINT i = 0; i < NumViews; i++) + if(IsReplayingAndReading()) { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppShaderResourceViews[i])); + if(IsLoading(m_State)) + RecordResourceStats(ShaderStage::Pixel, NumViews, ppShaderResourceViews); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Views[i] = (ID3D11ShaderResourceView *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Views[i] = NULL; - } - - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->PS.SRVs, Views, StartSlot, - NumViews); + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->PS.SRVs, ppShaderResourceViews, + StartSlot, NumViews); + ID3D11ShaderResourceView *SRVs[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; for(UINT i = 0; i < NumViews; i++) - Views[i] = UNWRAP(WrappedID3D11ShaderResourceView1, Views[i]); + SRVs[i] = UNWRAP(WrappedID3D11ShaderResourceView1, ppShaderResourceViews[i]); - if(m_State == READING) - RecordResourceStats(ShaderStage::Pixel, NumViews, Views); - - m_pRealContext->PSSetShaderResources(StartSlot, NumViews, Views); + m_pRealContext->PSSetShaderResources(StartSlot, NumViews, SRVs); VerifyState(); } @@ -2782,11 +2543,12 @@ void WrappedID3D11DeviceContext::PSSetShaderResources( m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(SET_PS_RESOURCES); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_PSSetShaderResources(StartSlot, NumViews, ppShaderResourceViews); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::PSSetShaderResources); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_PSSetShaderResources(GET_SERIALISER, StartSlot, NumViews, ppShaderResourceViews); m_ContextRecord->AddChunk(scope.Get()); } @@ -2797,7 +2559,7 @@ void WrappedID3D11DeviceContext::PSSetShaderResources( ID3D11ShaderResourceView *SRVs[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; for(UINT i = 0; i < NumViews; i++) { - if(ppShaderResourceViews[i] && m_State >= WRITING_CAPFRAME) + if(ppShaderResourceViews[i] && IsActiveCapturing(m_State)) { MarkResourceReferenced(GetIDForResource(ppShaderResourceViews[i]), eFrameRef_Read); MarkResourceReferenced(GetViewResourceResID(ppShaderResourceViews[i]), eFrameRef_Read); @@ -2810,36 +2572,27 @@ void WrappedID3D11DeviceContext::PSSetShaderResources( VerifyState(); } -bool WrappedID3D11DeviceContext::Serialise_PSSetSamplers(UINT StartSlot_, UINT NumSamplers_, +template +bool WrappedID3D11DeviceContext::Serialise_PSSetSamplers(SerialiserType &ser, UINT StartSlot, + UINT NumSamplers, ID3D11SamplerState *const *ppSamplers) { - SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); - SERIALISE_ELEMENT(uint32_t, NumSamplers, NumSamplers_); + SERIALISE_ELEMENT(StartSlot); + SERIALISE_ELEMENT_ARRAY(ppSamplers, NumSamplers); - ID3D11SamplerState *Samplers[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT]; - - for(UINT i = 0; i < NumSamplers; i++) + if(IsReplayingAndReading()) { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppSamplers[i])); + if(IsLoading(m_State)) + RecordSamplerStats(ShaderStage::Pixel, NumSamplers, ppSamplers); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Samplers[i] = (ID3D11SamplerState *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Samplers[i] = NULL; - } - - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->PS.Samplers, Samplers, StartSlot, - NumSamplers); + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->PS.Samplers, ppSamplers, + StartSlot, NumSamplers); + ID3D11SamplerState *samps[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT]; for(UINT i = 0; i < NumSamplers; i++) - Samplers[i] = UNWRAP(WrappedID3D11SamplerState, Samplers[i]); + samps[i] = UNWRAP(WrappedID3D11SamplerState, ppSamplers[i]); - if(m_State == READING) - RecordSamplerStats(ShaderStage::Pixel, NumSamplers, Samplers); - - m_pRealContext->PSSetSamplers(StartSlot, NumSamplers, Samplers); + m_pRealContext->PSSetSamplers(StartSlot, NumSamplers, samps); VerifyState(); } @@ -2853,11 +2606,12 @@ void WrappedID3D11DeviceContext::PSSetSamplers(UINT StartSlot, UINT NumSamplers, m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(SET_PS_SAMPLERS); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_PSSetSamplers(StartSlot, NumSamplers, ppSamplers); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::PSSetSamplers); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_PSSetSamplers(GET_SERIALISER, StartSlot, NumSamplers, ppSamplers); m_ContextRecord->AddChunk(scope.Get()); } @@ -2873,49 +2627,35 @@ void WrappedID3D11DeviceContext::PSSetSamplers(UINT StartSlot, UINT NumSamplers, VerifyState(); } -bool WrappedID3D11DeviceContext::Serialise_PSSetShader(ID3D11PixelShader *pShader, +template +bool WrappedID3D11DeviceContext::Serialise_PSSetShader(SerialiserType &ser, + ID3D11PixelShader *pShader, ID3D11ClassInstance *const *ppClassInstances, - UINT NumClassInstances_) + UINT NumClassInstances) { - SERIALISE_ELEMENT(ResourceId, Shader, GetIDForResource(pShader)); - SERIALISE_ELEMENT(uint32_t, NumClassInstances, NumClassInstances_); + SERIALISE_ELEMENT(pShader); + SERIALISE_ELEMENT_ARRAY(ppClassInstances, NumClassInstances); - ID3D11ClassInstance **Instances = new ID3D11ClassInstance *[NumClassInstances]; - - for(UINT i = 0; i < NumClassInstances; i++) + if(IsReplayingAndReading()) { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppClassInstances[i])); + if(IsLoading(m_State)) + RecordShaderStats(ShaderStage::Pixel, m_CurrentPipelineState->PS.Object, pShader); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Instances[i] = (ID3D11ClassInstance *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Instances[i] = NULL; - } - - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->PS.Instances, Instances, 0, + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->PS.Instances, ppClassInstances, 0, NumClassInstances); m_CurrentPipelineState->Change(m_CurrentPipelineState->PS.NumInstances, NumClassInstances); + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->PS.Object, + (ID3D11DeviceChild *)pShader); + ID3D11ClassInstance *insts[D3D11_SHADER_MAX_INTERFACES] = {0}; for(UINT i = 0; i < NumClassInstances; i++) - Instances[i] = UNWRAP(WrappedID3D11ClassInstance, Instances[i]); + insts[i] = UNWRAP(WrappedID3D11ClassInstance, ppClassInstances[i]); - ID3D11DeviceChild *pSH = NULL; - if(m_pDevice->GetResourceManager()->HasLiveResource(Shader)) - pSH = (ID3D11DeviceChild *)m_pDevice->GetResourceManager()->GetLiveResource(Shader); - - if(m_State == READING) - RecordShaderStats(ShaderStage::Pixel, m_CurrentPipelineState->PS.Shader, pSH); - - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->PS.Shader, pSH); - m_pRealContext->PSSetShader(UNWRAP(WrappedID3D11Shader, pSH), Instances, + m_pRealContext->PSSetShader(UNWRAP(WrappedID3D11Shader, pShader), insts, NumClassInstances); VerifyState(); } - SAFE_DELETE_ARRAY(Instances); - return true; } @@ -2927,18 +2667,19 @@ void WrappedID3D11DeviceContext::PSSetShader(ID3D11PixelShader *pPixelShader, m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(SET_PS); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_PSSetShader(pPixelShader, ppClassInstances, NumClassInstances); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::PSSetShader); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_PSSetShader(GET_SERIALISER, pPixelShader, ppClassInstances, NumClassInstances); MarkResourceReferenced(GetIDForResource(pPixelShader), eFrameRef_Read); m_ContextRecord->AddChunk(scope.Get()); } - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->PS.Shader, + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->PS.Object, (ID3D11DeviceChild *)pPixelShader); m_CurrentPipelineState->Change(m_CurrentPipelineState->PS.NumInstances, NumClassInstances); m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->PS.Instances, ppClassInstances, 0, @@ -3106,39 +2847,24 @@ void WrappedID3D11DeviceContext::OMGetDepthStencilState(ID3D11DepthStencilState RDCASSERT(*pStencilRef == m_CurrentPipelineState->OM.StencRef); } +template bool WrappedID3D11DeviceContext::Serialise_OMSetRenderTargets( - UINT NumViews_, ID3D11RenderTargetView *const *ppRenderTargetViews, + SerialiserType &ser, UINT NumViews, ID3D11RenderTargetView *const *ppRenderTargetViews, ID3D11DepthStencilView *pDepthStencilView) { - SERIALISE_ELEMENT(uint32_t, NumViews, NumViews_); - SERIALISE_ELEMENT(ResourceId, DepthStencilView, GetIDForResource(pDepthStencilView)); + SERIALISE_ELEMENT_ARRAY(ppRenderTargetViews, NumViews); + SERIALISE_ELEMENT(pDepthStencilView); - ID3D11RenderTargetView **RenderTargetViews = - new ID3D11RenderTargetView *[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT]; - - for(UINT i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) - RenderTargetViews[i] = NULL; - - for(UINT i = 0; i < NumViews; i++) + if(IsReplayingAndReading()) { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppRenderTargetViews[i])); + ID3D11RenderTargetView *RTs[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = {0}; + for(UINT i = 0; i < NumViews; i++) + RTs[i] = ppRenderTargetViews[i]; - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - RenderTargetViews[i] = - (ID3D11RenderTargetView *)m_pDevice->GetResourceManager()->GetLiveResource(id); - } - - if(m_State <= EXECUTING) - { - pDepthStencilView = NULL; - if(m_pDevice->GetResourceManager()->HasLiveResource(DepthStencilView)) - pDepthStencilView = (ID3D11DepthStencilView *)m_pDevice->GetResourceManager()->GetLiveResource( - DepthStencilView); - - if(m_CurrentPipelineState->ValidOutputMerger(RenderTargetViews, pDepthStencilView, NULL)) + if(m_CurrentPipelineState->ValidOutputMerger(ppRenderTargetViews, NumViews, pDepthStencilView, + NULL, 0)) { - m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->OM.RenderTargets, - RenderTargetViews, 0, + m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->OM.RenderTargets, RTs, 0, D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT); m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->OM.DepthView, pDepthStencilView); } @@ -3150,18 +2876,16 @@ bool WrappedID3D11DeviceContext::Serialise_OMSetRenderTargets( m_CurrentPipelineState->Change(m_CurrentPipelineState->OM.UAVStartSlot, NumViews); for(UINT i = 0; i < NumViews; i++) - RenderTargetViews[i] = UNWRAP(WrappedID3D11RenderTargetView1, RenderTargetViews[i]); + RTs[i] = UNWRAP(WrappedID3D11RenderTargetView1, RTs[i]); - if(m_State == READING) - RecordOutputMergerStats(NumViews, RenderTargetViews, pDepthStencilView, 0, 0, NULL); + if(IsLoading(m_State)) + RecordOutputMergerStats(NumViews, RTs, pDepthStencilView, 0, 0, NULL); - m_pRealContext->OMSetRenderTargets(NumViews, RenderTargetViews, + m_pRealContext->OMSetRenderTargets(NumViews, RTs, UNWRAP(WrappedID3D11DepthStencilView, pDepthStencilView)); VerifyState(); } - SAFE_DELETE_ARRAY(RenderTargetViews); - return true; } @@ -3173,11 +2897,12 @@ void WrappedID3D11DeviceContext::OMSetRenderTargets(UINT NumViews, m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_SMALL_CONTEXT(SET_RTARGET); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_OMSetRenderTargets(NumViews, ppRenderTargetViews, pDepthStencilView); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::OMSetRenderTargets); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_OMSetRenderTargets(GET_SERIALISER, NumViews, ppRenderTargetViews, pDepthStencilView); m_ContextRecord->AddChunk(scope.Get()); } @@ -3187,33 +2912,13 @@ void WrappedID3D11DeviceContext::OMSetRenderTargets(UINT NumViews, RTs[i] = ppRenderTargetViews[i]; // this function always sets all render targets - if(m_CurrentPipelineState->ValidOutputMerger(RTs, pDepthStencilView, NULL)) + if(m_CurrentPipelineState->ValidOutputMerger(RTs, NumViews, pDepthStencilView, NULL, 0)) { m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->OM.RenderTargets, RTs, 0, D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT); m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->OM.DepthView, pDepthStencilView); m_CurrentPipelineState->Change(m_CurrentPipelineState->OM.UAVStartSlot, NumViews); } - else if(m_State >= WRITING) - { - // make sure to mark resources referenced if the OM state is invalid, so they aren't eliminated - // from the - // log (which might make this combination valid on replay without some of the targets!) - for(UINT i = 0; i < NumViews; i++) - { - if(ppRenderTargetViews && ppRenderTargetViews[i]) - { - MarkResourceReferenced(GetIDForResource(ppRenderTargetViews[i]), eFrameRef_Read); - MarkResourceReferenced(GetViewResourceResID(ppRenderTargetViews[i]), eFrameRef_Read); - } - } - - if(pDepthStencilView) - { - MarkResourceReferenced(GetIDForResource(pDepthStencilView), eFrameRef_Read); - MarkResourceReferenced(GetViewResourceResID(pDepthStencilView), eFrameRef_Read); - } - } ID3D11UnorderedAccessView *UAVs[D3D11_1_UAV_SLOT_COUNT] = {0}; m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->OM.UAVs, UAVs, 0, @@ -3223,14 +2928,14 @@ void WrappedID3D11DeviceContext::OMSetRenderTargets(UINT NumViews, { if(ppRenderTargetViews && ppRenderTargetViews[i]) { - if(m_State >= WRITING) + if(IsCaptureMode(m_State)) { // technically this isn't dirty until the draw call, but let's be conservative // 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) + if(IsBackgroundCapturing(m_State)) MarkDirtyResource(GetViewResourceResID(ppRenderTargetViews[i])); - else if(m_State == WRITING_CAPFRAME) + else if(IsActiveCapturing(m_State)) m_MissingTracks.insert(GetViewResourceResID(ppRenderTargetViews[i])); } @@ -3238,143 +2943,146 @@ void WrappedID3D11DeviceContext::OMSetRenderTargets(UINT NumViews, } } - if(pDepthStencilView && m_State >= WRITING) + if(pDepthStencilView && IsCaptureMode(m_State)) { - if(m_State == WRITING_IDLE) + if(IsBackgroundCapturing(m_State)) MarkDirtyResource(GetViewResourceResID(pDepthStencilView)); - else if(m_State == WRITING_CAPFRAME) + else if(IsActiveCapturing(m_State)) m_MissingTracks.insert(GetViewResourceResID(pDepthStencilView)); } m_CurrentPipelineState->CacheViewportPartial(); + if(IsCaptureMode(m_State)) + { + // make sure to mark resources referenced even if the OM state is invalid, so they aren't + // eliminated from the capture (which might make this combination valid on replay without some + // of the targets!) + for(UINT i = 0; i < NumViews; i++) + { + if(ppRenderTargetViews && ppRenderTargetViews[i]) + { + MarkResourceReferenced(GetIDForResource(ppRenderTargetViews[i]), eFrameRef_Read); + if(m_CurrentPipelineState->IsViewportPartial()) + MarkResourceReferenced(GetViewResourceResID(ppRenderTargetViews[i]), eFrameRef_Read); + MarkResourceReferenced(GetViewResourceResID(ppRenderTargetViews[i]), eFrameRef_Write); + } + } + + if(pDepthStencilView) + { + MarkResourceReferenced(GetIDForResource(pDepthStencilView), eFrameRef_Read); + if(m_CurrentPipelineState->IsViewportPartial()) + MarkResourceReferenced(GetViewResourceResID(pDepthStencilView), eFrameRef_Read); + MarkResourceReferenced(GetViewResourceResID(pDepthStencilView), eFrameRef_Write); + } + } + m_pRealContext->OMSetRenderTargets(NumViews, RTs, UNWRAP(WrappedID3D11DepthStencilView, pDepthStencilView)); VerifyState(); } +template bool WrappedID3D11DeviceContext::Serialise_OMSetRenderTargetsAndUnorderedAccessViews( - UINT NumRTVs_, ID3D11RenderTargetView *const *ppRenderTargetViews, - ID3D11DepthStencilView *pDepthStencilView, UINT UAVStartSlot_, UINT NumUAVs_, + SerialiserType &ser, UINT NumRTVs, ID3D11RenderTargetView *const *ppRenderTargetViews, + ID3D11DepthStencilView *pDepthStencilView, UINT UAVStartSlot, UINT NumUAVs, ID3D11UnorderedAccessView *const *ppUnorderedAccessViews, const UINT *pUAVInitialCounts) { - SERIALISE_ELEMENT(ResourceId, DepthStencilView, GetIDForResource(pDepthStencilView)); + // handle special values for counts + SERIALISE_ELEMENT_LOCAL(KeepRTVs, bool(NumRTVs == D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL)); + SERIALISE_ELEMENT_LOCAL(KeepUAVs, bool(NumUAVs == D3D11_KEEP_UNORDERED_ACCESS_VIEWS)); - SERIALISE_ELEMENT(uint32_t, NumRTVs, NumRTVs_); + const bool ModifyRTVs = !KeepRTVs; + const bool ModifyUAVs = !KeepUAVs; - SERIALISE_ELEMENT(uint32_t, UAVStartSlot, UAVStartSlot_); - SERIALISE_ELEMENT(uint32_t, NumUAVs, NumUAVs_); + if(!ModifyRTVs) + NumRTVs = 0; + if(!ModifyUAVs) + NumUAVs = 0; - ID3D11RenderTargetView **RenderTargetViews = NULL; - ID3D11UnorderedAccessView **UnorderedAccessViews = NULL; + SERIALISE_ELEMENT_ARRAY(ppRenderTargetViews, NumRTVs); + SERIALISE_ELEMENT(NumRTVs); - if(NumRTVs != D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL) + SERIALISE_ELEMENT(pDepthStencilView); + SERIALISE_ELEMENT(UAVStartSlot); + + SERIALISE_ELEMENT_ARRAY(ppUnorderedAccessViews, NumUAVs); + SERIALISE_ELEMENT_ARRAY(pUAVInitialCounts, NumUAVs); + SERIALISE_ELEMENT(NumUAVs); + + RDCASSERT(ModifyRTVs || ModifyUAVs); + + if(IsReplayingAndReading()) { - RenderTargetViews = new ID3D11RenderTargetView *[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT]; - for(UINT i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) - RenderTargetViews[i] = NULL; - } + // any bind of RTVs or UAVs implicitly NULLs out the remaining slots, so we don't want to just + // change the bindings we were passed, we want to always change ALL bindings, and just set the + // subset that we were passed + ID3D11RenderTargetView *RTs[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = {0}; + ID3D11UnorderedAccessView *UAVs[D3D11_1_UAV_SLOT_COUNT] = {0}; - if(NumUAVs != D3D11_KEEP_UNORDERED_ACCESS_VIEWS) - { - UnorderedAccessViews = new ID3D11UnorderedAccessView *[D3D11_1_UAV_SLOT_COUNT]; - for(UINT i = 0; i < D3D11_1_UAV_SLOT_COUNT; i++) - UnorderedAccessViews[i] = NULL; - } + for(UINT i = 0; i < NumRTVs && ModifyRTVs; i++) + RTs[i] = ppRenderTargetViews[i]; - SERIALISE_ELEMENT(uint8_t, HasInitialCounts, pUAVInitialCounts != NULL); + for(UINT i = 0; i < NumUAVs && ModifyUAVs; i++) + UAVs[i] = ppUnorderedAccessViews[i]; - SERIALISE_ELEMENT_ARR_OPT(uint32_t, UAVInitialCounts, pUAVInitialCounts, NumUAVs, - HasInitialCounts && NumUAVs != D3D11_KEEP_UNORDERED_ACCESS_VIEWS); - - RDCASSERT(NumRTVs != D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL || - NumUAVs != D3D11_KEEP_UNORDERED_ACCESS_VIEWS); - - for(UINT i = 0; i < NumRTVs && NumRTVs != D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL; i++) - { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppRenderTargetViews[i])); - - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - RenderTargetViews[i] = - (ID3D11RenderTargetView *)m_pDevice->GetResourceManager()->GetLiveResource(id); - } - - for(UINT i = 0; i < NumUAVs && NumUAVs != D3D11_KEEP_UNORDERED_ACCESS_VIEWS; i++) - { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppUnorderedAccessViews[i])); - - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - UnorderedAccessViews[i] = - (ID3D11UnorderedAccessView *)m_pDevice->GetResourceManager()->GetLiveResource(id); - } - - if(m_State <= EXECUTING) - { - pDepthStencilView = NULL; - if(m_pDevice->GetResourceManager()->HasLiveResource(DepthStencilView)) - pDepthStencilView = (ID3D11DepthStencilView *)m_pDevice->GetResourceManager()->GetLiveResource( - DepthStencilView); - - if(NumRTVs != D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL) + if(ModifyRTVs) { - ID3D11UnorderedAccessView **srcUAVs = NumUAVs != D3D11_KEEP_UNORDERED_ACCESS_VIEWS - ? UnorderedAccessViews - : m_CurrentPipelineState->OM.UAVs; + ID3D11UnorderedAccessView *const *srcUAVs = + ModifyUAVs ? ppUnorderedAccessViews : m_CurrentPipelineState->OM.UAVs; + UINT srcUAVcount = ModifyUAVs ? NumUAVs : D3D11_1_UAV_SLOT_COUNT; - if(m_CurrentPipelineState->ValidOutputMerger(RenderTargetViews, pDepthStencilView, srcUAVs)) + if(m_CurrentPipelineState->ValidOutputMerger(ppRenderTargetViews, NumRTVs, pDepthStencilView, + srcUAVs, srcUAVcount)) { - m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->OM.RenderTargets, - RenderTargetViews, 0, + m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->OM.RenderTargets, RTs, 0, D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT); m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->OM.DepthView, pDepthStencilView); } } - if(NumUAVs != D3D11_KEEP_UNORDERED_ACCESS_VIEWS) + if(ModifyUAVs) { bool valid = false; - if(NumRTVs != D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL) - valid = m_CurrentPipelineState->ValidOutputMerger(RenderTargetViews, pDepthStencilView, - UnorderedAccessViews); + if(ModifyRTVs) + valid = m_CurrentPipelineState->ValidOutputMerger( + ppRenderTargetViews, NumRTVs, pDepthStencilView, ppUnorderedAccessViews, NumUAVs); else - valid = m_CurrentPipelineState->ValidOutputMerger(m_CurrentPipelineState->OM.RenderTargets, - m_CurrentPipelineState->OM.DepthView, - UnorderedAccessViews); + valid = m_CurrentPipelineState->ValidOutputMerger( + m_CurrentPipelineState->OM.RenderTargets, D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, + m_CurrentPipelineState->OM.DepthView, ppUnorderedAccessViews, NumUAVs); if(valid) { - m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->OM.UAVs, - UnorderedAccessViews, 0, D3D11_1_UAV_SLOT_COUNT); + m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->OM.UAVs, UAVs, 0, + D3D11_1_UAV_SLOT_COUNT); m_CurrentPipelineState->Change(m_CurrentPipelineState->OM.UAVStartSlot, UAVStartSlot); } } - for(UINT i = 0; i < NumRTVs && NumRTVs != D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL; i++) - RenderTargetViews[i] = UNWRAP(WrappedID3D11RenderTargetView1, RenderTargetViews[i]); + for(UINT i = 0; i < NumRTVs && ModifyRTVs; i++) + RTs[i] = UNWRAP(WrappedID3D11RenderTargetView1, RTs[i]); - for(UINT i = 0; i < NumUAVs && NumUAVs != D3D11_KEEP_UNORDERED_ACCESS_VIEWS; i++) - UnorderedAccessViews[i] = UNWRAP(WrappedID3D11UnorderedAccessView1, UnorderedAccessViews[i]); + for(UINT i = 0; i < NumUAVs && ModifyUAVs; i++) + UAVs[i] = UNWRAP(WrappedID3D11UnorderedAccessView1, UAVs[i]); - if(NumRTVs != D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL) + if(ModifyRTVs) pDepthStencilView = UNWRAP(WrappedID3D11DepthStencilView, pDepthStencilView); else pDepthStencilView = NULL; - if(m_State == READING) - RecordOutputMergerStats(NumRTVs, RenderTargetViews, pDepthStencilView, UAVStartSlot, NumUAVs, - UnorderedAccessViews); + if(IsLoading(m_State)) + RecordOutputMergerStats(NumRTVs, RTs, pDepthStencilView, UAVStartSlot, NumUAVs, UAVs); m_pRealContext->OMSetRenderTargetsAndUnorderedAccessViews( - NumRTVs, RenderTargetViews, pDepthStencilView, UAVStartSlot, NumUAVs, UnorderedAccessViews, - UAVInitialCounts); + ModifyRTVs ? NumRTVs : D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL, RTs, pDepthStencilView, + UAVStartSlot, ModifyUAVs ? NumUAVs : D3D11_KEEP_UNORDERED_ACCESS_VIEWS, UAVs, + pUAVInitialCounts); VerifyState(); } - SAFE_DELETE_ARRAY(RenderTargetViews); - SAFE_DELETE_ARRAY(UnorderedAccessViews); - SAFE_DELETE_ARRAY(UAVInitialCounts); - return true; } @@ -3399,11 +3107,12 @@ void WrappedID3D11DeviceContext::OMSetRenderTargetsAndUnorderedAccessViews( UAVStartSlot = RDCMAX(m_CurrentPipelineState->OM.UAVStartSlot, UAVStartSlot); } - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(SET_RTARGET_AND_UAVS); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_OMSetRenderTargetsAndUnorderedAccessViews(NumRTVs, ppRenderTargetViews, + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::OMSetRenderTargetsAndUnorderedAccessViews); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_OMSetRenderTargetsAndUnorderedAccessViews(GET_SERIALISER, NumRTVs, ppRenderTargetViews, pDepthStencilView, UAVStartSlot, NumUAVs, ppUnorderedAccessViews, pUAVInitialCounts); @@ -3422,18 +3131,23 @@ void WrappedID3D11DeviceContext::OMSetRenderTargetsAndUnorderedAccessViews( ppUnorderedAccessViews && NumUAVs != D3D11_KEEP_UNORDERED_ACCESS_VIEWS && i < NumUAVs; i++) UAVs[i] = ppUnorderedAccessViews[i]; - if(NumRTVs != D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL) - { - ID3D11UnorderedAccessView **srcUAVs = - NumUAVs != D3D11_KEEP_UNORDERED_ACCESS_VIEWS ? UAVs : m_CurrentPipelineState->OM.UAVs; + const bool ModifyRTVs = NumRTVs != D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL; + const bool ModifyUAVs = NumUAVs != D3D11_KEEP_UNORDERED_ACCESS_VIEWS; - if(m_CurrentPipelineState->ValidOutputMerger(RTs, pDepthStencilView, srcUAVs)) + if(ModifyRTVs) + { + ID3D11UnorderedAccessView **srcUAVs = ModifyUAVs ? UAVs : m_CurrentPipelineState->OM.UAVs; + UINT srcUAVcount = ModifyUAVs ? NumUAVs : D3D11_1_UAV_SLOT_COUNT; + + if(m_CurrentPipelineState->ValidOutputMerger(ppRenderTargetViews, NumRTVs, pDepthStencilView, + srcUAVs, srcUAVcount)) { m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->OM.RenderTargets, RTs, 0, D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT); m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->OM.DepthView, pDepthStencilView); } - else if(m_State >= WRITING) + + if(IsCaptureMode(m_State)) { // make sure to mark resources referenced if the OM state is invalid, so they aren't // eliminated from the @@ -3455,14 +3169,16 @@ void WrappedID3D11DeviceContext::OMSetRenderTargetsAndUnorderedAccessViews( } } - if(NumUAVs != D3D11_KEEP_UNORDERED_ACCESS_VIEWS) + if(ModifyUAVs) { bool valid = false; - if(NumRTVs != D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL) - valid = m_CurrentPipelineState->ValidOutputMerger(RTs, pDepthStencilView, UAVs); + if(ModifyRTVs) + valid = + m_CurrentPipelineState->ValidOutputMerger(RTs, NumRTVs, pDepthStencilView, UAVs, NumUAVs); else - valid = m_CurrentPipelineState->ValidOutputMerger(m_CurrentPipelineState->OM.RenderTargets, - m_CurrentPipelineState->OM.DepthView, UAVs); + valid = m_CurrentPipelineState->ValidOutputMerger( + m_CurrentPipelineState->OM.RenderTargets, D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, + m_CurrentPipelineState->OM.DepthView, UAVs, NumUAVs); if(valid) { @@ -3490,14 +3206,14 @@ void WrappedID3D11DeviceContext::OMSetRenderTargetsAndUnorderedAccessViews( ppRenderTargetViews && NumRTVs != D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL && i < NumRTVs; i++) { - if(ppRenderTargetViews[i] && m_State >= WRITING) + if(ppRenderTargetViews[i] && IsCaptureMode(m_State)) { // technically this isn't dirty until the draw call, but let's be conservative // 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) + if(IsBackgroundCapturing(m_State)) MarkDirtyResource(GetViewResourceResID(ppRenderTargetViews[i])); - else if(m_State == WRITING_CAPFRAME) + else if(IsActiveCapturing(m_State)) m_MissingTracks.insert(GetViewResourceResID(ppRenderTargetViews[i])); } @@ -3507,22 +3223,22 @@ void WrappedID3D11DeviceContext::OMSetRenderTargetsAndUnorderedAccessViews( for(UINT i = 0; ppUnorderedAccessViews && NumUAVs != D3D11_KEEP_UNORDERED_ACCESS_VIEWS && i < NumUAVs; i++) { - if(ppUnorderedAccessViews[i] && m_State >= WRITING) + if(ppUnorderedAccessViews[i] && IsCaptureMode(m_State)) { - if(m_State == WRITING_IDLE) + if(IsBackgroundCapturing(m_State)) MarkDirtyResource(GetViewResourceResID(ppUnorderedAccessViews[i])); - else if(m_State == WRITING_CAPFRAME) + else if(IsActiveCapturing(m_State)) m_MissingTracks.insert(GetViewResourceResID(ppUnorderedAccessViews[i])); } UAVs[i] = UNWRAP(WrappedID3D11UnorderedAccessView1, ppUnorderedAccessViews[i]); } - if(pDepthStencilView && m_State >= WRITING) + if(pDepthStencilView && IsCaptureMode(m_State)) { - if(m_State == WRITING_IDLE) + if(IsBackgroundCapturing(m_State)) MarkDirtyResource(GetViewResourceResID(pDepthStencilView)); - else if(m_State == WRITING_CAPFRAME) + else if(IsActiveCapturing(m_State)) m_MissingTracks.insert(GetViewResourceResID(pDepthStencilView)); } @@ -3535,47 +3251,30 @@ void WrappedID3D11DeviceContext::OMSetRenderTargetsAndUnorderedAccessViews( VerifyState(); } -bool WrappedID3D11DeviceContext::Serialise_OMSetBlendState(ID3D11BlendState *pBlendState, - const FLOAT BlendFactor_[4], - UINT SampleMask_) +template +bool WrappedID3D11DeviceContext::Serialise_OMSetBlendState(SerialiserType &ser, + ID3D11BlendState *pBlendState, + const FLOAT BlendFactor[4], + UINT SampleMask) { - SERIALISE_ELEMENT(ResourceId, State, GetIDForResource(pBlendState)); + SERIALISE_ELEMENT(pBlendState); + SERIALISE_ELEMENT_ARRAY(BlendFactor, FIXED_COUNT(4)); + SERIALISE_ELEMENT(SampleMask); - float BlendFactor[4] = {0}; - - if(m_State >= WRITING) + if(IsReplayingAndReading()) { - if((const FLOAT *)BlendFactor_ == NULL) - { - BlendFactor[0] = BlendFactor[1] = BlendFactor[2] = BlendFactor[3] = 1.0f; - } - else - { - memcpy(BlendFactor, BlendFactor_, sizeof(float) * 4); - } - } + FLOAT DefaultBlendFactor[4] = {1.0f, 1.0f, 1.0f, 1.0f}; + const FLOAT *SafeBlendFactor = BlendFactor ? BlendFactor : DefaultBlendFactor; - m_pSerialiser->SerialisePODArray<4>("BlendFactor", BlendFactor); - - SERIALISE_ELEMENT(uint32_t, SampleMask, SampleMask_); - - if(m_State <= EXECUTING) - { - ID3D11DeviceChild *live = NULL; - if(m_pDevice->GetResourceManager()->HasLiveResource(State)) - live = m_pDevice->GetResourceManager()->GetLiveResource(State); - - if(m_State == READING) - RecordBlendStats((ID3D11BlendState *)live, BlendFactor, SampleMask); + if(IsLoading(m_State)) + RecordBlendStats(pBlendState, SafeBlendFactor, SampleMask); { - WrappedID3D11BlendState1 *state = (WrappedID3D11BlendState1 *)live; - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->OM.BlendState, - (ID3D11BlendState *)state); - m_pRealContext->OMSetBlendState(UNWRAP(WrappedID3D11BlendState1, state), BlendFactor, + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->OM.BlendState, pBlendState); + m_pRealContext->OMSetBlendState(UNWRAP(WrappedID3D11BlendState1, pBlendState), BlendFactor, SampleMask); } - m_CurrentPipelineState->Change(m_CurrentPipelineState->OM.BlendFactor, BlendFactor, 0, 4); + m_CurrentPipelineState->Change(m_CurrentPipelineState->OM.BlendFactor, SafeBlendFactor, 0, 4); m_CurrentPipelineState->Change(m_CurrentPipelineState->OM.SampleMask, SampleMask); VerifyState(); } @@ -3590,11 +3289,12 @@ void WrappedID3D11DeviceContext::OMSetBlendState(ID3D11BlendState *pBlendState, m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(SET_BLEND); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_OMSetBlendState(pBlendState, BlendFactor, SampleMask); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::OMSetBlendState); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_OMSetBlendState(GET_SERIALISER, pBlendState, BlendFactor, SampleMask); m_ContextRecord->AddChunk(scope.Get()); } @@ -3614,20 +3314,16 @@ void WrappedID3D11DeviceContext::OMSetBlendState(ID3D11BlendState *pBlendState, VerifyState(); } +template bool WrappedID3D11DeviceContext::Serialise_OMSetDepthStencilState( - ID3D11DepthStencilState *pDepthStencilState, UINT StencilRef_) + SerialiserType &ser, ID3D11DepthStencilState *pDepthStencilState, UINT StencilRef) { - SERIALISE_ELEMENT(ResourceId, State, GetIDForResource(pDepthStencilState)); - SERIALISE_ELEMENT(uint32_t, StencilRef, StencilRef_ & 0xff); + SERIALISE_ELEMENT(pDepthStencilState); + SERIALISE_ELEMENT(StencilRef); - if(m_State <= EXECUTING) + if(IsReplayingAndReading()) { - pDepthStencilState = NULL; - if(m_pDevice->GetResourceManager()->HasLiveResource(State)) - pDepthStencilState = - (ID3D11DepthStencilState *)m_pDevice->GetResourceManager()->GetLiveResource(State); - - if(m_State == READING) + if(IsLoading(m_State)) RecordDepthStencilStats(pDepthStencilState, StencilRef); m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->OM.DepthStencilState, @@ -3648,11 +3344,12 @@ void WrappedID3D11DeviceContext::OMSetDepthStencilState(ID3D11DepthStencilState m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(SET_DEPTHSTENCIL); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_OMSetDepthStencilState(pDepthStencilState, StencilRef); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::OMSetDepthStencilState); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_OMSetDepthStencilState(GET_SERIALISER, pDepthStencilState, StencilRef); m_ContextRecord->AddChunk(scope.Get()); } @@ -3669,124 +3366,73 @@ void WrappedID3D11DeviceContext::OMSetDepthStencilState(ID3D11DepthStencilState #pragma region Draw -void WrappedID3D11DeviceContext::Serialise_DebugMessages() +template +void WrappedID3D11DeviceContext::Serialise_DebugMessages(SerialiserType &ser) { - SCOPED_SERIALISE_CONTEXT(DEBUG_MESSAGES); - - vector debugMessages; + std::vector DebugMessages; m_EmptyCommandList = false; // only grab debug messages for the immediate context, without serialising all // API use there's no way to find out which messages come from which context :(. - if(m_State == WRITING_CAPFRAME && GetType() == D3D11_DEVICE_CONTEXT_IMMEDIATE) + if(ser.IsWriting() && IsActiveCapturing(m_State) && GetType() == D3D11_DEVICE_CONTEXT_IMMEDIATE) { - debugMessages = m_pDevice->GetDebugMessages(); + DebugMessages = m_pDevice->GetDebugMessages(); } - SERIALISE_ELEMENT(bool, HasCallstack, - RenderDoc::Inst().GetCaptureOptions().CaptureCallstacksOnlyDraws != 0); + SERIALISE_ELEMENT(DebugMessages); - if(HasCallstack) + // hide empty sets of messages. + if(ser.IsReading() && DebugMessages.empty()) + ser.Hidden(); + + if(ser.IsReading() && IsLoading(m_State)) { - if(m_State >= WRITING) + for(DebugMessage &msg : DebugMessages) { - 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; - } - else - { - size_t numLevels = 0; - uint64_t *stack = NULL; - - m_pSerialiser->SerialisePODArray("callstack", stack, numLevels); - - m_pSerialiser->SetCallstack(stack, numLevels); - - SAFE_DELETE_ARRAY(stack); - } - } - - SERIALISE_ELEMENT(uint32_t, NumMessages, (uint32_t)debugMessages.size()); - - for(uint32_t i = 0; i < NumMessages; i++) - { - ScopedContext msgscope(m_pSerialiser, "DebugMessage", "DebugMessage", 0, false); - - string desc; - if(m_State >= WRITING) - desc = debugMessages[i].description; - - SERIALISE_ELEMENT(MessageCategory, Category, debugMessages[i].category); - SERIALISE_ELEMENT(MessageSeverity, Severity, debugMessages[i].severity); - SERIALISE_ELEMENT(uint32_t, ID, debugMessages[i].messageID); - SERIALISE_ELEMENT(string, Description, desc); - - if(m_State == READING) - { - DebugMessage msg; msg.eventID = m_CurEventID; - msg.source = MessageSource::API; - msg.category = Category; - msg.severity = Severity; - msg.messageID = ID; - msg.description = Description; - m_pDevice->AddDebugMessage(msg); } } } -bool WrappedID3D11DeviceContext::Serialise_DrawIndexedInstanced(UINT IndexCountPerInstance_, - UINT InstanceCount_, - UINT StartIndexLocation_, - INT BaseVertexLocation_, - UINT StartInstanceLocation_) +template +bool WrappedID3D11DeviceContext::Serialise_DrawIndexedInstanced( + SerialiserType &ser, UINT IndexCountPerInstance, UINT InstanceCount, UINT StartIndexLocation, + INT BaseVertexLocation, UINT StartInstanceLocation) { - SERIALISE_ELEMENT(uint32_t, IndexCountPerInstance, IndexCountPerInstance_); - SERIALISE_ELEMENT(uint32_t, InstanceCount, InstanceCount_); - SERIALISE_ELEMENT(uint32_t, StartIndexLocation, StartIndexLocation_); - SERIALISE_ELEMENT(int32_t, BaseVertexLocation, BaseVertexLocation_); - SERIALISE_ELEMENT(uint32_t, StartInstanceLocation, StartInstanceLocation_); + SERIALISE_ELEMENT(IndexCountPerInstance); + SERIALISE_ELEMENT(InstanceCount); + SERIALISE_ELEMENT(StartIndexLocation); + SERIALISE_ELEMENT(BaseVertexLocation); + SERIALISE_ELEMENT(StartInstanceLocation); - if(m_State <= EXECUTING) + Serialise_DebugMessages(GET_SERIALISER); + + if(IsReplayingAndReading()) { - if(m_State == READING) - RecordDrawStats(true, false, InstanceCount); - m_pRealContext->DrawIndexedInstanced(IndexCountPerInstance, InstanceCount, StartIndexLocation, BaseVertexLocation, StartInstanceLocation); - } - const string desc = m_pSerialiser->GetDebugStr(); + if(IsLoading(m_State)) + { + RecordDrawStats(true, false, InstanceCount); - Serialise_DebugMessages(); + AddEvent(); - if(m_State == READING) - { - AddEvent(desc); - string name = - "DrawIndexedInstanced(" + ToStr(IndexCountPerInstance) + ", " + ToStr(InstanceCount) + ")"; + DrawcallDescription draw; + draw.name = + StringFormat::Fmt("DrawIndexedInstanced(%u, %u)", IndexCountPerInstance, InstanceCount); + draw.numIndices = IndexCountPerInstance; + draw.numInstances = InstanceCount; + draw.indexOffset = StartIndexLocation; + draw.baseVertex = BaseVertexLocation; + draw.instanceOffset = StartInstanceLocation; - DrawcallDescription draw; - draw.name = name; - draw.numIndices = IndexCountPerInstance; - draw.numInstances = InstanceCount; - draw.indexOffset = StartIndexLocation; - draw.baseVertex = BaseVertexLocation; - draw.instanceOffset = StartInstanceLocation; + draw.flags |= DrawFlags::Drawcall | DrawFlags::Instanced | DrawFlags::UseIBuffer; - draw.flags |= DrawFlags::Drawcall | DrawFlags::Instanced | DrawFlags::UseIBuffer; - - AddDrawcall(draw, true); + AddDrawcall(draw, true); + } } return true; @@ -3803,12 +3449,14 @@ void WrappedID3D11DeviceContext::DrawIndexedInstanced(UINT IndexCountPerInstance m_pRealContext->DrawIndexedInstanced(IndexCountPerInstance, InstanceCount, StartIndexLocation, BaseVertexLocation, StartInstanceLocation); - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(DRAW_INDEXED_INST); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_DrawIndexedInstanced(IndexCountPerInstance, InstanceCount, StartIndexLocation, - BaseVertexLocation, StartInstanceLocation); + USE_SCRATCH_SERIALISER(); + GET_SERIALISER.SetDrawChunk(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::DrawIndexedInstanced); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_DrawIndexedInstanced(GET_SERIALISER, IndexCountPerInstance, InstanceCount, + StartIndexLocation, BaseVertexLocation, StartInstanceLocation); m_ContextRecord->AddChunk(scope.Get()); @@ -3816,45 +3464,41 @@ void WrappedID3D11DeviceContext::DrawIndexedInstanced(UINT IndexCountPerInstance } } -bool WrappedID3D11DeviceContext::Serialise_DrawInstanced(UINT VertexCountPerInstance_, - UINT InstanceCount_, - UINT StartVertexLocation_, - UINT StartInstanceLocation_) +template +bool WrappedID3D11DeviceContext::Serialise_DrawInstanced(SerialiserType &ser, + UINT VertexCountPerInstance, + UINT InstanceCount, UINT StartVertexLocation, + UINT StartInstanceLocation) { - SERIALISE_ELEMENT(uint32_t, VertexCountPerInstance, VertexCountPerInstance_); - SERIALISE_ELEMENT(uint32_t, InstanceCount, InstanceCount_); - SERIALISE_ELEMENT(uint32_t, StartVertexLocation, StartVertexLocation_); - SERIALISE_ELEMENT(uint32_t, StartInstanceLocation, StartInstanceLocation_); + SERIALISE_ELEMENT(VertexCountPerInstance); + SERIALISE_ELEMENT(InstanceCount); + SERIALISE_ELEMENT(StartVertexLocation); + SERIALISE_ELEMENT(StartInstanceLocation); - if(m_State <= EXECUTING) + Serialise_DebugMessages(GET_SERIALISER); + + if(IsReplayingAndReading()) { - if(m_State == READING) - RecordDrawStats(true, false, InstanceCount); - m_pRealContext->DrawInstanced(VertexCountPerInstance, InstanceCount, StartVertexLocation, StartInstanceLocation); - } - const string desc = m_pSerialiser->GetDebugStr(); + if(IsLoading(m_State)) + { + RecordDrawStats(true, false, InstanceCount); - Serialise_DebugMessages(); + AddEvent(); - if(m_State == READING) - { - AddEvent(desc); - string name = - "DrawInstanced(" + ToStr(VertexCountPerInstance) + ", " + ToStr(InstanceCount) + ")"; + DrawcallDescription draw; + draw.name = StringFormat::Fmt("DrawInstanced(%u, %u)", VertexCountPerInstance, InstanceCount); + draw.numIndices = VertexCountPerInstance; + draw.numInstances = InstanceCount; + draw.vertexOffset = StartVertexLocation; + draw.instanceOffset = StartInstanceLocation; - DrawcallDescription draw; - draw.name = name; - draw.numIndices = VertexCountPerInstance; - draw.numInstances = InstanceCount; - draw.vertexOffset = StartVertexLocation; - draw.instanceOffset = StartInstanceLocation; + draw.flags |= DrawFlags::Drawcall | DrawFlags::Instanced; - draw.flags |= DrawFlags::Drawcall | DrawFlags::Instanced; - - AddDrawcall(draw, true); + AddDrawcall(draw, true); + } } return true; @@ -3870,12 +3514,14 @@ void WrappedID3D11DeviceContext::DrawInstanced(UINT VertexCountPerInstance, UINT m_pRealContext->DrawInstanced(VertexCountPerInstance, InstanceCount, StartVertexLocation, StartInstanceLocation); - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(DRAW_INST); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_DrawInstanced(VertexCountPerInstance, InstanceCount, StartVertexLocation, - StartInstanceLocation); + USE_SCRATCH_SERIALISER(); + GET_SERIALISER.SetDrawChunk(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::DrawInstanced); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_DrawInstanced(GET_SERIALISER, VertexCountPerInstance, InstanceCount, + StartVertexLocation, StartInstanceLocation); m_ContextRecord->AddChunk(scope.Get()); @@ -3883,39 +3529,37 @@ void WrappedID3D11DeviceContext::DrawInstanced(UINT VertexCountPerInstance, UINT } } -bool WrappedID3D11DeviceContext::Serialise_DrawIndexed(UINT IndexCount_, UINT StartIndexLocation_, - INT BaseVertexLocation_) +template +bool WrappedID3D11DeviceContext::Serialise_DrawIndexed(SerialiserType &ser, UINT IndexCount, + UINT StartIndexLocation, + INT BaseVertexLocation) { - SERIALISE_ELEMENT(uint32_t, IndexCount, IndexCount_); - SERIALISE_ELEMENT(uint32_t, StartIndexLocation, StartIndexLocation_); - SERIALISE_ELEMENT(int32_t, BaseVertexLocation, BaseVertexLocation_); + SERIALISE_ELEMENT(IndexCount); + SERIALISE_ELEMENT(StartIndexLocation); + SERIALISE_ELEMENT(BaseVertexLocation); - if(m_State <= EXECUTING) + Serialise_DebugMessages(GET_SERIALISER); + + if(IsReplayingAndReading()) { - if(m_State == READING) + m_pRealContext->DrawIndexed(IndexCount, StartIndexLocation, BaseVertexLocation); + + if(IsLoading(m_State)) + { RecordDrawStats(false, false, 1); - m_pRealContext->DrawIndexed(IndexCount, StartIndexLocation, BaseVertexLocation); - } + AddEvent(); - const string desc = m_pSerialiser->GetDebugStr(); + DrawcallDescription draw; + draw.name = StringFormat::Fmt("DrawIndexed(%u)", IndexCount); + draw.numIndices = IndexCount; + draw.baseVertex = BaseVertexLocation; + draw.indexOffset = StartIndexLocation; - Serialise_DebugMessages(); + draw.flags |= DrawFlags::Drawcall | DrawFlags::UseIBuffer; - if(m_State == READING) - { - AddEvent(desc); - string name = "DrawIndexed(" + ToStr(IndexCount) + ")"; - - DrawcallDescription draw; - draw.name = name; - draw.numIndices = IndexCount; - draw.baseVertex = BaseVertexLocation; - draw.indexOffset = StartIndexLocation; - - draw.flags |= DrawFlags::Drawcall | DrawFlags::UseIBuffer; - - AddDrawcall(draw, true); + AddDrawcall(draw, true); + } } return true; @@ -3930,11 +3574,13 @@ void WrappedID3D11DeviceContext::DrawIndexed(UINT IndexCount, UINT StartIndexLoc m_pRealContext->DrawIndexed(IndexCount, StartIndexLocation, BaseVertexLocation); - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_SMALL_CONTEXT(DRAW_INDEXED); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_DrawIndexed(IndexCount, StartIndexLocation, BaseVertexLocation); + USE_SCRATCH_SERIALISER(); + GET_SERIALISER.SetDrawChunk(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::DrawIndexed); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_DrawIndexed(GET_SERIALISER, IndexCount, StartIndexLocation, BaseVertexLocation); m_ContextRecord->AddChunk(scope.Get()); @@ -3942,36 +3588,34 @@ void WrappedID3D11DeviceContext::DrawIndexed(UINT IndexCount, UINT StartIndexLoc } } -bool WrappedID3D11DeviceContext::Serialise_Draw(UINT VertexCount_, UINT StartVertexLocation_) +template +bool WrappedID3D11DeviceContext::Serialise_Draw(SerialiserType &ser, UINT VertexCount, + UINT StartVertexLocation) { - SERIALISE_ELEMENT(uint32_t, VertexCount, VertexCount_); - SERIALISE_ELEMENT(uint32_t, StartVertexLocation, StartVertexLocation_); + SERIALISE_ELEMENT(VertexCount); + SERIALISE_ELEMENT(StartVertexLocation); - if(m_State <= EXECUTING) + Serialise_DebugMessages(GET_SERIALISER); + + if(IsReplayingAndReading()) { - if(m_State == READING) + m_pRealContext->Draw(VertexCount, StartVertexLocation); + + if(IsLoading(m_State)) + { RecordDrawStats(false, false, 1); - m_pRealContext->Draw(VertexCount, StartVertexLocation); - } + AddEvent(); - const string desc = m_pSerialiser->GetDebugStr(); + DrawcallDescription draw; + draw.name = StringFormat::Fmt("Draw(%u)", VertexCount); + draw.numIndices = VertexCount; + draw.vertexOffset = StartVertexLocation; - Serialise_DebugMessages(); + draw.flags |= DrawFlags::Drawcall; - if(m_State == READING) - { - AddEvent(desc); - string name = "Draw(" + ToStr(VertexCount) + ")"; - - DrawcallDescription draw; - draw.name = name; - draw.numIndices = VertexCount; - draw.vertexOffset = StartVertexLocation; - - draw.flags |= DrawFlags::Drawcall; - - AddDrawcall(draw, true); + AddDrawcall(draw, true); + } } return true; @@ -3985,11 +3629,13 @@ void WrappedID3D11DeviceContext::Draw(UINT VertexCount, UINT StartVertexLocation m_pRealContext->Draw(VertexCount, StartVertexLocation); - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(DRAW); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_Draw(VertexCount, StartVertexLocation); + USE_SCRATCH_SERIALISER(); + GET_SERIALISER.SetDrawChunk(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::Draw); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_Draw(GET_SERIALISER, VertexCount, StartVertexLocation); m_ContextRecord->AddChunk(scope.Get()); @@ -3997,19 +3643,21 @@ void WrappedID3D11DeviceContext::Draw(UINT VertexCount, UINT StartVertexLocation } } -bool WrappedID3D11DeviceContext::Serialise_DrawAuto() +template +bool WrappedID3D11DeviceContext::Serialise_DrawAuto(SerialiserType &ser) { + Serialise_DebugMessages(GET_SERIALISER); + uint64_t numVerts = 0; - if(m_State <= EXECUTING) + if(IsReplayingAndReading()) { - if(m_State == READING) - RecordDrawStats(false, false, 1); - // spec says that only the first vertex buffer is used if(m_CurrentPipelineState->IA.VBs[0] == NULL) { - RDCERR("DrawAuto() with VB 0 set to NULL!"); + m_pDevice->AddDebugMessage(MessageCategory::Execution, MessageSeverity::High, + MessageSource::IncorrectAPIUse, + "DrawAuto() with VB 0 set to NULL!"); } else { @@ -4045,6 +3693,8 @@ bool WrappedID3D11DeviceContext::Serialise_DrawAuto() } else { + // otherwise use the cached value from the previous frame. + if(m_CurrentPipelineState->IA.Topo == D3D11_PRIMITIVE_TOPOLOGY_POINTLIST) numVerts = data.numPrims; else if(m_CurrentPipelineState->IA.Topo == D3D11_PRIMITIVE_TOPOLOGY_LINELIST) @@ -4055,27 +3705,24 @@ bool WrappedID3D11DeviceContext::Serialise_DrawAuto() m_pRealContext->Draw((UINT)numVerts, 0); } } - } - const string desc = m_pSerialiser->GetDebugStr(); + if(IsLoading(m_State)) + { + RecordDrawStats(false, false, 1); - Serialise_DebugMessages(); + AddEvent(); - if(m_State == READING) - { - AddEvent(desc); - string name = "DrawAuto(<" + ToStr(numVerts) + ">)"; + DrawcallDescription draw; + draw.name = StringFormat::Fmt("DrawAuto(<%u>)", numVerts); + draw.flags |= DrawFlags::Drawcall | DrawFlags::Auto; + draw.numIndices = (uint32_t)numVerts; + draw.vertexOffset = 0; + draw.indexOffset = 0; + draw.instanceOffset = 0; + draw.numInstances = 1; - DrawcallDescription draw; - draw.name = name; - draw.flags |= DrawFlags::Drawcall | DrawFlags::Auto; - draw.numIndices = (uint32_t)numVerts; - draw.vertexOffset = 0; - draw.indexOffset = 0; - draw.instanceOffset = 0; - draw.numInstances = 1; - - AddDrawcall(draw, true); + AddDrawcall(draw, true); + } } return true; @@ -4089,11 +3736,13 @@ void WrappedID3D11DeviceContext::DrawAuto() m_pRealContext->DrawAuto(); - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(DRAW_AUTO); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_DrawAuto(); + USE_SCRATCH_SERIALISER(); + GET_SERIALISER.SetDrawChunk(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::DrawAuto); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_DrawAuto(GET_SERIALISER); m_ContextRecord->AddChunk(scope.Get()); @@ -4101,100 +3750,99 @@ void WrappedID3D11DeviceContext::DrawAuto() } } -bool WrappedID3D11DeviceContext::Serialise_DrawIndexedInstancedIndirect(ID3D11Buffer *pBufferForArgs, - UINT AlignedByteOffsetForArgs_) +template +bool WrappedID3D11DeviceContext::Serialise_DrawIndexedInstancedIndirect(SerialiserType &ser, + ID3D11Buffer *pBufferForArgs, + UINT AlignedByteOffsetForArgs) { - SERIALISE_ELEMENT(ResourceId, BufferForArgs, GetIDForResource(pBufferForArgs)); - SERIALISE_ELEMENT(uint32_t, AlignedByteOffsetForArgs, AlignedByteOffsetForArgs_); + SERIALISE_ELEMENT(pBufferForArgs); + SERIALISE_ELEMENT(AlignedByteOffsetForArgs); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(BufferForArgs)) + Serialise_DebugMessages(GET_SERIALISER); + + if(IsReplayingAndReading()) { - m_pRealContext->DrawIndexedInstancedIndirect( - UNWRAP(WrappedID3D11Buffer, m_pDevice->GetResourceManager()->GetLiveResource(BufferForArgs)), - AlignedByteOffsetForArgs); - } - - const string desc = m_pSerialiser->GetDebugStr(); - - Serialise_DebugMessages(); - - if(m_State == READING) - { - AddEvent(desc); - - DrawcallDescription draw; - - string name = "DrawIndexedInstancedIndirect(-, -)"; - - if(m_pDevice->GetResourceManager()->HasLiveResource(BufferForArgs)) + if(pBufferForArgs) { - ID3D11Buffer *argBuffer = - (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetLiveResource(BufferForArgs); - - vector argarray; - m_pDevice->GetDebugManager()->GetBufferData(argBuffer, AlignedByteOffsetForArgs, - 5 * sizeof(uint32_t), argarray); - - struct DrawArgs - { - uint32_t IndexCountPerInstance; - uint32_t InstanceCount; - uint32_t StartIndexLocation; - int32_t BaseVertexLocation; - uint32_t StartInstanceLocation; - }; - - if(argarray.size() >= sizeof(DrawArgs)) - { - DrawArgs *args = (DrawArgs *)&argarray[0]; - - draw.numIndices = args->IndexCountPerInstance; - draw.numInstances = args->InstanceCount; - draw.indexOffset = args->StartIndexLocation; - draw.baseVertex = args->BaseVertexLocation; - draw.instanceOffset = args->StartInstanceLocation; - - RecordDrawStats(true, true, draw.numInstances); - - name = "DrawIndexedInstancedIndirect(<" + ToStr(draw.numIndices) + ", " + - ToStr(draw.numInstances) + ">)"; - } - else - { - name = "DrawIndexedInstancedIndirect()"; - D3D11_BUFFER_DESC bufDesc; - - argBuffer->GetDesc(&bufDesc); - - if(AlignedByteOffsetForArgs >= bufDesc.ByteWidth) - { - m_pDevice->AddDebugMessage( - MessageCategory::Execution, MessageSeverity::High, MessageSource::IncorrectAPIUse, - StringFormat::Fmt("Call to DrawIndexedInstancedIndirect with buffer of %u " - "bytes, but byte offset specified is %u bytes.", - bufDesc.ByteWidth, AlignedByteOffsetForArgs)); - } - else if(AlignedByteOffsetForArgs + sizeof(DrawArgs) >= bufDesc.ByteWidth) - { - m_pDevice->AddDebugMessage( - MessageCategory::Execution, MessageSeverity::High, MessageSource::IncorrectAPIUse, - StringFormat::Fmt( - "Call to DrawIndexedInstancedIndirect with buffer of %u " - "bytes at offset of %u bytes, which leaves less than %u bytes for the arguments.", - bufDesc.ByteWidth, AlignedByteOffsetForArgs, sizeof(DrawArgs))); - } - } - - m_ResourceUses[GetIDForResource(argBuffer)].push_back( - EventUsage(m_CurEventID, ResourceUsage::Indirect)); + m_pRealContext->DrawIndexedInstancedIndirect(UNWRAP(WrappedID3D11Buffer, pBufferForArgs), + AlignedByteOffsetForArgs); } - draw.name = name; + if(IsLoading(m_State)) + { + AddEvent(); - draw.flags |= - DrawFlags::Drawcall | DrawFlags::Instanced | DrawFlags::UseIBuffer | DrawFlags::Indirect; + DrawcallDescription draw; - AddDrawcall(draw, true); + std::string name = "DrawIndexedInstancedIndirect(-, -)"; + + if(pBufferForArgs) + { + struct DrawArgs + { + uint32_t IndexCountPerInstance; + uint32_t InstanceCount; + uint32_t StartIndexLocation; + int32_t BaseVertexLocation; + uint32_t StartInstanceLocation; + }; + + std::vector argarray; + m_pDevice->GetDebugManager()->GetBufferData(pBufferForArgs, AlignedByteOffsetForArgs, + sizeof(DrawArgs), argarray); + + if(argarray.size() >= sizeof(DrawArgs)) + { + DrawArgs *args = (DrawArgs *)&argarray[0]; + + draw.numIndices = args->IndexCountPerInstance; + draw.numInstances = args->InstanceCount; + draw.indexOffset = args->StartIndexLocation; + draw.baseVertex = args->BaseVertexLocation; + draw.instanceOffset = args->StartInstanceLocation; + + RecordDrawStats(true, true, draw.numInstances); + + name = StringFormat::Fmt("DrawIndexedInstancedIndirect(<%u, %u>)", draw.numIndices, + draw.numInstances); + } + else + { + name = "DrawIndexedInstancedIndirect()"; + D3D11_BUFFER_DESC bufDesc; + + pBufferForArgs->GetDesc(&bufDesc); + + if(AlignedByteOffsetForArgs >= bufDesc.ByteWidth) + { + m_pDevice->AddDebugMessage( + MessageCategory::Execution, MessageSeverity::High, MessageSource::IncorrectAPIUse, + StringFormat::Fmt("Call to DrawIndexedInstancedIndirect with buffer of %u " + "bytes, but byte offset specified is %u bytes.", + bufDesc.ByteWidth, AlignedByteOffsetForArgs)); + } + else if(AlignedByteOffsetForArgs + sizeof(DrawArgs) >= bufDesc.ByteWidth) + { + m_pDevice->AddDebugMessage( + MessageCategory::Execution, MessageSeverity::High, MessageSource::IncorrectAPIUse, + StringFormat::Fmt("Call to DrawIndexedInstancedIndirect with buffer of %u " + "bytes at offset of %u bytes, which leaves less than %u bytes " + "for the arguments.", + bufDesc.ByteWidth, AlignedByteOffsetForArgs, sizeof(DrawArgs))); + } + } + + m_ResourceUses[GetIDForResource(pBufferForArgs)].push_back( + EventUsage(m_CurEventID, ResourceUsage::Indirect)); + } + + draw.name = name; + + draw.flags |= + DrawFlags::Drawcall | DrawFlags::Instanced | DrawFlags::UseIBuffer | DrawFlags::Indirect; + + AddDrawcall(draw, true); + } } return true; @@ -4210,101 +3858,113 @@ void WrappedID3D11DeviceContext::DrawIndexedInstancedIndirect(ID3D11Buffer *pBuf m_pRealContext->DrawIndexedInstancedIndirect(UNWRAP(WrappedID3D11Buffer, pBufferForArgs), AlignedByteOffsetForArgs); - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(DRAW_INDEXED_INST_INDIRECT); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_DrawIndexedInstancedIndirect(pBufferForArgs, AlignedByteOffsetForArgs); + USE_SCRATCH_SERIALISER(); + GET_SERIALISER.SetDrawChunk(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::DrawIndexedInstancedIndirect); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_DrawIndexedInstancedIndirect(GET_SERIALISER, pBufferForArgs, AlignedByteOffsetForArgs); m_ContextRecord->AddChunk(scope.Get()); m_CurrentPipelineState->MarkReferenced(this, false); } - if(pBufferForArgs && m_State >= WRITING_CAPFRAME) + if(pBufferForArgs && IsActiveCapturing(m_State)) MarkResourceReferenced(GetIDForResource(pBufferForArgs), eFrameRef_Read); } -bool WrappedID3D11DeviceContext::Serialise_DrawInstancedIndirect(ID3D11Buffer *pBufferForArgs, - UINT AlignedByteOffsetForArgs_) +template +bool WrappedID3D11DeviceContext::Serialise_DrawInstancedIndirect(SerialiserType &ser, + ID3D11Buffer *pBufferForArgs, + UINT AlignedByteOffsetForArgs) { - SERIALISE_ELEMENT(ResourceId, BufferForArgs, GetIDForResource(pBufferForArgs)); - SERIALISE_ELEMENT(uint32_t, AlignedByteOffsetForArgs, AlignedByteOffsetForArgs_); + SERIALISE_ELEMENT(pBufferForArgs); + SERIALISE_ELEMENT(AlignedByteOffsetForArgs); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(BufferForArgs)) + Serialise_DebugMessages(GET_SERIALISER); + + if(IsReplayingAndReading()) { - m_pRealContext->DrawInstancedIndirect( - UNWRAP(WrappedID3D11Buffer, m_pDevice->GetResourceManager()->GetLiveResource(BufferForArgs)), - AlignedByteOffsetForArgs); - } - - const string desc = m_pSerialiser->GetDebugStr(); - - Serialise_DebugMessages(); - - if(m_State == READING) - { - AddEvent(desc); - - DrawcallDescription draw; - - string name = "DrawInstancedIndirect(-, -)"; - if(m_pDevice->GetResourceManager()->HasLiveResource(BufferForArgs)) + if(pBufferForArgs) { - ID3D11Buffer *argBuffer = - (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetLiveResource(BufferForArgs); - - vector args; - m_pDevice->GetDebugManager()->GetBufferData(argBuffer, AlignedByteOffsetForArgs, - 4 * sizeof(uint32_t), args); - uint32_t *uargs = (uint32_t *)&args[0]; - - if(args.size() >= sizeof(uint32_t) * 4) - { - draw.numIndices = uargs[0]; - draw.numInstances = uargs[1]; - draw.vertexOffset = uargs[2]; - draw.instanceOffset = uargs[3]; - - name = "DrawInstancedIndirect(<" + ToStr(uargs[0]) + ", " + ToStr(uargs[1]) + ">)"; - - RecordDrawStats(true, true, draw.numInstances); - } - else - { - name = "DrawInstancedIndirect()"; - D3D11_BUFFER_DESC bufDesc; - - argBuffer->GetDesc(&bufDesc); - - if(AlignedByteOffsetForArgs >= bufDesc.ByteWidth) - { - m_pDevice->AddDebugMessage( - MessageCategory::Execution, MessageSeverity::High, MessageSource::IncorrectAPIUse, - StringFormat::Fmt("Call to DrawInstancedIndirect with buffer of %u " - "bytes, but byte offset specified is %u bytes.", - bufDesc.ByteWidth, AlignedByteOffsetForArgs)); - } - else if(AlignedByteOffsetForArgs + sizeof(uint32_t) * 4 >= bufDesc.ByteWidth) - { - m_pDevice->AddDebugMessage( - MessageCategory::Execution, MessageSeverity::High, MessageSource::IncorrectAPIUse, - StringFormat::Fmt( - "Call to DrawInstancedIndirect with buffer of %u " - "bytes at offset of %u bytes, which leaves less than %u bytes for the arguments.", - bufDesc.ByteWidth, AlignedByteOffsetForArgs, sizeof(uint32_t) * 4)); - } - } - - m_ResourceUses[GetIDForResource(argBuffer)].push_back( - EventUsage(m_CurEventID, ResourceUsage::Indirect)); + m_pRealContext->DrawInstancedIndirect(UNWRAP(WrappedID3D11Buffer, pBufferForArgs), + AlignedByteOffsetForArgs); } - draw.name = name; + if(IsLoading(m_State)) + { + AddEvent(); - draw.flags |= DrawFlags::Drawcall | DrawFlags::Instanced | DrawFlags::Indirect; + DrawcallDescription draw; - AddDrawcall(draw, true); + std::string name = "DrawInstancedIndirect(-, -)"; + + if(pBufferForArgs) + { + struct DrawArgs + { + uint32_t VertexCountPerInstance; + uint32_t InstanceCount; + uint32_t StartVertexLocation; + uint32_t StartInstanceLocation; + }; + + std::vector argarray; + m_pDevice->GetDebugManager()->GetBufferData(pBufferForArgs, AlignedByteOffsetForArgs, + sizeof(DrawArgs), argarray); + + if(argarray.size() >= sizeof(DrawArgs)) + { + DrawArgs *args = (DrawArgs *)&argarray[0]; + + draw.numIndices = args->VertexCountPerInstance; + draw.numInstances = args->InstanceCount; + draw.vertexOffset = args->StartVertexLocation; + draw.instanceOffset = args->StartInstanceLocation; + + RecordDrawStats(true, true, draw.numInstances); + + name = StringFormat::Fmt("DrawInstancedIndirect(<%u, %u>)", draw.numIndices, + draw.numInstances); + } + else + { + name = "DrawInstancedIndirect()"; + D3D11_BUFFER_DESC bufDesc; + + pBufferForArgs->GetDesc(&bufDesc); + + if(AlignedByteOffsetForArgs >= bufDesc.ByteWidth) + { + m_pDevice->AddDebugMessage( + MessageCategory::Execution, MessageSeverity::High, MessageSource::IncorrectAPIUse, + StringFormat::Fmt("Call to DrawIndexedInstancedIndirect with buffer of %u " + "bytes, but byte offset specified is %u bytes.", + bufDesc.ByteWidth, AlignedByteOffsetForArgs)); + } + else if(AlignedByteOffsetForArgs + sizeof(DrawArgs) >= bufDesc.ByteWidth) + { + m_pDevice->AddDebugMessage( + MessageCategory::Execution, MessageSeverity::High, MessageSource::IncorrectAPIUse, + StringFormat::Fmt("Call to DrawIndexedInstancedIndirect with buffer of %u " + "bytes at offset of %u bytes, which leaves less than %u bytes " + "for the arguments.", + bufDesc.ByteWidth, AlignedByteOffsetForArgs, sizeof(DrawArgs))); + } + } + + m_ResourceUses[GetIDForResource(pBufferForArgs)].push_back( + EventUsage(m_CurEventID, ResourceUsage::Indirect)); + } + + draw.name = name; + + draw.flags |= DrawFlags::Drawcall | DrawFlags::Instanced | DrawFlags::Indirect; + + AddDrawcall(draw, true); + } } return true; @@ -4320,18 +3980,20 @@ void WrappedID3D11DeviceContext::DrawInstancedIndirect(ID3D11Buffer *pBufferForA m_pRealContext->DrawInstancedIndirect(UNWRAP(WrappedID3D11Buffer, pBufferForArgs), AlignedByteOffsetForArgs); - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(DRAW_INST_INDIRECT); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_DrawInstancedIndirect(pBufferForArgs, AlignedByteOffsetForArgs); + USE_SCRATCH_SERIALISER(); + GET_SERIALISER.SetDrawChunk(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::DrawInstancedIndirect); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_DrawInstancedIndirect(GET_SERIALISER, pBufferForArgs, AlignedByteOffsetForArgs); m_ContextRecord->AddChunk(scope.Get()); m_CurrentPipelineState->MarkReferenced(this, false); } - if(pBufferForArgs && m_State >= WRITING_CAPFRAME) + if(pBufferForArgs && IsActiveCapturing(m_State)) MarkResourceReferenced(GetIDForResource(pBufferForArgs), eFrameRef_Read); } @@ -4438,7 +4100,7 @@ void WrappedID3D11DeviceContext::CSGetShader(ID3D11ComputeShader **ppComputeShad *ppComputeShader = (ID3D11ComputeShader *)m_pDevice->GetResourceManager()->GetWrapper(realShader); SAFE_ADDREF(*ppComputeShader); - RDCASSERT(*ppComputeShader == m_CurrentPipelineState->CS.Shader); + RDCASSERT(*ppComputeShader == m_CurrentPipelineState->CS.Object); } if(ppClassInstances) @@ -4459,45 +4121,34 @@ void WrappedID3D11DeviceContext::CSGetShader(ID3D11ComputeShader **ppComputeShad } } -bool WrappedID3D11DeviceContext::Serialise_CSSetConstantBuffers(UINT StartSlot_, UINT NumBuffers_, +template +bool WrappedID3D11DeviceContext::Serialise_CSSetConstantBuffers(SerialiserType &ser, UINT StartSlot, + UINT NumBuffers, ID3D11Buffer *const *ppConstantBuffers) { - SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); - SERIALISE_ELEMENT(uint32_t, NumBuffers, NumBuffers_); + SERIALISE_ELEMENT(StartSlot); + SERIALISE_ELEMENT_ARRAY(ppConstantBuffers, NumBuffers); - ID3D11Buffer **Buffers = new ID3D11Buffer *[NumBuffers]; - - for(UINT i = 0; i < NumBuffers; i++) + if(IsReplayingAndReading()) { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppConstantBuffers[i])); + if(IsLoading(m_State)) + RecordConstantStats(ShaderStage::Compute, NumBuffers, ppConstantBuffers); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Buffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Buffers[i] = NULL; - } - - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->CS.ConstantBuffers, Buffers, - StartSlot, NumBuffers); + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->CS.ConstantBuffers, + ppConstantBuffers, StartSlot, NumBuffers); m_CurrentPipelineState->Change(m_CurrentPipelineState->CS.CBOffsets, NullCBOffsets, StartSlot, NumBuffers); m_CurrentPipelineState->Change(m_CurrentPipelineState->CS.CBCounts, NullCBCounts, StartSlot, NumBuffers); + ID3D11Buffer *bufs[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {0}; for(UINT i = 0; i < NumBuffers; i++) - Buffers[i] = UNWRAP(WrappedID3D11Buffer, Buffers[i]); + bufs[i] = UNWRAP(WrappedID3D11Buffer, ppConstantBuffers[i]); - if(m_State == READING) - RecordConstantStats(ShaderStage::Compute, NumBuffers, Buffers); - - m_pRealContext->CSSetConstantBuffers(StartSlot, NumBuffers, Buffers); + m_pRealContext->CSSetConstantBuffers(StartSlot, NumBuffers, bufs); VerifyState(); } - SAFE_DELETE_ARRAY(Buffers); - return true; } @@ -4508,11 +4159,12 @@ void WrappedID3D11DeviceContext::CSSetConstantBuffers(UINT StartSlot, UINT NumBu m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(SET_CS_CBUFFERS); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_CSSetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::CSSetConstantBuffers); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_CSSetConstantBuffers(GET_SERIALISER, StartSlot, NumBuffers, ppConstantBuffers); m_ContextRecord->AddChunk(scope.Get()); } @@ -4527,7 +4179,7 @@ void WrappedID3D11DeviceContext::CSSetConstantBuffers(UINT StartSlot, UINT NumBu ID3D11Buffer *bufs[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; for(UINT i = 0; i < NumBuffers; i++) { - if(ppConstantBuffers[i] && m_State >= WRITING_CAPFRAME) + if(ppConstantBuffers[i] && IsActiveCapturing(m_State)) MarkResourceReferenced(GetIDForResource(ppConstantBuffers[i]), eFrameRef_Read); bufs[i] = UNWRAP(WrappedID3D11Buffer, ppConstantBuffers[i]); @@ -4537,41 +4189,30 @@ void WrappedID3D11DeviceContext::CSSetConstantBuffers(UINT StartSlot, UINT NumBu VerifyState(); } +template bool WrappedID3D11DeviceContext::Serialise_CSSetShaderResources( - UINT StartSlot_, UINT NumViews_, ID3D11ShaderResourceView *const *ppShaderResourceViews) + SerialiserType &ser, UINT StartSlot, UINT NumViews, + ID3D11ShaderResourceView *const *ppShaderResourceViews) { - SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); - SERIALISE_ELEMENT(uint32_t, NumViews, NumViews_); + SERIALISE_ELEMENT(StartSlot); + SERIALISE_ELEMENT_ARRAY(ppShaderResourceViews, NumViews); - ID3D11ShaderResourceView **Views = new ID3D11ShaderResourceView *[NumViews]; - - for(UINT i = 0; i < NumViews; i++) + if(IsReplayingAndReading()) { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppShaderResourceViews[i])); + if(IsLoading(m_State)) + RecordResourceStats(ShaderStage::Compute, NumViews, ppShaderResourceViews); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Views[i] = (ID3D11ShaderResourceView *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Views[i] = NULL; - } - - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->CS.SRVs, Views, StartSlot, - NumViews); + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->CS.SRVs, ppShaderResourceViews, + StartSlot, NumViews); + ID3D11ShaderResourceView *SRVs[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; for(UINT i = 0; i < NumViews; i++) - Views[i] = UNWRAP(WrappedID3D11ShaderResourceView1, Views[i]); + SRVs[i] = UNWRAP(WrappedID3D11ShaderResourceView1, ppShaderResourceViews[i]); - if(m_State == READING) - RecordResourceStats(ShaderStage::Compute, NumViews, Views); - - m_pRealContext->CSSetShaderResources(StartSlot, NumViews, Views); + m_pRealContext->CSSetShaderResources(StartSlot, NumViews, SRVs); VerifyState(); } - SAFE_DELETE_ARRAY(Views); - return true; } @@ -4582,11 +4223,12 @@ void WrappedID3D11DeviceContext::CSSetShaderResources( m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(SET_CS_RESOURCES); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_CSSetShaderResources(StartSlot, NumViews, ppShaderResourceViews); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::CSSetShaderResources); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_CSSetShaderResources(GET_SERIALISER, StartSlot, NumViews, ppShaderResourceViews); m_ContextRecord->AddChunk(scope.Get()); } @@ -4597,7 +4239,7 @@ void WrappedID3D11DeviceContext::CSSetShaderResources( ID3D11ShaderResourceView *SRVs[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; for(UINT i = 0; i < NumViews; i++) { - if(ppShaderResourceViews[i] && m_State >= WRITING_CAPFRAME) + if(ppShaderResourceViews[i] && IsActiveCapturing(m_State)) { MarkResourceReferenced(GetIDForResource(ppShaderResourceViews[i]), eFrameRef_Read); MarkResourceReferenced(GetViewResourceResID(ppShaderResourceViews[i]), eFrameRef_Read); @@ -4610,46 +4252,33 @@ void WrappedID3D11DeviceContext::CSSetShaderResources( VerifyState(); } +template bool WrappedID3D11DeviceContext::Serialise_CSSetUnorderedAccessViews( - UINT StartSlot_, UINT NumUAVs_, ID3D11UnorderedAccessView *const *ppUnorderedAccessViews, - const UINT *pUAVInitialCounts) + SerialiserType &ser, UINT StartSlot, UINT NumUAVs, + ID3D11UnorderedAccessView *const *ppUnorderedAccessViews, const UINT *pUAVInitialCounts) { - SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); - SERIALISE_ELEMENT(uint32_t, NumUAVs, NumUAVs_); - SERIALISE_ELEMENT(uint8_t, HasInitialCounts, pUAVInitialCounts != NULL); - SERIALISE_ELEMENT_ARR_OPT(uint32_t, UAVInitialCounts, pUAVInitialCounts, NumUAVs, HasInitialCounts); + SERIALISE_ELEMENT(StartSlot); + SERIALISE_ELEMENT_ARRAY(ppUnorderedAccessViews, NumUAVs); + SERIALISE_ELEMENT_ARRAY(pUAVInitialCounts, NumUAVs); + SERIALISE_ELEMENT(NumUAVs); - ID3D11UnorderedAccessView **UAVs = new ID3D11UnorderedAccessView *[NumUAVs]; - - for(UINT i = 0; i < NumUAVs; i++) + if(IsReplayingAndReading()) { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppUnorderedAccessViews[i])); - - UAVs[i] = NULL; - - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - UAVs[i] = - (WrappedID3D11UnorderedAccessView1 *)m_pDevice->GetResourceManager()->GetLiveResource(id); - } - - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->CSUAVs, UAVs, StartSlot, NumUAVs); + m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->CSUAVs, ppUnorderedAccessViews, + StartSlot, NumUAVs); + ID3D11UnorderedAccessView *UAVs[D3D11_1_UAV_SLOT_COUNT]; for(UINT i = 0; i < NumUAVs; i++) - UAVs[i] = UNWRAP(WrappedID3D11UnorderedAccessView1, UAVs[i]); + UAVs[i] = UNWRAP(WrappedID3D11UnorderedAccessView1, ppUnorderedAccessViews[i]); // #mivance this isn't strictly correct... - if(m_State == READING) + if(IsLoading(m_State)) RecordOutputMergerStats(0, NULL, NULL, StartSlot, NumUAVs, UAVs); - m_pRealContext->CSSetUnorderedAccessViews(StartSlot, NumUAVs, UAVs, UAVInitialCounts); + m_pRealContext->CSSetUnorderedAccessViews(StartSlot, NumUAVs, UAVs, pUAVInitialCounts); VerifyState(); } - SAFE_DELETE_ARRAY(UAVs); - SAFE_DELETE_ARRAY(UAVInitialCounts); - return true; } @@ -4661,11 +4290,12 @@ void WrappedID3D11DeviceContext::CSSetUnorderedAccessViews( m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(SET_CS_UAVS); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_CSSetUnorderedAccessViews(StartSlot, NumUAVs, ppUnorderedAccessViews, + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::CSSetUnorderedAccessViews); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_CSSetUnorderedAccessViews(GET_SERIALISER, StartSlot, NumUAVs, ppUnorderedAccessViews, pUAVInitialCounts); m_ContextRecord->AddChunk(scope.Get()); @@ -4674,15 +4304,21 @@ void WrappedID3D11DeviceContext::CSSetUnorderedAccessViews( m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->CSUAVs, ppUnorderedAccessViews, StartSlot, NumUAVs); - ID3D11UnorderedAccessView *UAVs[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; + ID3D11UnorderedAccessView *UAVs[D3D11_1_UAV_SLOT_COUNT]; for(UINT i = 0; i < NumUAVs; i++) { - if(ppUnorderedAccessViews[i] && m_State >= WRITING) + if(ppUnorderedAccessViews[i] && IsCaptureMode(m_State)) { - if(m_State == WRITING_IDLE) + if(IsBackgroundCapturing(m_State)) + { MarkDirtyResource(GetViewResourceResID(ppUnorderedAccessViews[i])); - else if(m_State == WRITING_CAPFRAME) + } + else if(IsActiveCapturing(m_State)) + { m_MissingTracks.insert(GetViewResourceResID(ppUnorderedAccessViews[i])); + MarkResourceReferenced(GetIDForResource(ppUnorderedAccessViews[i]), eFrameRef_Read); + MarkResourceReferenced(GetViewResourceResID(ppUnorderedAccessViews[i]), eFrameRef_Read); + } } UAVs[i] = UNWRAP(WrappedID3D11UnorderedAccessView1, ppUnorderedAccessViews[i]); @@ -4692,38 +4328,30 @@ void WrappedID3D11DeviceContext::CSSetUnorderedAccessViews( VerifyState(); } -bool WrappedID3D11DeviceContext::Serialise_CSSetSamplers(UINT StartSlot_, UINT NumSamplers_, +template +bool WrappedID3D11DeviceContext::Serialise_CSSetSamplers(SerialiserType &ser, UINT StartSlot, + UINT NumSamplers, ID3D11SamplerState *const *ppSamplers) { - SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); - SERIALISE_ELEMENT(uint32_t, NumSamplers, NumSamplers_); + SERIALISE_ELEMENT(StartSlot); + SERIALISE_ELEMENT_ARRAY(ppSamplers, NumSamplers); - ID3D11SamplerState **Sampler = new ID3D11SamplerState *[NumSamplers]; - - for(UINT i = 0; i < NumSamplers; i++) + if(IsReplayingAndReading()) { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppSamplers[i])); + if(IsLoading(m_State)) + RecordSamplerStats(ShaderStage::Compute, NumSamplers, ppSamplers); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Sampler[i] = (ID3D11SamplerState *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Sampler[i] = NULL; - } - - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->CS.Samplers, Sampler, StartSlot, - NumSamplers); + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->CS.Samplers, ppSamplers, + StartSlot, NumSamplers); + ID3D11SamplerState *samps[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT]; for(UINT i = 0; i < NumSamplers; i++) - Sampler[i] = UNWRAP(WrappedID3D11SamplerState, Sampler[i]); + samps[i] = UNWRAP(WrappedID3D11SamplerState, ppSamplers[i]); - m_pRealContext->CSSetSamplers(StartSlot, NumSamplers, Sampler); + m_pRealContext->CSSetSamplers(StartSlot, NumSamplers, samps); VerifyState(); } - SAFE_DELETE_ARRAY(Sampler); - return true; } @@ -4734,11 +4362,12 @@ void WrappedID3D11DeviceContext::CSSetSamplers(UINT StartSlot, UINT NumSamplers, m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(SET_CS_SAMPLERS); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_CSSetSamplers(StartSlot, NumSamplers, ppSamplers); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::CSSetSamplers); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_CSSetSamplers(GET_SERIALISER, StartSlot, NumSamplers, ppSamplers); m_ContextRecord->AddChunk(scope.Get()); } @@ -4754,49 +4383,35 @@ void WrappedID3D11DeviceContext::CSSetSamplers(UINT StartSlot, UINT NumSamplers, VerifyState(); } -bool WrappedID3D11DeviceContext::Serialise_CSSetShader(ID3D11ComputeShader *pShader, +template +bool WrappedID3D11DeviceContext::Serialise_CSSetShader(SerialiserType &ser, + ID3D11ComputeShader *pShader, ID3D11ClassInstance *const *ppClassInstances, - UINT NumClassInstances_) + UINT NumClassInstances) { - SERIALISE_ELEMENT(ResourceId, Shader, GetIDForResource(pShader)); - SERIALISE_ELEMENT(uint32_t, NumClassInstances, NumClassInstances_); + SERIALISE_ELEMENT(pShader); + SERIALISE_ELEMENT_ARRAY(ppClassInstances, NumClassInstances); - ID3D11ClassInstance **Instances = new ID3D11ClassInstance *[NumClassInstances]; - - for(UINT i = 0; i < NumClassInstances; i++) + if(IsReplayingAndReading()) { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppClassInstances[i])); + if(IsLoading(m_State)) + RecordShaderStats(ShaderStage::Compute, m_CurrentPipelineState->CS.Object, pShader); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Instances[i] = (ID3D11ClassInstance *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Instances[i] = NULL; - } - - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->CS.Instances, Instances, 0, + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->CS.Instances, ppClassInstances, 0, NumClassInstances); m_CurrentPipelineState->Change(m_CurrentPipelineState->CS.NumInstances, NumClassInstances); + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->CS.Object, + (ID3D11DeviceChild *)pShader); + ID3D11ClassInstance *insts[D3D11_SHADER_MAX_INTERFACES] = {0}; for(UINT i = 0; i < NumClassInstances; i++) - Instances[i] = UNWRAP(WrappedID3D11ClassInstance, Instances[i]); + insts[i] = UNWRAP(WrappedID3D11ClassInstance, ppClassInstances[i]); - ID3D11DeviceChild *pSH = NULL; - if(m_pDevice->GetResourceManager()->HasLiveResource(Shader)) - pSH = (ID3D11DeviceChild *)m_pDevice->GetResourceManager()->GetLiveResource(Shader); - - if(m_State == READING) - RecordShaderStats(ShaderStage::Compute, m_CurrentPipelineState->CS.Shader, pSH); - - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->CS.Shader, pSH); - m_pRealContext->CSSetShader(UNWRAP(WrappedID3D11Shader, pSH), Instances, + m_pRealContext->CSSetShader(UNWRAP(WrappedID3D11Shader, pShader), insts, NumClassInstances); VerifyState(); } - SAFE_DELETE_ARRAY(Instances); - return true; } @@ -4808,18 +4423,19 @@ void WrappedID3D11DeviceContext::CSSetShader(ID3D11ComputeShader *pComputeShader m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(SET_CS); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_CSSetShader(pComputeShader, ppClassInstances, NumClassInstances); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::CSSetShader); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_CSSetShader(GET_SERIALISER, pComputeShader, ppClassInstances, NumClassInstances); MarkResourceReferenced(GetIDForResource(pComputeShader), eFrameRef_Read); m_ContextRecord->AddChunk(scope.Get()); } - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->CS.Shader, + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->CS.Object, (ID3D11DeviceChild *)pComputeShader); m_CurrentPipelineState->Change(m_CurrentPipelineState->CS.NumInstances, NumClassInstances); m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->CS.Instances, ppClassInstances, 0, @@ -4837,40 +4453,256 @@ void WrappedID3D11DeviceContext::CSSetShader(ID3D11ComputeShader *pComputeShader #pragma endregion Compute Shader +#pragma region Dispatch + +template +bool WrappedID3D11DeviceContext::Serialise_Dispatch(SerialiserType &ser, UINT ThreadGroupCountX, + UINT ThreadGroupCountY, UINT ThreadGroupCountZ) +{ + SERIALISE_ELEMENT(ThreadGroupCountX); + SERIALISE_ELEMENT(ThreadGroupCountY); + SERIALISE_ELEMENT(ThreadGroupCountZ); + + Serialise_DebugMessages(GET_SERIALISER); + + if(IsReplayingAndReading()) + { + m_pRealContext->Dispatch(ThreadGroupCountX, ThreadGroupCountY, ThreadGroupCountZ); + + if(IsLoading(m_State)) + { + RecordDispatchStats(false); + + AddEvent(); + + DrawcallDescription draw; + draw.name = StringFormat::Fmt("Dispatch(%u, %u, %u)", ThreadGroupCountX, ThreadGroupCountY, + ThreadGroupCountZ); + draw.flags |= DrawFlags::Dispatch; + + draw.dispatchDimension[0] = ThreadGroupCountX; + draw.dispatchDimension[1] = ThreadGroupCountY; + draw.dispatchDimension[2] = ThreadGroupCountZ; + + if(ThreadGroupCountX == 0) + m_pDevice->AddDebugMessage( + MessageCategory::Execution, MessageSeverity::Medium, MessageSource::IncorrectAPIUse, + "Dispatch call has ThreadGroup count X=0. This will do nothing, " + "which is unusual for a non-indirect Dispatch. Did you mean X=1?"); + if(ThreadGroupCountY == 0) + m_pDevice->AddDebugMessage( + MessageCategory::Execution, MessageSeverity::Medium, MessageSource::IncorrectAPIUse, + "Dispatch call has ThreadGroup count Y=0. This will do nothing, " + "which is unusual for a non-indirect Dispatch. Did you mean Y=1?"); + if(ThreadGroupCountZ == 0) + m_pDevice->AddDebugMessage( + MessageCategory::Execution, MessageSeverity::Medium, MessageSource::IncorrectAPIUse, + "Dispatch call has ThreadGroup count Z=0. This will do nothing, " + "which is unusual for a non-indirect Dispatch. Did you mean Z=1?"); + + AddDrawcall(draw, true); + } + } + + return true; +} + +void WrappedID3D11DeviceContext::Dispatch(UINT ThreadGroupCountX, UINT ThreadGroupCountY, + UINT ThreadGroupCountZ) +{ + DrainAnnotationQueue(); + + m_EmptyCommandList = false; + + m_pRealContext->Dispatch(ThreadGroupCountX, ThreadGroupCountY, ThreadGroupCountZ); + + if(IsActiveCapturing(m_State)) + { + USE_SCRATCH_SERIALISER(); + GET_SERIALISER.SetDrawChunk(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::Dispatch); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_Dispatch(GET_SERIALISER, ThreadGroupCountX, ThreadGroupCountY, ThreadGroupCountZ); + + m_ContextRecord->AddChunk(scope.Get()); + + m_CurrentPipelineState->MarkReferenced(this, false); + } +} + +template +bool WrappedID3D11DeviceContext::Serialise_DispatchIndirect(SerialiserType &ser, + ID3D11Buffer *pBufferForArgs, + UINT AlignedByteOffsetForArgs) +{ + SERIALISE_ELEMENT(pBufferForArgs); + SERIALISE_ELEMENT(AlignedByteOffsetForArgs); + + Serialise_DebugMessages(GET_SERIALISER); + + if(IsReplayingAndReading()) + { + if(pBufferForArgs) + { + m_pRealContext->DispatchIndirect(UNWRAP(WrappedID3D11Buffer, pBufferForArgs), + AlignedByteOffsetForArgs); + } + + if(IsLoading(m_State)) + { + RecordDispatchStats(true); + + AddEvent(); + + DrawcallDescription draw; + + std::string name = "DispatchIndirect(-, -, -)"; + if(pBufferForArgs) + { + struct DispatchArgs + { + UINT ThreadGroupCountX; + UINT ThreadGroupCountY; + UINT ThreadGroupCountZ; + }; + + std::vector argarray; + m_pDevice->GetDebugManager()->GetBufferData(pBufferForArgs, AlignedByteOffsetForArgs, + sizeof(DispatchArgs), argarray); + + if(argarray.size() >= sizeof(DispatchArgs)) + { + DispatchArgs *args = (DispatchArgs *)&argarray[0]; + + draw.dispatchDimension[0] = args->ThreadGroupCountX; + draw.dispatchDimension[1] = args->ThreadGroupCountY; + draw.dispatchDimension[2] = args->ThreadGroupCountZ; + + name = StringFormat::Fmt("DispatchIndirect(<%u, %u, %u>)", args->ThreadGroupCountX, + args->ThreadGroupCountY, args->ThreadGroupCountZ); + } + else + { + name = "DispatchIndirect()"; + D3D11_BUFFER_DESC bufDesc; + + pBufferForArgs->GetDesc(&bufDesc); + + if(AlignedByteOffsetForArgs >= bufDesc.ByteWidth) + { + m_pDevice->AddDebugMessage( + MessageCategory::Execution, MessageSeverity::High, MessageSource::IncorrectAPIUse, + StringFormat::Fmt("Call to DispatchIndirect with buffer of %u " + "bytes, but byte offset specified is %u bytes.", + bufDesc.ByteWidth, AlignedByteOffsetForArgs)); + } + else if(AlignedByteOffsetForArgs + sizeof(DispatchArgs) >= bufDesc.ByteWidth) + { + m_pDevice->AddDebugMessage( + MessageCategory::Execution, MessageSeverity::High, MessageSource::IncorrectAPIUse, + StringFormat::Fmt("Call to DispatchIndirect with buffer of %u " + "bytes at offset of %u bytes, which leaves less than %u bytes " + "for the arguments.", + bufDesc.ByteWidth, AlignedByteOffsetForArgs, sizeof(DispatchArgs))); + } + } + + m_ResourceUses[GetIDForResource(pBufferForArgs)].push_back( + EventUsage(m_CurEventID, ResourceUsage::Indirect)); + } + + draw.name = name; + draw.flags |= DrawFlags::Dispatch | DrawFlags::Indirect; + + AddDrawcall(draw, true); + } + } + + return true; +} + +void WrappedID3D11DeviceContext::DispatchIndirect(ID3D11Buffer *pBufferForArgs, + UINT AlignedByteOffsetForArgs) +{ + DrainAnnotationQueue(); + + m_EmptyCommandList = false; + + m_pRealContext->DispatchIndirect(UNWRAP(WrappedID3D11Buffer, pBufferForArgs), + AlignedByteOffsetForArgs); + + if(IsActiveCapturing(m_State)) + { + USE_SCRATCH_SERIALISER(); + GET_SERIALISER.SetDrawChunk(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::DispatchIndirect); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_DispatchIndirect(GET_SERIALISER, pBufferForArgs, AlignedByteOffsetForArgs); + + m_ContextRecord->AddChunk(scope.Get()); + + m_CurrentPipelineState->MarkReferenced(this, false); + } + + if(pBufferForArgs && IsActiveCapturing(m_State)) + MarkResourceReferenced(GetIDForResource(pBufferForArgs), eFrameRef_Read); +} + +#pragma endregion Dispatch + #pragma region Execute -bool WrappedID3D11DeviceContext::Serialise_ExecuteCommandList(ID3D11CommandList *pCommandList, +template +bool WrappedID3D11DeviceContext::Serialise_ExecuteCommandList(SerialiserType &ser, + ID3D11CommandList *pCommandList, BOOL RestoreContextState_) { - SERIALISE_ELEMENT(uint8_t, RestoreContextState, RestoreContextState_ == TRUE); - SERIALISE_ELEMENT(ResourceId, cmdList, GetIDForResource(pCommandList)); + SERIALISE_ELEMENT_LOCAL(CommandList, GetIDForResource(pCommandList)); + SERIALISE_ELEMENT_LOCAL(RestoreContextState, bool(RestoreContextState_ == TRUE)); - const string desc = m_pSerialiser->GetDebugStr(); + Serialise_DebugMessages(GET_SERIALISER); - Serialise_DebugMessages(); - - if(m_State <= EXECUTING && RestoreContextState) + if(IsReplayingAndReading()) { - SAFE_DELETE(m_DeferredSavedState); - m_DeferredSavedState = new D3D11RenderState(this); + // The serialise of exec happens at the start of the inserted linearised commands from the + // deferred command list. So if we're going to restore context state afterwards, save off our + // current state. This will be restored in the Serialise_PostExecuteCommandList chunk. + if(RestoreContextState) + { + SAFE_DELETE(m_DeferredSavedState); + m_DeferredSavedState = new D3D11RenderState(this); + } // From the Docs: // "Immediate context state is cleared before and after a command list is executed. A command // list has no concept of inheritance." ClearState(); + + if(IsLoading(m_State)) + { + DrawcallDescription draw; + draw.name = StringFormat::Fmt("ExecuteCommandList(List %s)", ToStr(CommandList).c_str()); + draw.flags |= DrawFlags::CmdList; + + AddDrawcall(draw, true); + } } - if(m_State == READING) + return true; +} + +template +bool WrappedID3D11DeviceContext::Serialise_PostExecuteCommandListRestore(SerialiserType &ser) +{ + // this is a 'fake' call we insert after executing, to give us a chance to restore the state. + if(IsReplayingAndReading()) { - string name = "ExecuteCommandList(" + ToStr(cmdList) + ")"; - - DrawcallDescription draw; - draw.name = name; - draw.flags |= DrawFlags::CmdList; - - AddDrawcall(draw, true); + if(m_DeferredSavedState) + { + m_DeferredSavedState->ApplyState(this); + SAFE_DELETE(m_DeferredSavedState); + } } - return true; } @@ -4886,12 +4718,14 @@ void WrappedID3D11DeviceContext::ExecuteCommandList(ID3D11CommandList *pCommandL m_pRealContext->ExecuteCommandList(UNWRAP(WrappedID3D11CommandList, pCommandList), RestoreContextState); - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { { - SCOPED_SERIALISE_CONTEXT(EXECUTE_CMD_LIST); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_ExecuteCommandList(pCommandList, RestoreContextState); + USE_SCRATCH_SERIALISER(); + GET_SERIALISER.SetDrawChunk(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::ExecuteCommandList); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_ExecuteCommandList(GET_SERIALISER, pCommandList, RestoreContextState); m_ContextRecord->AddChunk(scope.Get()); } @@ -4925,14 +4759,16 @@ void WrappedID3D11DeviceContext::ExecuteCommandList(ID3D11CommandList *pCommandL { // insert a chunk to let us know on replay that we finished the command list's // chunks and we can restore the state - SCOPED_SERIALISE_CONTEXT(RESTORE_STATE_AFTER_EXEC); - m_pSerialiser->Serialise("context", m_ResourceID); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::PostExecuteCommandListRestore); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_PostExecuteCommandListRestore(GET_SERIALISER); m_ContextRecord->AddChunk(scope.Get()); } m_CurrentPipelineState->MarkReferenced(this, false); } - else if(m_State == WRITING_IDLE) + else if(IsBackgroundCapturing(m_State)) { WrappedID3D11CommandList *wrapped = (WrappedID3D11CommandList *)pCommandList; @@ -4945,209 +4781,22 @@ void WrappedID3D11DeviceContext::ExecuteCommandList(ID3D11CommandList *pCommandL VerifyState(); } -bool WrappedID3D11DeviceContext::Serialise_Dispatch(UINT ThreadGroupCountX_, - UINT ThreadGroupCountY_, UINT ThreadGroupCountZ_) -{ - SERIALISE_ELEMENT(uint32_t, ThreadGroupCountX, ThreadGroupCountX_); - SERIALISE_ELEMENT(uint32_t, ThreadGroupCountY, ThreadGroupCountY_); - SERIALISE_ELEMENT(uint32_t, ThreadGroupCountZ, ThreadGroupCountZ_); - - if(m_State <= EXECUTING) - { - if(m_State == READING) - RecordDispatchStats(false); - - m_pRealContext->Dispatch(ThreadGroupCountX, ThreadGroupCountY, ThreadGroupCountZ); - } - - const string desc = m_pSerialiser->GetDebugStr(); - - Serialise_DebugMessages(); - - if(m_State == READING) - { - AddEvent(desc); - string name = "Dispatch(" + ToStr(ThreadGroupCountX) + ", " + ToStr(ThreadGroupCountY) + ", " + - ToStr(ThreadGroupCountZ) + ")"; - - DrawcallDescription draw; - draw.name = name; - draw.flags |= DrawFlags::Dispatch; - - draw.dispatchDimension[0] = ThreadGroupCountX; - draw.dispatchDimension[1] = ThreadGroupCountY; - draw.dispatchDimension[2] = ThreadGroupCountZ; - - if(ThreadGroupCountX == 0) - m_pDevice->AddDebugMessage(MessageCategory::Execution, MessageSeverity::Medium, - MessageSource::IncorrectAPIUse, - "Dispatch call has ThreadGroup count X=0. This will do nothing, " - "which is unusual for a non-indirect Dispatch. Did you mean X=1?"); - if(ThreadGroupCountY == 0) - m_pDevice->AddDebugMessage(MessageCategory::Execution, MessageSeverity::Medium, - MessageSource::IncorrectAPIUse, - "Dispatch call has ThreadGroup count Y=0. This will do nothing, " - "which is unusual for a non-indirect Dispatch. Did you mean Y=1?"); - if(ThreadGroupCountZ == 0) - m_pDevice->AddDebugMessage(MessageCategory::Execution, MessageSeverity::Medium, - MessageSource::IncorrectAPIUse, - "Dispatch call has ThreadGroup count Z=0. This will do nothing, " - "which is unusual for a non-indirect Dispatch. Did you mean Z=1?"); - - AddDrawcall(draw, true); - } - - return true; -} - -void WrappedID3D11DeviceContext::Dispatch(UINT ThreadGroupCountX, UINT ThreadGroupCountY, - UINT ThreadGroupCountZ) -{ - DrainAnnotationQueue(); - - m_EmptyCommandList = false; - - m_pRealContext->Dispatch(ThreadGroupCountX, ThreadGroupCountY, ThreadGroupCountZ); - - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(DISPATCH); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_Dispatch(ThreadGroupCountX, ThreadGroupCountY, ThreadGroupCountZ); - - m_ContextRecord->AddChunk(scope.Get()); - - m_CurrentPipelineState->MarkReferenced(this, false); - } -} - -bool WrappedID3D11DeviceContext::Serialise_DispatchIndirect(ID3D11Buffer *pBufferForArgs, - UINT AlignedByteOffsetForArgs_) -{ - SERIALISE_ELEMENT(ResourceId, BufferForArgs, GetIDForResource(pBufferForArgs)); - SERIALISE_ELEMENT(uint32_t, AlignedByteOffsetForArgs, AlignedByteOffsetForArgs_); - - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(BufferForArgs)) - { - if(m_State == READING) - RecordDispatchStats(true); - - m_pRealContext->DispatchIndirect( - UNWRAP(WrappedID3D11Buffer, m_pDevice->GetResourceManager()->GetLiveResource(BufferForArgs)), - AlignedByteOffsetForArgs); - } - - const string desc = m_pSerialiser->GetDebugStr(); - - Serialise_DebugMessages(); - - if(m_State == READING) - { - AddEvent(desc); - - DrawcallDescription draw; - - string name = "DispatchIndirect(-, -, -)"; - if(m_pDevice->GetResourceManager()->HasLiveResource(BufferForArgs)) - { - ID3D11Buffer *argBuffer = - (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetLiveResource(BufferForArgs); - - vector args; - m_pDevice->GetDebugManager()->GetBufferData(argBuffer, AlignedByteOffsetForArgs, - 3 * sizeof(uint32_t), args); - uint32_t *uargs = (uint32_t *)&args[0]; - - if(args.size() >= sizeof(uint32_t) * 3) - { - draw.dispatchDimension[0] = uargs[0]; - draw.dispatchDimension[1] = uargs[1]; - draw.dispatchDimension[2] = uargs[2]; - - name = "DispatchIndirect(<" + ToStr(uargs[0]) + ", " + ToStr(uargs[1]) + +", " + - ToStr(uargs[2]) + ">)"; - } - else - { - name = "DispatchIndirect()"; - D3D11_BUFFER_DESC bufDesc; - - argBuffer->GetDesc(&bufDesc); - - if(AlignedByteOffsetForArgs >= bufDesc.ByteWidth) - { - m_pDevice->AddDebugMessage( - MessageCategory::Execution, MessageSeverity::High, MessageSource::IncorrectAPIUse, - StringFormat::Fmt("Call to DispatchIndirect with buffer of %u " - "bytes, but byte offset specified is %u bytes.", - bufDesc.ByteWidth, AlignedByteOffsetForArgs)); - } - else if(AlignedByteOffsetForArgs + sizeof(uint32_t) * 3 >= bufDesc.ByteWidth) - { - m_pDevice->AddDebugMessage( - MessageCategory::Execution, MessageSeverity::High, MessageSource::IncorrectAPIUse, - StringFormat::Fmt( - "Call to DispatchIndirect with buffer of %u " - "bytes at offset of %u bytes, which leaves less than %u bytes for the arguments.", - bufDesc.ByteWidth, AlignedByteOffsetForArgs, sizeof(uint32_t) * 3)); - } - } - - m_ResourceUses[GetIDForResource(argBuffer)].push_back( - EventUsage(m_CurEventID, ResourceUsage::Indirect)); - } - - draw.name = name; - draw.flags |= DrawFlags::Dispatch | DrawFlags::Indirect; - - AddDrawcall(draw, true); - } - - return true; -} - -void WrappedID3D11DeviceContext::DispatchIndirect(ID3D11Buffer *pBufferForArgs, - UINT AlignedByteOffsetForArgs) -{ - DrainAnnotationQueue(); - - m_EmptyCommandList = false; - - m_pRealContext->DispatchIndirect(UNWRAP(WrappedID3D11Buffer, pBufferForArgs), - AlignedByteOffsetForArgs); - - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(DISPATCH_INDIRECT); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_DispatchIndirect(pBufferForArgs, AlignedByteOffsetForArgs); - - m_ContextRecord->AddChunk(scope.Get()); - - m_CurrentPipelineState->MarkReferenced(this, false); - } - - if(pBufferForArgs && m_State >= WRITING_CAPFRAME) - MarkResourceReferenced(GetIDForResource(pBufferForArgs), eFrameRef_Read); -} - -bool WrappedID3D11DeviceContext::Serialise_FinishCommandList(BOOL RestoreDeferredContextState_, +template +bool WrappedID3D11DeviceContext::Serialise_FinishCommandList(SerialiserType &ser, + BOOL RestoreDeferredContextState_, ID3D11CommandList **ppCommandList) { - SERIALISE_ELEMENT(uint8_t, RestoreDeferredContextState, RestoreDeferredContextState_ == TRUE); - SERIALISE_ELEMENT(ResourceId, cmdList, GetIDForResource(*ppCommandList)); + SERIALISE_ELEMENT_LOCAL(RestoreDeferredContextState, bool(RestoreDeferredContextState_ == TRUE)); + SERIALISE_ELEMENT_LOCAL(pCommandList, GetIDForResource(*ppCommandList)); - const string desc = m_pSerialiser->GetDebugStr(); + Serialise_DebugMessages(GET_SERIALISER); - Serialise_DebugMessages(); - - if(m_State == READING) + if(IsReplayingAndReading() && IsLoading(m_State)) { - AddEvent(desc); - string name = "FinishCommandList() -> " + ToStr(cmdList); + AddEvent(); DrawcallDescription draw; - draw.name = name; + draw.name = StringFormat::Fmt("FinishCommandList(List %s)", ToStr(pCommandList).c_str()); draw.flags |= DrawFlags::CmdList; AddDrawcall(draw, true); @@ -5156,6 +4805,22 @@ bool WrappedID3D11DeviceContext::Serialise_FinishCommandList(BOOL RestoreDeferre return true; } +template +bool WrappedID3D11DeviceContext::Serialise_PostFinishCommandListSet(SerialiserType &ser) +{ + D3D11RenderState RenderState(*m_CurrentPipelineState); + + SERIALISE_ELEMENT(RenderState).Named("Initial Pipeline State"); + + // this is a 'fake' call we insert after finishing in a fresh deferred context, to allow us to + // preserve the state after a previous finish stole all the serialised chunks. + if(IsReplayingAndReading()) + { + RenderState.ApplyState(this); + } + return true; +} + HRESULT WrappedID3D11DeviceContext::FinishCommandList(BOOL RestoreDeferredContextState, ID3D11CommandList **ppCommandList) { @@ -5177,13 +4842,13 @@ HRESULT WrappedID3D11DeviceContext::FinishCommandList(BOOL RestoreDeferredContex bool cmdListSuccessful = m_SuccessfulCapture; - if(m_State != WRITING_CAPFRAME && !m_EmptyCommandList) + if(!IsActiveCapturing(m_State) && !m_EmptyCommandList) cmdListSuccessful = false; WrappedID3D11CommandList *wrapped = new WrappedID3D11CommandList(real, m_pDevice, this, cmdListSuccessful); - if(m_State >= WRITING) + if(IsCaptureMode(m_State)) { RDCASSERT(m_pDevice->GetResourceManager()->GetResourceRecord(wrapped->GetResourceID()) == NULL); @@ -5191,82 +4856,93 @@ HRESULT WrappedID3D11DeviceContext::FinishCommandList(BOOL RestoreDeferredContex m_pDevice->GetResourceManager()->AddResourceRecord(wrapped->GetResourceID()); record->Length = 0; record->ignoreSerialise = true; - } - - // if we got here and m_SuccessfulCapture is on, we have captured everything in this command list - if(m_State == WRITING_CAPFRAME && m_SuccessfulCapture) - { - RDCDEBUG("Deferred Context %llu Finish()'d successfully! Got successful command list %llu", - GetResourceID(), wrapped->GetResourceID()); - - RDCASSERT(wrapped->IsCaptured()); - - ID3D11CommandList *w = wrapped; + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(FINISH_CMD_LIST); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_FinishCommandList(RestoreDeferredContextState, &w); - m_ContextRecord->AddChunk(scope.Get()); + // if we got here and m_SuccessfulCapture is on, we have captured everything in this command + // list + if(m_SuccessfulCapture) + { + RDCDEBUG("Deferred Context %llu Finish()'d successfully! Got successful command list %llu", + GetResourceID(), wrapped->GetResourceID()); + + RDCASSERT(wrapped->IsCaptured()); + + ID3D11CommandList *w = wrapped; + + // serialise the finish marker + { + USE_SCRATCH_SERIALISER(); + GET_SERIALISER.SetDrawChunk(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::FinishCommandList); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_FinishCommandList(GET_SERIALISER, RestoreDeferredContextState, &w); + m_ContextRecord->AddChunk(scope.Get()); + } + + D3D11ResourceRecord *r = + m_pDevice->GetResourceManager()->GetResourceRecord(wrapped->GetResourceID()); + RDCASSERT(r); + + // swap our chunks, references, and dirty resources with the 'baked' command list. + m_ContextRecord->SwapChunks(r); + wrapped->SwapReferences(m_DeferredReferences); + wrapped->SwapDirtyResources(m_DeferredDirty); + } + else // !m_SuccessfulCapture + { + RDCDEBUG( + "Deferred Context %llu wasn't successful, but now we've Finish()'d so it is! Produced " + "unsuccessful command list %llu.", + GetResourceID(), wrapped->GetResourceID()); + + RDCASSERT(!wrapped->IsCaptured()); + + // need to clear out anything we had serialised before + m_ContextRecord->LockChunks(); + while(m_ContextRecord->HasChunks()) + { + Chunk *chunk = m_ContextRecord->GetLastChunk(); + SAFE_DELETE(chunk); + m_ContextRecord->PopChunk(); + } + m_ContextRecord->UnlockChunks(); + + // It's now 'successful' again, being empty + m_SuccessfulCapture = true; + } + + // if we're supposed to restore, save the state to restore to now. This is because the next + // recording to this deferred context is expected to have the same state, but we don't have + // that state serialised right now. So we blat out the whole serialisation + if(RestoreDeferredContextState) + { + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::PostFinishCommandListSet); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_PostFinishCommandListSet(GET_SERIALISER); + m_ContextRecord->AddChunk(scope.Get()); + } } - - D3D11ResourceRecord *r = - m_pDevice->GetResourceManager()->GetResourceRecord(wrapped->GetResourceID()); - RDCASSERT(r); - - m_ContextRecord->SwapChunks(r); - wrapped->SetReferences(m_DeferredReferences); - wrapped->SetDirtyResources(m_DeferredDirty); - - // if we're supposed to restore, save the state to restore to now - if(RestoreDeferredContextState) + else // IsIdleCapturing(m_State) { - SCOPED_SERIALISE_CONTEXT(RESTORE_STATE_AFTER_FINISH); - m_pSerialiser->Serialise("context", m_ResourceID); - D3D11RenderState rs(*m_CurrentPipelineState); - rs.SetSerialiser(m_pSerialiser); - rs.Serialise(m_State, m_pDevice); - m_ContextRecord->AddChunk(scope.Get()); + // mark that this command list is empty so that if we immediately try and capture + // we pick up on that. + m_EmptyCommandList = true; + + // still need to propagate up dirty resources to the immediate context + wrapped->SwapDirtyResources(m_DeferredDirty); + + RDCDEBUG( + "Deferred Context %llu not capturing at the moment, Produced unsuccessful command list " + "%llu.", + GetResourceID(), wrapped->GetResourceID()); } } - else if(m_State == WRITING_CAPFRAME && !m_SuccessfulCapture) - { - m_SuccessfulCapture = true; - - RDCDEBUG( - "Deferred Context %llu wasn't successful, but now we've Finish()'d so it is! Produced " - "unsuccessful command list %llu.", - GetResourceID(), wrapped->GetResourceID()); - - RDCASSERT(!wrapped->IsCaptured()); - - // need to clear out anything we had serialised before - m_ContextRecord->LockChunks(); - while(m_ContextRecord->HasChunks()) - { - Chunk *chunk = m_ContextRecord->GetLastChunk(); - SAFE_DELETE(chunk); - m_ContextRecord->PopChunk(); - } - m_ContextRecord->UnlockChunks(); - } - else if(m_State >= WRITING) - { - // mark that this command list is empty so that if we immediately try and capture - // we pick up on that. - m_EmptyCommandList = true; - - // still need to propagate up dirty resources to the immediate context - wrapped->SetDirtyResources(m_DeferredDirty); - - RDCDEBUG( - "Deferred Context %llu not capturing at the moment, Produced unsuccessful command list " - "%llu.", - GetResourceID(), wrapped->GetResourceID()); - } if(!RestoreDeferredContextState) m_CurrentPipelineState->Clear(); + VerifyState(); if(ppCommandList) @@ -5275,9 +4951,10 @@ HRESULT WrappedID3D11DeviceContext::FinishCommandList(BOOL RestoreDeferredContex return hr; } -bool WrappedID3D11DeviceContext::Serialise_Flush() +template +bool WrappedID3D11DeviceContext::Serialise_Flush(SerialiserType &ser) { - if(m_State <= EXECUTING) + if(IsReplayingAndReading()) { m_pRealContext->Flush(); } @@ -5289,11 +4966,12 @@ void WrappedID3D11DeviceContext::Flush() { m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(FLUSH); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_Flush(); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::Flush); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_Flush(GET_SERIALISER); m_ContextRecord->AddChunk(scope.Get()); @@ -5307,80 +4985,70 @@ void WrappedID3D11DeviceContext::Flush() #pragma region Copy +template bool WrappedID3D11DeviceContext::Serialise_CopySubresourceRegion( - ID3D11Resource *pDstResource, UINT DstSubresource, UINT DstX, UINT DstY, UINT DstZ, - ID3D11Resource *pSrcResource, UINT SrcSubresource, const D3D11_BOX *pSrcBox) + SerialiserType &ser, ID3D11Resource *pDstResource, UINT DstSubresource, UINT DstX, UINT DstY, + UINT DstZ, ID3D11Resource *pSrcResource, UINT SrcSubresource, const D3D11_BOX *pSrcBox) { - SERIALISE_ELEMENT(ResourceId, Destination, GetIDForResource(pDstResource)); - SERIALISE_ELEMENT(uint32_t, DestSubresource, DstSubresource); - SERIALISE_ELEMENT(uint32_t, DestX, DstX); - SERIALISE_ELEMENT(uint32_t, DestY, DstY); - SERIALISE_ELEMENT(uint32_t, DestZ, DstZ); - SERIALISE_ELEMENT(ResourceId, Source, GetIDForResource(pSrcResource)); - SERIALISE_ELEMENT(uint32_t, SourceSubresource, SrcSubresource); - SERIALISE_ELEMENT(uint8_t, HasSourceBox, pSrcBox != NULL); - SERIALISE_ELEMENT_OPT(D3D11_BOX, SourceBox, *pSrcBox, HasSourceBox); + SERIALISE_ELEMENT(pDstResource); + SERIALISE_ELEMENT(DstSubresource); + SERIALISE_ELEMENT(DstX); + SERIALISE_ELEMENT(DstY); + SERIALISE_ELEMENT(DstZ); + SERIALISE_ELEMENT(pSrcResource); + SERIALISE_ELEMENT(SrcSubresource); + SERIALISE_ELEMENT_OPT(pSrcBox); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(Destination) && - m_pDevice->GetResourceManager()->HasLiveResource(Source)) + Serialise_DebugMessages(GET_SERIALISER); + + if(IsReplayingAndReading()) { - D3D11_BOX *box = &SourceBox; - if(!HasSourceBox) - box = NULL; - - m_pRealContext->CopySubresourceRegion( - m_pDevice->GetResourceManager()->UnwrapResource( - (ID3D11Resource *)m_pDevice->GetResourceManager()->GetLiveResource(Destination)), - DestSubresource, DestX, DestY, DestZ, - m_pDevice->GetResourceManager()->UnwrapResource( - (ID3D11Resource *)m_pDevice->GetResourceManager()->GetLiveResource(Source)), - SourceSubresource, box); - } - - const string desc = m_pSerialiser->GetDebugStr(); - - // version 5 added this as a drawcall, we can assume for older logs there's just no debug messages - if(m_pDevice->GetLogVersion() >= 0x000006) - Serialise_DebugMessages(); - - if(m_State == READING) - { - std::string dstName = GetDebugName(m_pDevice->GetResourceManager()->GetLiveResource(Destination)); - std::string srcName = GetDebugName(m_pDevice->GetResourceManager()->GetLiveResource(Source)); - - if(dstName == "") - dstName = ToStr(Destination); - if(srcName == "") - srcName = ToStr(Source); - - AddEvent(desc); - string name = "CopySubresourceRegion(" + dstName + ", " + srcName + ")"; - - DrawcallDescription draw; - draw.name = name; - draw.flags |= DrawFlags::Copy; - - if(m_pDevice->GetResourceManager()->HasLiveResource(Destination) && - m_pDevice->GetResourceManager()->HasLiveResource(Source)) + if(pDstResource && pSrcResource) { - draw.copySource = Source; - draw.copyDestination = Destination; - - if(Destination == Source) - { - m_ResourceUses[m_pDevice->GetResourceManager()->GetLiveID(Destination)].push_back( - EventUsage(m_CurEventID, ResourceUsage::Copy)); - } - else - { - m_ResourceUses[m_pDevice->GetResourceManager()->GetLiveID(Destination)].push_back( - EventUsage(m_CurEventID, ResourceUsage::CopyDst)); - m_ResourceUses[m_pDevice->GetResourceManager()->GetLiveID(Source)].push_back( - EventUsage(m_CurEventID, ResourceUsage::CopySrc)); - } + m_pRealContext->CopySubresourceRegion( + GetResourceManager()->UnwrapResource(pDstResource), DstSubresource, DstX, DstY, DstZ, + GetResourceManager()->UnwrapResource(pSrcResource), SrcSubresource, pSrcBox); } - AddDrawcall(draw, true); + if(IsLoading(m_State)) + { + std::string dstName = GetDebugName(pDstResource); + std::string srcName = GetDebugName(pSrcResource); + + ResourceId dstLiveID = GetIDForResource(pDstResource); + ResourceId srcLiveID = GetIDForResource(pSrcResource); + ResourceId dstOrigID = GetResourceManager()->GetOriginalID(dstLiveID); + ResourceId srcOrigID = GetResourceManager()->GetOriginalID(srcLiveID); + + if(dstName == "") + dstName = ToStr(dstOrigID); + if(srcName == "") + srcName = ToStr(srcOrigID); + + AddEvent(); + + DrawcallDescription draw; + draw.name = "CopySubresourceRegion(" + dstName + ", " + srcName + ")"; + draw.flags |= DrawFlags::Copy; + + if(pDstResource && pSrcResource) + { + draw.copySource = srcOrigID; + draw.copyDestination = dstOrigID; + + if(dstLiveID == srcLiveID) + { + m_ResourceUses[dstLiveID].push_back(EventUsage(m_CurEventID, ResourceUsage::Copy)); + } + else + { + m_ResourceUses[dstLiveID].push_back(EventUsage(m_CurEventID, ResourceUsage::CopyDst)); + m_ResourceUses[srcLiveID].push_back(EventUsage(m_CurEventID, ResourceUsage::CopySrc)); + } + } + + AddDrawcall(draw, true); + } } return true; @@ -5395,12 +5063,14 @@ void WrappedID3D11DeviceContext::CopySubresourceRegion(ID3D11Resource *pDstResou m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(COPY_SUBRESOURCE_REGION); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_CopySubresourceRegion(pDstResource, DstSubresource, DstX, DstY, DstZ, pSrcResource, - SrcSubresource, pSrcBox); + USE_SCRATCH_SERIALISER(); + GET_SERIALISER.SetDrawChunk(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::CopySubresourceRegion); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_CopySubresourceRegion(GET_SERIALISER, pDstResource, DstSubresource, DstX, DstY, DstZ, + pSrcResource, SrcSubresource, pSrcBox); D3D11ResourceRecord *record = m_pDevice->GetResourceManager()->GetResourceRecord(GetIDForResource(pDstResource)); @@ -5418,7 +5088,7 @@ void WrappedID3D11DeviceContext::CopySubresourceRegion(ID3D11Resource *pDstResou MarkResourceReferenced(GetIDForResource(pDstResource), eFrameRef_Write); MarkResourceReferenced(GetIDForResource(pSrcResource), eFrameRef_Read); } - else if(m_State >= WRITING) + else if(IsBackgroundCapturing(m_State)) { D3D11ResourceRecord *record = m_pDevice->GetResourceManager()->GetResourceRecord(GetIDForResource(pDstResource)); @@ -5470,66 +5140,63 @@ void WrappedID3D11DeviceContext::CopySubresourceRegion(ID3D11Resource *pDstResou DstZ, m_pDevice->GetResourceManager()->UnwrapResource(pSrcResource), SrcSubresource, pSrcBox); } -bool WrappedID3D11DeviceContext::Serialise_CopyResource(ID3D11Resource *pDstResource, +template +bool WrappedID3D11DeviceContext::Serialise_CopyResource(SerialiserType &ser, + ID3D11Resource *pDstResource, ID3D11Resource *pSrcResource) { - SERIALISE_ELEMENT(ResourceId, Destination, GetIDForResource(pDstResource)); - SERIALISE_ELEMENT(ResourceId, Source, GetIDForResource(pSrcResource)); + SERIALISE_ELEMENT(pDstResource); + SERIALISE_ELEMENT(pSrcResource); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(Destination) && - m_pDevice->GetResourceManager()->HasLiveResource(Source)) + Serialise_DebugMessages(GET_SERIALISER); + + if(IsReplayingAndReading()) { - m_pRealContext->CopyResource( - m_pDevice->GetResourceManager()->UnwrapResource( - (ID3D11Resource *)m_pDevice->GetResourceManager()->GetLiveResource(Destination)), - m_pDevice->GetResourceManager()->UnwrapResource( - (ID3D11Resource *)m_pDevice->GetResourceManager()->GetLiveResource(Source))); - } - - const string desc = m_pSerialiser->GetDebugStr(); - - // version 5 added this as a drawcall, we can assume for older logs there's just no debug messages - if(m_pDevice->GetLogVersion() >= 0x000006) - Serialise_DebugMessages(); - - if(m_State == READING) - { - std::string dstName = GetDebugName(m_pDevice->GetResourceManager()->GetLiveResource(Destination)); - std::string srcName = GetDebugName(m_pDevice->GetResourceManager()->GetLiveResource(Source)); - - if(dstName == "") - dstName = ToStr(Destination); - if(srcName == "") - srcName = ToStr(Source); - - AddEvent(desc); - string name = "CopyResource(" + dstName + ", " + srcName + ")"; - - DrawcallDescription draw; - draw.name = name; - draw.flags |= DrawFlags::Copy; - - if(m_pDevice->GetResourceManager()->HasLiveResource(Destination) && - m_pDevice->GetResourceManager()->HasLiveResource(Source)) + if(pDstResource && pSrcResource) { - draw.copySource = Source; - draw.copyDestination = Destination; - - if(Destination == Source) - { - m_ResourceUses[m_pDevice->GetResourceManager()->GetLiveID(Destination)].push_back( - EventUsage(m_CurEventID, ResourceUsage::Copy)); - } - else - { - m_ResourceUses[m_pDevice->GetResourceManager()->GetLiveID(Destination)].push_back( - EventUsage(m_CurEventID, ResourceUsage::CopyDst)); - m_ResourceUses[m_pDevice->GetResourceManager()->GetLiveID(Source)].push_back( - EventUsage(m_CurEventID, ResourceUsage::CopySrc)); - } + m_pRealContext->CopyResource(m_pDevice->GetResourceManager()->UnwrapResource(pDstResource), + m_pDevice->GetResourceManager()->UnwrapResource(pSrcResource)); } - AddDrawcall(draw, true); + if(IsLoading(m_State)) + { + std::string dstName = GetDebugName(pDstResource); + std::string srcName = GetDebugName(pSrcResource); + + ResourceId dstLiveID = GetIDForResource(pDstResource); + ResourceId srcLiveID = GetIDForResource(pSrcResource); + ResourceId dstOrigID = GetResourceManager()->GetOriginalID(dstLiveID); + ResourceId srcOrigID = GetResourceManager()->GetOriginalID(srcLiveID); + + if(dstName == "") + dstName = ToStr(dstOrigID); + if(srcName == "") + srcName = ToStr(srcOrigID); + + AddEvent(); + + DrawcallDescription draw; + draw.name = "CopyResource(" + dstName + ", " + srcName + ")"; + draw.flags |= DrawFlags::Copy; + + if(pDstResource && pSrcResource) + { + draw.copySource = srcOrigID; + draw.copyDestination = dstOrigID; + + if(dstLiveID == srcLiveID) + { + m_ResourceUses[dstLiveID].push_back(EventUsage(m_CurEventID, ResourceUsage::Copy)); + } + else + { + m_ResourceUses[dstLiveID].push_back(EventUsage(m_CurEventID, ResourceUsage::CopyDst)); + m_ResourceUses[srcLiveID].push_back(EventUsage(m_CurEventID, ResourceUsage::CopySrc)); + } + } + + AddDrawcall(draw, true); + } } return true; @@ -5542,11 +5209,13 @@ void WrappedID3D11DeviceContext::CopyResource(ID3D11Resource *pDstResource, m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(COPY_RESOURCE); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_CopyResource(pDstResource, pSrcResource); + USE_SCRATCH_SERIALISER(); + GET_SERIALISER.SetDrawChunk(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::CopyResource); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_CopyResource(GET_SERIALISER, pDstResource, pSrcResource); D3D11ResourceRecord *record = m_pDevice->GetResourceManager()->GetResourceRecord(GetIDForResource(pDstResource)); @@ -5562,7 +5231,7 @@ void WrappedID3D11DeviceContext::CopyResource(ID3D11Resource *pDstResource, MarkResourceReferenced(GetIDForResource(pDstResource), eFrameRef_Write); MarkResourceReferenced(GetIDForResource(pSrcResource), eFrameRef_Read); } - else if(m_State >= WRITING) + else if(IsBackgroundCapturing(m_State)) { D3D11ResourceRecord *record = m_pDevice->GetResourceManager()->GetResourceRecord(GetIDForResource(pDstResource)); @@ -5572,7 +5241,10 @@ void WrappedID3D11DeviceContext::CopyResource(ID3D11Resource *pDstResource, m_pDevice->GetResourceManager()->GetResourceRecord(GetIDForResource(pSrcResource)); RDCASSERT(srcRecord); - if(m_pDevice->GetResourceManager()->IsResourceDirty(GetIDForResource(pSrcResource))) + record->UpdateCount++; + + if(record->UpdateCount > 5 || + m_pDevice->GetResourceManager()->IsResourceDirty(GetIDForResource(pSrcResource))) { MarkDirtyResource(GetIDForResource(pDstResource)); } @@ -5595,41 +5267,7 @@ void WrappedID3D11DeviceContext::CopyResource(ID3D11Resource *pDstResource, (WrappedID3D11Texture3D1::IsAlloc(pDstResource) && WrappedID3D11Texture3D1::IsAlloc(pSrcResource))) { - // can't copy without data allocated - if(!record->DataInSerialiser || !srcRecord->DataInSerialiser) - { - SCOPED_SERIALISE_CONTEXT(COPY_RESOURCE); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_CopyResource(pDstResource, pSrcResource); - - m_pDevice->LockForChunkRemoval(); - - record->LockChunks(); - for(;;) - { - Chunk *end = record->GetLastChunk(); - - if(end->GetChunkType() == CLEAR_RTV || end->GetChunkType() == CLEAR_DSV || - end->GetChunkType() == CLEAR_UAV_FLOAT || end->GetChunkType() == CLEAR_UAV_INT || - end->GetChunkType() == RESOLVE_SUBRESOURCE || end->GetChunkType() == COPY_RESOURCE) - { - SAFE_DELETE(end); - - record->PopChunk(); - - continue; - } - - break; - } - record->UnlockChunks(); - - m_pDevice->UnlockForChunkRemoval(); - - record->AddChunk(scope.Get()); - record->AddParent(srcRecord); - } - else + if(record->DataInSerialiser && srcRecord->DataInSerialiser) { RDCASSERT(record->NumSubResources == srcRecord->NumSubResources); @@ -5641,6 +5279,17 @@ void WrappedID3D11DeviceContext::CopyResource(ID3D11Resource *pDstResource, memcpy(to, from, (size_t)record->SubResources[i]->Length); } } + else + { + // can't copy without data allocated + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::CopyResource); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_CopyResource(GET_SERIALISER, pDstResource, pSrcResource); + + record->AddChunk(scope.Get()); + record->AddParent(srcRecord); + } } else { @@ -5652,16 +5301,15 @@ void WrappedID3D11DeviceContext::CopyResource(ID3D11Resource *pDstResource, m_pDevice->GetResourceManager()->UnwrapResource(pSrcResource)); } -bool WrappedID3D11DeviceContext::Serialise_UpdateSubresource(ID3D11Resource *pDstResource, - UINT DstSubresource, - const D3D11_BOX *pDstBox, - const void *pSrcData, UINT SrcRowPitch, - UINT SrcDepthPitch) +template +bool WrappedID3D11DeviceContext::Serialise_UpdateSubresource( + SerialiserType &ser, ID3D11Resource *pDstResource, UINT DstSubresource, + const D3D11_BOX *pDstBox, const void *pSrcData, UINT SrcRowPitch, UINT SrcDepthPitch) { // pass ~0U as the flags to indicate this came for UpdateSubresource, so we know to apply // deferred context workarounds or not - return Serialise_UpdateSubresource1(pDstResource, DstSubresource, pDstBox, pSrcData, SrcRowPitch, - SrcDepthPitch, ~0U); + return Serialise_UpdateSubresource1(ser, pDstResource, DstSubresource, pDstBox, pSrcData, + SrcRowPitch, SrcDepthPitch, ~0U); } void WrappedID3D11DeviceContext::UpdateSubresource(ID3D11Resource *pDstResource, UINT DstSubresource, @@ -5723,18 +5371,19 @@ void WrappedID3D11DeviceContext::UpdateSubresource(ID3D11Resource *pDstResource, pSrcData = ((const BYTE *)pSrcData) + (alignedBox.left); } - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(UPDATE_SUBRESOURCE); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_UpdateSubresource(pDstResource, DstSubresource, pDstBox, pSrcData, SrcRowPitch, - SrcDepthPitch); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::UpdateSubresource); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_UpdateSubresource(GET_SERIALISER, pDstResource, DstSubresource, pDstBox, pSrcData, + SrcRowPitch, SrcDepthPitch); m_MissingTracks.insert(GetIDForResource(pDstResource)); m_ContextRecord->AddChunk(scope.Get()); } - else if(m_State >= WRITING) + else if(IsBackgroundCapturing(m_State)) { ResourceId idx = GetIDForResource(pDstResource); D3D11ResourceRecord *record = m_pDevice->GetResourceManager()->GetResourceRecord(idx); @@ -5775,11 +5424,12 @@ void WrappedID3D11DeviceContext::UpdateSubresource(ID3D11Resource *pDstResource, // this record isn't in the log already, write out a chunk that we can update after. if(!record->SubResources[DstSubresource]->DataInSerialiser) { - SCOPED_SERIALISE_CONTEXT(UPDATE_SUBRESOURCE); - m_pSerialiser->Serialise("context", m_ResourceID); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::UpdateSubresource); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); - Serialise_UpdateSubresource(pDstResource, DstSubresource, pDstBox, pSrcData, SrcRowPitch, - SrcDepthPitch); + Serialise_UpdateSubresource(GET_SERIALISER, pDstResource, DstSubresource, pDstBox, pSrcData, + SrcRowPitch, SrcDepthPitch); Chunk *chunk = scope.Get(); @@ -5932,21 +5582,20 @@ void WrappedID3D11DeviceContext::UpdateSubresource(ID3D11Resource *pDstResource, SrcDepthPitch); } -bool WrappedID3D11DeviceContext::Serialise_CopyStructureCount(ID3D11Buffer *pDstBuffer, +template +bool WrappedID3D11DeviceContext::Serialise_CopyStructureCount(SerialiserType &ser, + ID3D11Buffer *pDstBuffer, UINT DstAlignedByteOffset, ID3D11UnorderedAccessView *pSrcView) { - SERIALISE_ELEMENT(ResourceId, DestBuffer, GetIDForResource(pDstBuffer)); - SERIALISE_ELEMENT(uint32_t, DestAlignedByteOffset, DstAlignedByteOffset); - SERIALISE_ELEMENT(ResourceId, SourceView, GetIDForResource(pSrcView)); + SERIALISE_ELEMENT(pDstBuffer); + SERIALISE_ELEMENT(DstAlignedByteOffset); + SERIALISE_ELEMENT(pSrcView); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(DestBuffer) && - m_pDevice->GetResourceManager()->HasLiveResource(SourceView)) + if(IsReplayingAndReading() && pDstBuffer && pSrcView) { - m_pRealContext->CopyStructureCount( - UNWRAP(WrappedID3D11Buffer, m_pDevice->GetResourceManager()->GetLiveResource(DestBuffer)), - DestAlignedByteOffset, UNWRAP(WrappedID3D11UnorderedAccessView1, - m_pDevice->GetResourceManager()->GetLiveResource(SourceView))); + m_pRealContext->CopyStructureCount(UNWRAP(WrappedID3D11Buffer, pDstBuffer), DstAlignedByteOffset, + UNWRAP(WrappedID3D11UnorderedAccessView1, pSrcView)); } return true; @@ -5960,11 +5609,12 @@ void WrappedID3D11DeviceContext::CopyStructureCount(ID3D11Buffer *pDstBuffer, m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(COPY_STRUCTURE_COUNT); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_CopyStructureCount(pDstBuffer, DstAlignedByteOffset, pSrcView); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::CopyStructureCount); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_CopyStructureCount(GET_SERIALISER, pDstBuffer, DstAlignedByteOffset, pSrcView); m_ContextRecord->AddChunk(scope.Get()); @@ -5974,7 +5624,7 @@ void WrappedID3D11DeviceContext::CopyStructureCount(ID3D11Buffer *pDstBuffer, MarkResourceReferenced(GetIDForResource(pSrcView), eFrameRef_Read); } - else if(m_State >= WRITING) + else if(IsBackgroundCapturing(m_State)) { // needs to go into device serialiser @@ -5995,76 +5645,69 @@ void WrappedID3D11DeviceContext::CopyStructureCount(ID3D11Buffer *pDstBuffer, UNWRAP(WrappedID3D11UnorderedAccessView1, pSrcView)); } -bool WrappedID3D11DeviceContext::Serialise_ResolveSubresource(ID3D11Resource *pDstResource, +template +bool WrappedID3D11DeviceContext::Serialise_ResolveSubresource(SerialiserType &ser, + ID3D11Resource *pDstResource, UINT DstSubresource, ID3D11Resource *pSrcResource, - UINT SrcSubresource, - DXGI_FORMAT Format_) + UINT SrcSubresource, DXGI_FORMAT Format) { - SERIALISE_ELEMENT(ResourceId, DestResource, GetIDForResource(pDstResource)); - SERIALISE_ELEMENT(uint32_t, DestSubresource, DstSubresource); - SERIALISE_ELEMENT(ResourceId, SourceResource, GetIDForResource(pSrcResource)); - SERIALISE_ELEMENT(uint32_t, SourceSubresource, SrcSubresource); - SERIALISE_ELEMENT(DXGI_FORMAT, Format, Format_); + SERIALISE_ELEMENT(pDstResource); + SERIALISE_ELEMENT(DstSubresource); + SERIALISE_ELEMENT(pSrcResource); + SERIALISE_ELEMENT(SrcSubresource); + SERIALISE_ELEMENT(Format); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(DestResource) && - m_pDevice->GetResourceManager()->HasLiveResource(SourceResource)) + Serialise_DebugMessages(GET_SERIALISER); + + if(IsReplayingAndReading()) { - m_pRealContext->ResolveSubresource( - m_pDevice->GetResourceManager()->UnwrapResource( - (ID3D11Resource *)m_pDevice->GetResourceManager()->GetLiveResource(DestResource)), - DestSubresource, - m_pDevice->GetResourceManager()->UnwrapResource( - (ID3D11Resource *)m_pDevice->GetResourceManager()->GetLiveResource(SourceResource)), - SourceSubresource, Format); - } - - const string desc = m_pSerialiser->GetDebugStr(); - - // version 5 added this as a drawcall, we can assume for older logs there's just no debug messages - if(m_pDevice->GetLogVersion() >= 0x000006) - Serialise_DebugMessages(); - - if(m_State == READING) - { - std::string dstName = - GetDebugName(m_pDevice->GetResourceManager()->GetLiveResource(DestResource)); - std::string srcName = - GetDebugName(m_pDevice->GetResourceManager()->GetLiveResource(SourceResource)); - - if(dstName == "") - dstName = ToStr(DestResource); - if(srcName == "") - srcName = ToStr(SourceResource); - - AddEvent(desc); - string name = "ResolveSubresource(" + dstName + ", " + srcName + ")"; - - DrawcallDescription draw; - draw.name = name; - draw.flags |= DrawFlags::Resolve; - - if(m_pDevice->GetResourceManager()->HasLiveResource(DestResource) && - m_pDevice->GetResourceManager()->HasLiveResource(SourceResource)) + if(pDstResource && pSrcResource) { - draw.copySource = SourceResource; - draw.copyDestination = DestResource; - - if(DestResource == SourceResource) - { - m_ResourceUses[m_pDevice->GetResourceManager()->GetLiveID(DestResource)].push_back( - EventUsage(m_CurEventID, ResourceUsage::Resolve)); - } - else - { - m_ResourceUses[m_pDevice->GetResourceManager()->GetLiveID(DestResource)].push_back( - EventUsage(m_CurEventID, ResourceUsage::ResolveDst)); - m_ResourceUses[m_pDevice->GetResourceManager()->GetLiveID(SourceResource)].push_back( - EventUsage(m_CurEventID, ResourceUsage::ResolveSrc)); - } + m_pRealContext->ResolveSubresource( + m_pDevice->GetResourceManager()->UnwrapResource(pDstResource), DstSubresource, + m_pDevice->GetResourceManager()->UnwrapResource(pSrcResource), SrcSubresource, Format); } - AddDrawcall(draw, true); + if(IsLoading(m_State)) + { + std::string dstName = GetDebugName(pDstResource); + std::string srcName = GetDebugName(pSrcResource); + + ResourceId dstLiveID = GetIDForResource(pDstResource); + ResourceId srcLiveID = GetIDForResource(pSrcResource); + ResourceId dstOrigID = GetResourceManager()->GetOriginalID(dstLiveID); + ResourceId srcOrigID = GetResourceManager()->GetOriginalID(srcLiveID); + + if(dstName == "") + dstName = ToStr(dstOrigID); + if(srcName == "") + srcName = ToStr(srcOrigID); + + AddEvent(); + + DrawcallDescription draw; + draw.name = "ResolveSubresource(" + dstName + ", " + srcName + ")"; + draw.flags |= DrawFlags::Resolve; + + if(pDstResource && pSrcResource) + { + draw.copySource = srcOrigID; + draw.copyDestination = dstOrigID; + + if(dstLiveID == srcLiveID) + { + m_ResourceUses[dstLiveID].push_back(EventUsage(m_CurEventID, ResourceUsage::Resolve)); + } + else + { + m_ResourceUses[dstLiveID].push_back(EventUsage(m_CurEventID, ResourceUsage::ResolveDst)); + m_ResourceUses[srcLiveID].push_back(EventUsage(m_CurEventID, ResourceUsage::ResolveSrc)); + } + } + + AddDrawcall(draw, true); + } } return true; @@ -6078,11 +5721,14 @@ void WrappedID3D11DeviceContext::ResolveSubresource(ID3D11Resource *pDstResource m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(RESOLVE_SUBRESOURCE); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_ResolveSubresource(pDstResource, DstSubresource, pSrcResource, SrcSubresource, Format); + USE_SCRATCH_SERIALISER(); + GET_SERIALISER.SetDrawChunk(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::ResolveSubresource); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_ResolveSubresource(GET_SERIALISER, pDstResource, DstSubresource, pSrcResource, + SrcSubresource, Format); m_ContextRecord->AddChunk(scope.Get()); @@ -6091,65 +5737,9 @@ void WrappedID3D11DeviceContext::ResolveSubresource(ID3D11Resource *pDstResource MarkResourceReferenced(GetIDForResource(pDstResource), eFrameRef_Write); MarkResourceReferenced(GetIDForResource(pSrcResource), eFrameRef_Read); } - else if(m_State >= WRITING) + else if(IsBackgroundCapturing(m_State)) { - // needs to go into device serialiser - - RDCASSERT(WrappedID3D11Texture2D1::IsAlloc(pDstResource) && - WrappedID3D11Texture2D1::IsAlloc(pSrcResource)); - - D3D11ResourceRecord *record = - m_pDevice->GetResourceManager()->GetResourceRecord(GetIDForResource(pDstResource)); - RDCASSERT(record); - - D3D11ResourceRecord *srcRecord = - m_pDevice->GetResourceManager()->GetResourceRecord(GetIDForResource(pSrcResource)); - RDCASSERT(srcRecord); - - // resolve subresource only really 'clears' if it's the only subresource. - // This is usually the case for render target textures though. - if(m_pDevice->GetResourceManager()->IsResourceDirty(GetIDForResource(pSrcResource)) || - record->NumSubResources > 1) - { - MarkDirtyResource(GetIDForResource(pDstResource)); - } - else - { - record->AddParent(srcRecord); - - SCOPED_SERIALISE_CONTEXT(RESOLVE_SUBRESOURCE); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_ResolveSubresource(pDstResource, DstSubresource, pSrcResource, SrcSubresource, - Format); - - { - m_pDevice->LockForChunkRemoval(); - - record->LockChunks(); - for(;;) - { - Chunk *end = record->GetLastChunk(); - - if(end->GetChunkType() == CLEAR_RTV || end->GetChunkType() == CLEAR_DSV || - end->GetChunkType() == CLEAR_UAV_FLOAT || end->GetChunkType() == CLEAR_UAV_INT || - end->GetChunkType() == RESOLVE_SUBRESOURCE || end->GetChunkType() == COPY_RESOURCE) - { - SAFE_DELETE(end); - - record->PopChunk(); - - continue; - } - - break; - } - record->UnlockChunks(); - - m_pDevice->UnlockForChunkRemoval(); - } - - record->AddChunk(scope.Get()); - } + MarkDirtyResource(GetIDForResource(pDstResource)); } m_pRealContext->ResolveSubresource( @@ -6157,51 +5747,45 @@ void WrappedID3D11DeviceContext::ResolveSubresource(ID3D11Resource *pDstResource m_pDevice->GetResourceManager()->UnwrapResource(pSrcResource), SrcSubresource, Format); } -bool WrappedID3D11DeviceContext::Serialise_GenerateMips(ID3D11ShaderResourceView *pShaderResourceView) +template +bool WrappedID3D11DeviceContext::Serialise_GenerateMips(SerialiserType &ser, + ID3D11ShaderResourceView *pShaderResourceView) { - SERIALISE_ELEMENT(ResourceId, ShaderResourceView, GetIDForResource(pShaderResourceView)); + SERIALISE_ELEMENT(pShaderResourceView); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(ShaderResourceView)) + Serialise_DebugMessages(GET_SERIALISER); + + if(IsReplayingAndReading()) { - m_pRealContext->GenerateMips( - UNWRAP(WrappedID3D11ShaderResourceView1, - m_pDevice->GetResourceManager()->GetLiveResource(ShaderResourceView))); - } - - const string desc = m_pSerialiser->GetDebugStr(); - - // version 5 added this as a drawcall, we can assume for older logs there's just no debug messages - if(m_pDevice->GetLogVersion() >= 0x000006) - Serialise_DebugMessages(); - - if(m_State == READING) - { - ResourceId id = ShaderResourceView; - - if(m_pDevice->GetResourceManager()->HasLiveResource(ShaderResourceView)) + if(pShaderResourceView) { - WrappedID3D11ShaderResourceView1 *view = - (WrappedID3D11ShaderResourceView1 *)m_pDevice->GetResourceManager()->GetLiveResource( - ShaderResourceView); - id = view->GetResourceResID(); - m_ResourceUses[id].push_back( - EventUsage(m_CurEventID, ResourceUsage::GenMips, view->GetResourceID())); - id = m_pDevice->GetResourceManager()->GetOriginalID(id); + m_pRealContext->GenerateMips(UNWRAP(WrappedID3D11ShaderResourceView1, pShaderResourceView)); } - std::string resName = GetDebugName(m_pDevice->GetResourceManager()->GetLiveResource(id)); + if(IsLoading(m_State)) + { + WrappedID3D11ShaderResourceView1 *view = + (WrappedID3D11ShaderResourceView1 *)pShaderResourceView; - if(resName == "") - resName = ToStr(id); + if(view) + { + m_ResourceUses[view->GetResourceResID()].push_back( + EventUsage(m_CurEventID, ResourceUsage::GenMips, view->GetResourceID())); + } - AddEvent(desc); - string name = "GenerateMips(" + resName + ")"; + std::string resName = GetDebugName(pShaderResourceView); - DrawcallDescription draw; - draw.name = name; - draw.flags |= DrawFlags::GenMips; + if(resName == "") + resName = ToStr(GetResourceManager()->GetOriginalID(GetIDForResource(pShaderResourceView))); - AddDrawcall(draw, true); + AddEvent(); + + DrawcallDescription draw; + draw.name = "GenerateMips(" + resName + ")"; + draw.flags |= DrawFlags::GenMips; + + AddDrawcall(draw, true); + } } return true; @@ -6216,11 +5800,13 @@ void WrappedID3D11DeviceContext::GenerateMips(ID3D11ShaderResourceView *pShaderR if(!pShaderResourceView) return; - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(GENERATE_MIPS); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_GenerateMips(pShaderResourceView); + USE_SCRATCH_SERIALISER(); + GET_SERIALISER.SetDrawChunk(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::GenerateMips); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_GenerateMips(GET_SERIALISER, pShaderResourceView); m_ContextRecord->AddChunk(scope.Get()); @@ -6232,7 +5818,7 @@ void WrappedID3D11DeviceContext::GenerateMips(ID3D11ShaderResourceView *pShaderR MarkResourceReferenced(id, eFrameRef_Write); MarkResourceReferenced(GetIDForResource(pShaderResourceView), eFrameRef_Read); } - else if(m_State >= WRITING) + else if(IsBackgroundCapturing(m_State)) { MarkDirtyResource(GetViewResourceResID(pShaderResourceView)); } @@ -6244,9 +5830,10 @@ void WrappedID3D11DeviceContext::GenerateMips(ID3D11ShaderResourceView *pShaderR #pragma region Clear -bool WrappedID3D11DeviceContext::Serialise_ClearState() +template +bool WrappedID3D11DeviceContext::Serialise_ClearState(SerialiserType &ser) { - if(m_State <= EXECUTING) + if(IsReplayingAndReading()) { m_CurrentPipelineState->Clear(); m_pRealContext->ClearState(); @@ -6260,11 +5847,13 @@ void WrappedID3D11DeviceContext::ClearState() { m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(CLEAR_STATE); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_ClearState(); + USE_SCRATCH_SERIALISER(); + GET_SERIALISER.SetDrawChunk(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::ClearState); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_ClearState(GET_SERIALISER); m_ContextRecord->AddChunk(scope.Get()); } @@ -6274,99 +5863,45 @@ void WrappedID3D11DeviceContext::ClearState() VerifyState(); } +template bool WrappedID3D11DeviceContext::Serialise_ClearRenderTargetView( - ID3D11RenderTargetView *pRenderTargetView, const FLOAT ColorRGBA[4]) + SerialiserType &ser, ID3D11RenderTargetView *pRenderTargetView, const FLOAT ColorRGBA[4]) { - SERIALISE_ELEMENT(ResourceId, View, GetIDForResource(pRenderTargetView)); + SERIALISE_ELEMENT(pRenderTargetView); + SERIALISE_ELEMENT_ARRAY(ColorRGBA, FIXED_COUNT(4)); - // at time of writing we don't support the 11.3 DESC1, but for the sake - // of not having to bump serialisation version later we'll serialise that - // version of the descriptor. We can just alias the memory because the only - // difference is some union members got larger. - union + Serialise_DebugMessages(GET_SERIALISER); + + if(IsReplayingAndReading()) { - D3D11_RENDER_TARGET_VIEW_DESC1 Desc1; - D3D11_RENDER_TARGET_VIEW_DESC Desc; - } ViewDesc; - ResourceId resID; - - RDCEraseEl(ViewDesc.Desc1); - - if(m_State >= WRITING) - { - pRenderTargetView->GetDesc(&ViewDesc.Desc); - resID = ((WrappedID3D11RenderTargetView1 *)pRenderTargetView)->GetResourceResID(); - } - - if(m_State >= WRITING || m_pDevice->GetLogVersion() >= 0x000009) - { - m_pSerialiser->Serialise("ViewDesc", ViewDesc.Desc1); - m_pSerialiser->Serialise("resID", resID); - } - - float Color[4] = {0}; - - if(m_State >= WRITING) - memcpy(Color, ColorRGBA, sizeof(float) * 4); - - m_pSerialiser->SerialisePODArray<4>("ColorRGBA", Color); - - if(m_State <= EXECUTING) - { - if(m_pDevice->GetResourceManager()->HasLiveResource(View)) + if(pRenderTargetView) { m_pRealContext->ClearRenderTargetView( - UNWRAP(WrappedID3D11RenderTargetView1, - m_pDevice->GetResourceManager()->GetLiveResource(View)), - Color); + UNWRAP(WrappedID3D11RenderTargetView1, pRenderTargetView), ColorRGBA); } - else if(m_pDevice->GetLogVersion() >= 0x000009) + + if(IsLoading(m_State)) { - // no live view, we have to create one ourselves to clear with. - if(m_pDevice->GetResourceManager()->HasLiveResource(resID)) + AddEvent(); + + WrappedID3D11RenderTargetView1 *view = (WrappedID3D11RenderTargetView1 *)pRenderTargetView; + + DrawcallDescription draw; + draw.name = StringFormat::Fmt("ClearRenderTargetView(%f, %f, %f, %f)", ColorRGBA[0], + ColorRGBA[1], ColorRGBA[2], ColorRGBA[3]); + draw.flags |= DrawFlags::Clear | DrawFlags::ClearColor; + draw.copyDestination = GetResourceManager()->GetOriginalID(view->GetResourceResID()); + + if(view) { - ID3D11RenderTargetView *view = NULL; - m_pDevice->CreateRenderTargetView( - (ID3D11Resource *)m_pDevice->GetResourceManager()->GetLiveResource(resID), - &ViewDesc.Desc, &view); - m_pRealContext->ClearRenderTargetView(UNWRAP(WrappedID3D11RenderTargetView1, view), Color); - SAFE_RELEASE(view); + m_ResourceUses[view->GetResourceResID()].push_back( + EventUsage(m_CurEventID, ResourceUsage::Clear, view->GetResourceID())); + draw.copyDestination = + m_pDevice->GetResourceManager()->GetOriginalID(view->GetResourceResID()); } + + AddDrawcall(draw, true); } - else - { - RDCWARN( - "No view was found to perform clear - data might be wrong. " - "Re-capture with latest RenderDoc to solve this issue."); - } - } - - const string desc = m_pSerialiser->GetDebugStr(); - - Serialise_DebugMessages(); - - if(m_State == READING) - { - AddEvent(desc); - string name = "ClearRenderTargetView(" + ToStr(Color[0]) + ", " + ToStr(Color[1]) + ", " + - ToStr(Color[2]) + ", " + ToStr(Color[3]) + ")"; - - DrawcallDescription draw; - draw.name = name; - draw.flags |= DrawFlags::Clear | DrawFlags::ClearColor; - - draw.copyDestination = resID; - - if(m_pDevice->GetResourceManager()->HasLiveResource(View)) - { - WrappedID3D11RenderTargetView1 *view = - (WrappedID3D11RenderTargetView1 *)m_pDevice->GetResourceManager()->GetLiveResource(View); - m_ResourceUses[view->GetResourceResID()].push_back( - EventUsage(m_CurEventID, ResourceUsage::Clear, view->GetResourceID())); - draw.copyDestination = m_pDevice->GetResourceManager()->GetOriginalID(view->GetResourceResID()); - } - - AddDrawcall(draw, true); } return true; @@ -6385,153 +5920,70 @@ void WrappedID3D11DeviceContext::ClearRenderTargetView(ID3D11RenderTargetView *p m_pRealContext->ClearRenderTargetView(UNWRAP(WrappedID3D11RenderTargetView1, pRenderTargetView), ColorRGBA); - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(CLEAR_RTV); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_ClearRenderTargetView(pRenderTargetView, ColorRGBA); + USE_SCRATCH_SERIALISER(); + GET_SERIALISER.SetDrawChunk(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::ClearRenderTargetView); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_ClearRenderTargetView(GET_SERIALISER, pRenderTargetView, ColorRGBA); + + if(pRenderTargetView) + { + MarkResourceReferenced(GetViewResourceResID(pRenderTargetView), eFrameRef_Write); + MarkResourceReferenced(GetIDForResource(pRenderTargetView), eFrameRef_Read); + } m_MissingTracks.insert(GetViewResourceResID(pRenderTargetView)); m_ContextRecord->AddChunk(scope.Get()); } - else if(m_State >= WRITING) + else if(IsBackgroundCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(CLEAR_RTV); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_ClearRenderTargetView(pRenderTargetView, ColorRGBA); - - ResourceId id = GetViewResourceResID(pRenderTargetView); - - D3D11ResourceRecord *record = m_pDevice->GetResourceManager()->GetResourceRecord(id); - RDCASSERT(record); - - m_pDevice->LockForChunkRemoval(); - - record->LockChunks(); - for(;;) - { - Chunk *end = record->GetLastChunk(); - - if(end->GetChunkType() == CLEAR_RTV || end->GetChunkType() == CLEAR_DSV || - end->GetChunkType() == CLEAR_UAV_FLOAT || end->GetChunkType() == CLEAR_UAV_INT || - end->GetChunkType() == RESOLVE_SUBRESOURCE || end->GetChunkType() == COPY_RESOURCE) - { - SAFE_DELETE(end); - - record->PopChunk(); - - continue; - } - - break; - } - record->UnlockChunks(); - - m_pDevice->UnlockForChunkRemoval(); - - record->AddChunk(scope.Get()); - } - - if(pRenderTargetView && m_State == WRITING_CAPFRAME) - { - MarkResourceReferenced(GetViewResourceResID(pRenderTargetView), eFrameRef_Write); - MarkResourceReferenced(GetIDForResource(pRenderTargetView), eFrameRef_Read); + MarkDirtyResource(GetViewResourceResID(pRenderTargetView)); } } +template bool WrappedID3D11DeviceContext::Serialise_ClearUnorderedAccessViewUint( - ID3D11UnorderedAccessView *pUnorderedAccessView, const UINT Values_[4]) + SerialiserType &ser, ID3D11UnorderedAccessView *pUnorderedAccessView, const UINT Values[4]) { - SERIALISE_ELEMENT(ResourceId, View, GetIDForResource(pUnorderedAccessView)); + SERIALISE_ELEMENT(pUnorderedAccessView); + SERIALISE_ELEMENT_ARRAY(Values, FIXED_COUNT(4)); - // at time of writing we don't support the 11.3 DESC1, but for the sake - // of not having to bump serialisation version later we'll serialise that - // version of the descriptor. We can just alias the memory because the only - // difference is some union members got larger. - union + Serialise_DebugMessages(GET_SERIALISER); + + if(IsReplayingAndReading()) { - D3D11_UNORDERED_ACCESS_VIEW_DESC1 Desc1; - D3D11_UNORDERED_ACCESS_VIEW_DESC Desc; - } ViewDesc; - ResourceId resID; - - RDCEraseEl(ViewDesc.Desc1); - - if(m_State >= WRITING) - { - pUnorderedAccessView->GetDesc(&ViewDesc.Desc); - resID = ((WrappedID3D11UnorderedAccessView1 *)pUnorderedAccessView)->GetResourceResID(); - } - - if(m_State >= WRITING || m_pDevice->GetLogVersion() >= 0x000009) - { - m_pSerialiser->Serialise("ViewDesc", ViewDesc.Desc1); - m_pSerialiser->Serialise("resID", resID); - } - - UINT Values[4] = {0}; - - if(m_State >= WRITING) - memcpy(Values, Values_, sizeof(UINT) * 4); - - m_pSerialiser->SerialisePODArray<4>("Values", Values); - - if(m_State <= EXECUTING) - { - if(m_pDevice->GetResourceManager()->HasLiveResource(View)) + if(pUnorderedAccessView) { m_pRealContext->ClearUnorderedAccessViewUint( - UNWRAP(WrappedID3D11UnorderedAccessView1, - m_pDevice->GetResourceManager()->GetLiveResource(View)), - Values); + UNWRAP(WrappedID3D11UnorderedAccessView1, pUnorderedAccessView), Values); } - else if(m_pDevice->GetLogVersion() >= 0x000009) + + if(IsLoading(m_State)) { - // no live view, we have to create one ourselves to clear with. - if(m_pDevice->GetResourceManager()->HasLiveResource(resID)) - { - ID3D11UnorderedAccessView *view = NULL; - m_pDevice->CreateUnorderedAccessView( - (ID3D11Resource *)m_pDevice->GetResourceManager()->GetLiveResource(resID), - &ViewDesc.Desc, &view); - m_pRealContext->ClearUnorderedAccessViewUint( - UNWRAP(WrappedID3D11UnorderedAccessView1, view), Values); - SAFE_RELEASE(view); - } - } - else - { - RDCWARN( - "No view was found to perform clear - data might be wrong. " - "Re-capture with latest RenderDoc to solve this issue."); - } - } + AddEvent(); - const string desc = m_pSerialiser->GetDebugStr(); - - if(m_State == READING) - { - AddEvent(desc); - string name = "ClearUnorderedAccessViewUint(" + ToStr(Values[0]) + ", " + ToStr(Values[1]) + - ", " + ToStr(Values[2]) + ", " + ToStr(Values[3]) + ")"; - - DrawcallDescription draw; - draw.name = name; - - draw.flags |= DrawFlags::Clear; - draw.copyDestination = resID; - - if(m_pDevice->GetResourceManager()->HasLiveResource(View)) - { WrappedID3D11UnorderedAccessView1 *view = - (WrappedID3D11UnorderedAccessView1 *)m_pDevice->GetResourceManager()->GetLiveResource(View); - m_ResourceUses[view->GetResourceResID()].push_back( - EventUsage(m_CurEventID, ResourceUsage::Clear, view->GetResourceID())); - draw.copyDestination = m_pDevice->GetResourceManager()->GetOriginalID(view->GetResourceResID()); - } + (WrappedID3D11UnorderedAccessView1 *)pUnorderedAccessView; - AddDrawcall(draw, true); + DrawcallDescription draw; + draw.name = StringFormat::Fmt("ClearUnorderedAccessViewUint(%u, %u, %u, %u)", Values[0], + Values[1], Values[2], Values[3]); + draw.flags |= DrawFlags::Clear; + draw.copyDestination = GetResourceManager()->GetOriginalID(view->GetResourceResID()); + + if(view) + { + m_ResourceUses[view->GetResourceResID()].push_back( + EventUsage(m_CurEventID, ResourceUsage::Clear, view->GetResourceID())); + draw.copyDestination = + m_pDevice->GetResourceManager()->GetOriginalID(view->GetResourceResID()); + } + + AddDrawcall(draw, true); + } } return true; @@ -6542,154 +5994,73 @@ void WrappedID3D11DeviceContext::ClearUnorderedAccessViewUint( { m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) + m_pRealContext->ClearUnorderedAccessViewUint( + UNWRAP(WrappedID3D11UnorderedAccessView1, pUnorderedAccessView), Values); + + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(CLEAR_UAV_INT); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_ClearUnorderedAccessViewUint(pUnorderedAccessView, Values); + USE_SCRATCH_SERIALISER(); + GET_SERIALISER.SetDrawChunk(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::ClearUnorderedAccessViewUint); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_ClearUnorderedAccessViewUint(GET_SERIALISER, pUnorderedAccessView, Values); + + if(pUnorderedAccessView) + { + MarkResourceReferenced(GetViewResourceResID(pUnorderedAccessView), eFrameRef_Write); + MarkResourceReferenced(GetIDForResource(pUnorderedAccessView), eFrameRef_Read); + } m_MissingTracks.insert(GetViewResourceResID(pUnorderedAccessView)); m_ContextRecord->AddChunk(scope.Get()); } - else if(m_State >= WRITING) + else if(IsBackgroundCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(CLEAR_UAV_INT); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_ClearUnorderedAccessViewUint(pUnorderedAccessView, Values); - - D3D11ResourceRecord *record = m_pDevice->GetResourceManager()->GetResourceRecord( - GetViewResourceResID(pUnorderedAccessView)); - RDCASSERT(record); - - m_pDevice->LockForChunkRemoval(); - - record->LockChunks(); - for(;;) - { - Chunk *end = record->GetLastChunk(); - - if(end->GetChunkType() == CLEAR_RTV || end->GetChunkType() == CLEAR_DSV || - end->GetChunkType() == CLEAR_UAV_FLOAT || end->GetChunkType() == CLEAR_UAV_INT || - end->GetChunkType() == RESOLVE_SUBRESOURCE || end->GetChunkType() == COPY_RESOURCE) - { - SAFE_DELETE(end); - - record->PopChunk(); - - continue; - } - - break; - } - record->UnlockChunks(); - - m_pDevice->UnlockForChunkRemoval(); - - record->AddChunk(scope.Get()); + MarkDirtyResource(GetViewResourceResID(pUnorderedAccessView)); } - - if(pUnorderedAccessView && m_State == WRITING_CAPFRAME) - { - MarkResourceReferenced(GetViewResourceResID(pUnorderedAccessView), eFrameRef_Write); - MarkResourceReferenced(GetIDForResource(pUnorderedAccessView), eFrameRef_Read); - } - - m_pRealContext->ClearUnorderedAccessViewUint( - UNWRAP(WrappedID3D11UnorderedAccessView1, pUnorderedAccessView), Values); } +template bool WrappedID3D11DeviceContext::Serialise_ClearUnorderedAccessViewFloat( - ID3D11UnorderedAccessView *pUnorderedAccessView, const FLOAT Values_[4]) + SerialiserType &ser, ID3D11UnorderedAccessView *pUnorderedAccessView, const FLOAT Values[4]) { - SERIALISE_ELEMENT(ResourceId, View, GetIDForResource(pUnorderedAccessView)); + SERIALISE_ELEMENT(pUnorderedAccessView); + SERIALISE_ELEMENT_ARRAY(Values, FIXED_COUNT(4)); - // at time of writing we don't support the 11.3 DESC1, but for the sake - // of not having to bump serialisation version later we'll serialise that - // version of the descriptor. We can just alias the memory because the only - // difference is some union members got larger. - union + Serialise_DebugMessages(GET_SERIALISER); + + if(IsReplayingAndReading()) { - D3D11_UNORDERED_ACCESS_VIEW_DESC1 Desc1; - D3D11_UNORDERED_ACCESS_VIEW_DESC Desc; - } ViewDesc; - ResourceId resID; - - RDCEraseEl(ViewDesc.Desc1); - - if(m_State >= WRITING) - { - pUnorderedAccessView->GetDesc(&ViewDesc.Desc); - resID = ((WrappedID3D11UnorderedAccessView1 *)pUnorderedAccessView)->GetResourceResID(); - } - - if(m_State >= WRITING || m_pDevice->GetLogVersion() >= 0x000009) - { - m_pSerialiser->Serialise("ViewDesc", ViewDesc.Desc1); - m_pSerialiser->Serialise("resID", resID); - } - - FLOAT Values[4] = {0}; - - if(m_State >= WRITING) - memcpy(Values, Values_, sizeof(FLOAT) * 4); - - m_pSerialiser->SerialisePODArray<4>("Values", Values); - - if(m_State <= EXECUTING) - { - if(m_pDevice->GetResourceManager()->HasLiveResource(View)) + if(pUnorderedAccessView) { m_pRealContext->ClearUnorderedAccessViewFloat( - UNWRAP(WrappedID3D11UnorderedAccessView1, - m_pDevice->GetResourceManager()->GetLiveResource(View)), - Values); + UNWRAP(WrappedID3D11UnorderedAccessView1, pUnorderedAccessView), Values); } - else if(m_pDevice->GetLogVersion() >= 0x000009) + + if(IsLoading(m_State)) { - // no live view, we have to create one ourselves to clear with. - if(m_pDevice->GetResourceManager()->HasLiveResource(resID)) - { - ID3D11UnorderedAccessView *view = NULL; - m_pDevice->CreateUnorderedAccessView( - (ID3D11Resource *)m_pDevice->GetResourceManager()->GetLiveResource(resID), - &ViewDesc.Desc, &view); - m_pRealContext->ClearUnorderedAccessViewFloat( - UNWRAP(WrappedID3D11UnorderedAccessView1, view), Values); - SAFE_RELEASE(view); - } - } - else - { - RDCWARN( - "No view was found to perform clear - data might be wrong. " - "Re-capture with latest RenderDoc to solve this issue."); - } - } + AddEvent(); - const string desc = m_pSerialiser->GetDebugStr(); - - if(m_State == READING) - { - AddEvent(desc); - string name = "ClearUnorderedAccessViewFloat(" + ToStr(Values[0]) + ", " + ToStr(Values[1]) + - ", " + ToStr(Values[2]) + ", " + ToStr(Values[3]) + ", " + ")"; - - DrawcallDescription draw; - draw.name = (name); - draw.flags |= DrawFlags::Clear; - draw.copyDestination = resID; - - if(m_pDevice->GetResourceManager()->HasLiveResource(View)) - { WrappedID3D11UnorderedAccessView1 *view = - (WrappedID3D11UnorderedAccessView1 *)m_pDevice->GetResourceManager()->GetLiveResource(View); - m_ResourceUses[view->GetResourceResID()].push_back( - EventUsage(m_CurEventID, ResourceUsage::Clear, view->GetResourceID())); - draw.copyDestination = m_pDevice->GetResourceManager()->GetOriginalID(view->GetResourceResID()); - } + (WrappedID3D11UnorderedAccessView1 *)pUnorderedAccessView; - AddDrawcall(draw, true); + DrawcallDescription draw; + draw.name = StringFormat::Fmt("ClearUnorderedAccessViewFloat(%f, %f, %f, %f)", Values[0], + Values[1], Values[2], Values[3]); + draw.flags |= DrawFlags::Clear; + draw.copyDestination = GetResourceManager()->GetOriginalID(view->GetResourceResID()); + + if(view) + { + m_ResourceUses[view->GetResourceResID()].push_back( + EventUsage(m_CurEventID, ResourceUsage::Clear, view->GetResourceID())); + draw.copyDestination = + m_pDevice->GetResourceManager()->GetOriginalID(view->GetResourceResID()); + } + + AddDrawcall(draw, true); + } } return true; @@ -6700,141 +6071,81 @@ void WrappedID3D11DeviceContext::ClearUnorderedAccessViewFloat( { m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) + m_pRealContext->ClearUnorderedAccessViewFloat( + UNWRAP(WrappedID3D11UnorderedAccessView1, pUnorderedAccessView), Values); + + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(CLEAR_UAV_FLOAT); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_ClearUnorderedAccessViewFloat(pUnorderedAccessView, Values); + USE_SCRATCH_SERIALISER(); + GET_SERIALISER.SetDrawChunk(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::ClearUnorderedAccessViewFloat); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_ClearUnorderedAccessViewFloat(GET_SERIALISER, pUnorderedAccessView, Values); + + if(pUnorderedAccessView) + { + MarkResourceReferenced(GetViewResourceResID(pUnorderedAccessView), eFrameRef_Write); + MarkResourceReferenced(GetIDForResource(pUnorderedAccessView), eFrameRef_Read); + } m_MissingTracks.insert(GetViewResourceResID(pUnorderedAccessView)); m_ContextRecord->AddChunk(scope.Get()); } - else if(m_State >= WRITING) + else if(IsBackgroundCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(CLEAR_UAV_FLOAT); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_ClearUnorderedAccessViewFloat(pUnorderedAccessView, Values); - - D3D11ResourceRecord *record = m_pDevice->GetResourceManager()->GetResourceRecord( - GetViewResourceResID(pUnorderedAccessView)); - RDCASSERT(record); - - m_pDevice->LockForChunkRemoval(); - - record->LockChunks(); - for(;;) - { - Chunk *end = record->GetLastChunk(); - - if(end->GetChunkType() == CLEAR_RTV || end->GetChunkType() == CLEAR_DSV || - end->GetChunkType() == CLEAR_UAV_FLOAT || end->GetChunkType() == CLEAR_UAV_INT || - end->GetChunkType() == RESOLVE_SUBRESOURCE || end->GetChunkType() == COPY_RESOURCE) - { - SAFE_DELETE(end); - - record->PopChunk(); - - continue; - } - - break; - } - record->UnlockChunks(); - - m_pDevice->UnlockForChunkRemoval(); - - record->AddChunk(scope.Get()); + MarkDirtyResource(GetViewResourceResID(pUnorderedAccessView)); } - - if(pUnorderedAccessView && m_State == WRITING_CAPFRAME) - { - MarkResourceReferenced(GetViewResourceResID(pUnorderedAccessView), eFrameRef_Write); - MarkResourceReferenced(GetIDForResource(pUnorderedAccessView), eFrameRef_Read); - } - - m_pRealContext->ClearUnorderedAccessViewFloat( - UNWRAP(WrappedID3D11UnorderedAccessView1, pUnorderedAccessView), Values); } +template bool WrappedID3D11DeviceContext::Serialise_ClearDepthStencilView( - ID3D11DepthStencilView *pDepthStencilView, UINT ClearFlags_, FLOAT Depth_, UINT8 Stencil_) + SerialiserType &ser, ID3D11DepthStencilView *pDepthStencilView, UINT ClearFlags, FLOAT Depth, + UINT8 Stencil) { - SERIALISE_ELEMENT(ResourceId, View, GetIDForResource(pDepthStencilView)); - SERIALISE_ELEMENT(uint32_t, ClearFlags, ClearFlags_); - SERIALISE_ELEMENT(float, Depth, Depth_); - SERIALISE_ELEMENT(uint8_t, Stencil, Stencil_); + SERIALISE_ELEMENT(pDepthStencilView); + SERIALISE_ELEMENT_TYPED(D3D11_CLEAR_FLAG, ClearFlags); + SERIALISE_ELEMENT(Depth); + SERIALISE_ELEMENT(Stencil); - D3D11_DEPTH_STENCIL_VIEW_DESC ViewDesc = {}; - ResourceId resID; + Serialise_DebugMessages(GET_SERIALISER); - if(m_State >= WRITING) + if(IsReplayingAndReading()) { - pDepthStencilView->GetDesc(&ViewDesc); - resID = ((WrappedID3D11DepthStencilView *)pDepthStencilView)->GetResourceResID(); - } - - if(m_State >= WRITING || m_pDevice->GetLogVersion() >= 0x000009) - { - m_pSerialiser->Serialise("ViewDesc", ViewDesc); - m_pSerialiser->Serialise("resID", resID); - } - - if(m_State <= EXECUTING) - { - if(m_pDevice->GetResourceManager()->HasLiveResource(View)) + if(pDepthStencilView) { m_pRealContext->ClearDepthStencilView( - UNWRAP(WrappedID3D11DepthStencilView, - m_pDevice->GetResourceManager()->GetLiveResource(View)), - ClearFlags, Depth, Stencil); + UNWRAP(WrappedID3D11DepthStencilView, pDepthStencilView), ClearFlags, Depth, Stencil); } - else if(m_pDevice->GetLogVersion() >= 0x000009) + + if(IsLoading(m_State)) { - // no live view, we have to create one ourselves to clear with. - if(m_pDevice->GetResourceManager()->HasLiveResource(resID)) + AddEvent(); + + WrappedID3D11DepthStencilView *view = (WrappedID3D11DepthStencilView *)pDepthStencilView; + + DrawcallDescription draw; + if(ClearFlags == (D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL)) + draw.name = StringFormat::Fmt("ClearDepthStencilView(D=%f, S=%02hhx)", Depth, Stencil); + else if(ClearFlags == D3D11_CLEAR_DEPTH) + draw.name = StringFormat::Fmt("ClearDepthStencilView(D=%f)", Depth); + else if(ClearFlags == D3D11_CLEAR_STENCIL) + draw.name = StringFormat::Fmt("ClearDepthStencilView(S=%02hhx)", Stencil); + else + draw.name = "ClearDepthStencilView(None)"; + draw.flags |= DrawFlags::Clear | DrawFlags::ClearDepthStencil; + draw.copyDestination = GetResourceManager()->GetOriginalID(view->GetResourceResID()); + + if(view) { - ID3D11DepthStencilView *view = NULL; - m_pDevice->CreateDepthStencilView( - (ID3D11Resource *)m_pDevice->GetResourceManager()->GetLiveResource(resID), &ViewDesc, - &view); - m_pRealContext->ClearDepthStencilView(UNWRAP(WrappedID3D11DepthStencilView, view), - ClearFlags, Depth, Stencil); - SAFE_RELEASE(view); + m_ResourceUses[view->GetResourceResID()].push_back( + EventUsage(m_CurEventID, ResourceUsage::Clear, view->GetResourceID())); + draw.copyDestination = + m_pDevice->GetResourceManager()->GetOriginalID(view->GetResourceResID()); } + + AddDrawcall(draw, true); } - else - { - RDCWARN( - "No view was found to perform clear - data might be wrong. " - "Re-capture with latest RenderDoc to solve this issue."); - } - } - - const string desc = m_pSerialiser->GetDebugStr(); - - Serialise_DebugMessages(); - - if(m_State == READING) - { - AddEvent(desc); - string name = "ClearDepthStencilView(" + ToStr(Depth) + ", " + ToStr(Stencil) + ")"; - - DrawcallDescription draw; - draw.name = name; - draw.flags |= DrawFlags::Clear | DrawFlags::ClearDepthStencil; - draw.copyDestination = resID; - - if(m_pDevice->GetResourceManager()->HasLiveResource(View)) - { - WrappedID3D11DepthStencilView *view = - (WrappedID3D11DepthStencilView *)m_pDevice->GetResourceManager()->GetLiveResource(View); - m_ResourceUses[view->GetResourceResID()].push_back( - EventUsage(m_CurEventID, ResourceUsage::Clear, view->GetResourceID())); - draw.copyDestination = m_pDevice->GetResourceManager()->GetOriginalID(view->GetResourceResID()); - } - - AddDrawcall(draw, true); } return true; @@ -6853,57 +6164,27 @@ void WrappedID3D11DeviceContext::ClearDepthStencilView(ID3D11DepthStencilView *p m_pRealContext->ClearDepthStencilView(UNWRAP(WrappedID3D11DepthStencilView, pDepthStencilView), ClearFlags, Depth, Stencil); - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(CLEAR_DSV); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_ClearDepthStencilView(pDepthStencilView, ClearFlags, Depth, Stencil); + USE_SCRATCH_SERIALISER(); + GET_SERIALISER.SetDrawChunk(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::ClearDepthStencilView); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_ClearDepthStencilView(GET_SERIALISER, pDepthStencilView, ClearFlags, Depth, Stencil); + + if(pDepthStencilView) + { + MarkResourceReferenced(GetViewResourceResID(pDepthStencilView), eFrameRef_Write); + MarkResourceReferenced(GetIDForResource(pDepthStencilView), eFrameRef_Read); + } m_MissingTracks.insert(GetViewResourceResID(pDepthStencilView)); m_ContextRecord->AddChunk(scope.Get()); } - else if(m_State >= WRITING) + else if(IsBackgroundCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(CLEAR_DSV); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_ClearDepthStencilView(pDepthStencilView, ClearFlags, Depth, Stencil); - - D3D11ResourceRecord *record = - m_pDevice->GetResourceManager()->GetResourceRecord(GetViewResourceResID(pDepthStencilView)); - RDCASSERT(record); - - m_pDevice->LockForChunkRemoval(); - - record->LockChunks(); - for(;;) - { - Chunk *end = record->GetLastChunk(); - - if(end->GetChunkType() == CLEAR_RTV || end->GetChunkType() == CLEAR_DSV || - end->GetChunkType() == CLEAR_UAV_FLOAT || end->GetChunkType() == CLEAR_UAV_INT || - end->GetChunkType() == RESOLVE_SUBRESOURCE || end->GetChunkType() == COPY_RESOURCE) - { - SAFE_DELETE(end); - - record->PopChunk(); - - continue; - } - - break; - } - record->UnlockChunks(); - - m_pDevice->UnlockForChunkRemoval(); - - record->AddChunk(scope.Get()); - } - - if(pDepthStencilView && m_State == WRITING_CAPFRAME) - { - MarkResourceReferenced(GetViewResourceResID(pDepthStencilView), eFrameRef_Write); - MarkResourceReferenced(GetIDForResource(pDepthStencilView), eFrameRef_Read); + MarkDirtyResource(GetViewResourceResID(pDepthStencilView)); } } @@ -6911,33 +6192,10 @@ void WrappedID3D11DeviceContext::ClearDepthStencilView(ID3D11DepthStencilView *p #pragma region Misc -bool WrappedID3D11DeviceContext::Serialise_Begin(ID3D11Asynchronous *pAsync) +template +bool WrappedID3D11DeviceContext::Serialise_Begin(SerialiserType &ser, ID3D11Asynchronous *pAsync) { - SERIALISE_ELEMENT(ResourceId, Async, GetIDForResource(pAsync)); - - SERIALISE_ELEMENT(bool, IsQuery, WrappedID3D11Query1::IsAlloc(pAsync)); - - if(IsQuery) - { - D3D11_QUERY qt = D3D11_QUERY_EVENT; - - if(m_State >= WRITING) - { - D3D11_QUERY_DESC desc; - ID3D11Query *q = (ID3D11Query *)pAsync; - q->GetDesc(&desc); - - qt = desc.Query; - } - - SERIALISE_ELEMENT(D3D11_QUERY, QueryType, qt); - } - - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(Async)) - { - // m_pImmediateContext->Begin((ID3D11Asynchronous - // *)m_pDevice->GetResourceManager()->GetLiveResource(Async)); - } + SERIALISE_ELEMENT(pAsync); return true; } @@ -6955,11 +6213,12 @@ void WrappedID3D11DeviceContext::Begin(ID3D11Asynchronous *pAsync) else RDCERR("Unexpected ID3D11Asynchronous"); - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(BEGIN); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_Begin(pAsync); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::Begin); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_Begin(GET_SERIALISER, pAsync); m_ContextRecord->AddChunk(scope.Get()); } @@ -6967,33 +6226,10 @@ void WrappedID3D11DeviceContext::Begin(ID3D11Asynchronous *pAsync) m_pRealContext->Begin(unwrapped); } -bool WrappedID3D11DeviceContext::Serialise_End(ID3D11Asynchronous *pAsync) +template +bool WrappedID3D11DeviceContext::Serialise_End(SerialiserType &ser, ID3D11Asynchronous *pAsync) { - SERIALISE_ELEMENT(ResourceId, Async, GetIDForResource(pAsync)); - - SERIALISE_ELEMENT(bool, IsQuery, WrappedID3D11Query1::IsAlloc(pAsync)); - - if(IsQuery) - { - D3D11_QUERY qt = D3D11_QUERY_EVENT; - - if(m_State >= WRITING) - { - D3D11_QUERY_DESC desc; - ID3D11Query *q = (ID3D11Query *)pAsync; - q->GetDesc(&desc); - - qt = desc.Query; - } - - SERIALISE_ELEMENT(D3D11_QUERY, QueryType, qt); - } - - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(Async)) - { - // m_pImmediateContext->End((ID3D11Asynchronous - // *)m_pDevice->GetResourceManager()->GetLiveResource(Async)); - } + SERIALISE_ELEMENT(pAsync); return true; } @@ -7011,11 +6247,12 @@ void WrappedID3D11DeviceContext::End(ID3D11Asynchronous *pAsync) else RDCERR("Unexpected ID3D11Asynchronous"); - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(BEGIN); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_End(pAsync); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::End); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_End(GET_SERIALISER, pAsync); m_ContextRecord->AddChunk(scope.Get()); } @@ -7040,19 +6277,17 @@ HRESULT WrappedID3D11DeviceContext::GetData(ID3D11Asynchronous *pAsync, void *pD return m_pRealContext->GetData(unwrapped, pData, DataSize, GetDataFlags); } -bool WrappedID3D11DeviceContext::Serialise_SetPredication(ID3D11Predicate *pPredicate, +template +bool WrappedID3D11DeviceContext::Serialise_SetPredication(SerialiserType &ser, + ID3D11Predicate *pPredicate, BOOL PredicateValue_) { - SERIALISE_ELEMENT(ResourceId, Predicate, GetIDForResource(pPredicate)); - SERIALISE_ELEMENT(uint8_t, PredicateValue, PredicateValue_ == TRUE); + SERIALISE_ELEMENT(pPredicate); + SERIALISE_ELEMENT_LOCAL(PredicateValue, PredicateValue_ == TRUE); - if(m_State <= EXECUTING) + if(IsReplayingAndReading()) { - pPredicate = NULL; - if(m_pDevice->GetResourceManager()->HasLiveResource(Predicate)) - pPredicate = UNWRAP(WrappedID3D11Predicate, - m_pDevice->GetResourceManager()->GetLiveResource(Predicate)); - m_pRealContext->SetPredication(pPredicate, PredicateValue); + m_pRealContext->SetPredication(pPredicate, PredicateValue ? TRUE : FALSE); } return true; @@ -7062,11 +6297,12 @@ void WrappedID3D11DeviceContext::SetPredication(ID3D11Predicate *pPredicate, BOO { m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(SET_PREDICATION); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_SetPredication(pPredicate, PredicateValue); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::SetPredication); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_SetPredication(GET_SERIALISER, pPredicate, PredicateValue); m_ContextRecord->AddChunk(scope.Get()); } @@ -7079,15 +6315,17 @@ FLOAT WrappedID3D11DeviceContext::GetResourceMinLOD(ID3D11Resource *pResource) return m_pRealContext->GetResourceMinLOD(m_pDevice->GetResourceManager()->UnwrapResource(pResource)); } -bool WrappedID3D11DeviceContext::Serialise_SetResourceMinLOD(ID3D11Resource *pResource, FLOAT MinLOD_) +template +bool WrappedID3D11DeviceContext::Serialise_SetResourceMinLOD(SerialiserType &ser, + ID3D11Resource *pResource, FLOAT MinLOD) { - SERIALISE_ELEMENT(ResourceId, Resource, GetIDForResource(pResource)); - SERIALISE_ELEMENT(float, MinLOD, MinLOD_); + SERIALISE_ELEMENT(pResource); + SERIALISE_ELEMENT(MinLOD); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(Resource)) + if(IsReplayingAndReading()) { - m_pRealContext->SetResourceMinLOD( - (ID3D11Resource *)m_pDevice->GetResourceManager()->GetLiveResource(Resource), MinLOD); + if(pResource) + m_pRealContext->SetResourceMinLOD(pResource, MinLOD); } return true; @@ -7097,11 +6335,12 @@ void WrappedID3D11DeviceContext::SetResourceMinLOD(ID3D11Resource *pResource, FL { m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(SET_RESOURCE_MINLOD); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_SetResourceMinLOD(pResource, MinLOD); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::SetResourceMinLOD); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_SetResourceMinLOD(GET_SERIALISER, pResource, MinLOD); m_ContextRecord->AddChunk(scope.Get()); } @@ -7348,10 +6587,21 @@ void MapIntercept::CopyToD3D(size_t RangeStart, size_t RangeEnd) } } -bool WrappedID3D11DeviceContext::Serialise_Map(ID3D11Resource *pResource, UINT Subresource, - D3D11_MAP MapType, UINT MapFlags, +template +bool WrappedID3D11DeviceContext::Serialise_Map(SerialiserType &ser, ID3D11Resource *pResource, + UINT Subresource, D3D11_MAP MapType, UINT MapFlags, D3D11_MAPPED_SUBRESOURCE *pMappedResource) { + // unused - just for the user's benefit + SERIALISE_ELEMENT(pResource); + SERIALISE_ELEMENT(Subresource); + SERIALISE_ELEMENT(MapType); + SERIALISE_ELEMENT_TYPED(D3D11_MAP_FLAG, MapFlags); + + // nothing to do on replay, all the work happens in Unmap. + if(ser.IsReading()) + return true; + D3D11_MAPPED_SUBRESOURCE mappedResource = D3D11_MAPPED_SUBRESOURCE(); if(pMappedResource) @@ -7360,9 +6610,6 @@ bool WrappedID3D11DeviceContext::Serialise_Map(ID3D11Resource *pResource, UINT S D3D11ResourceRecord *record = m_pDevice->GetResourceManager()->GetResourceRecord(GetIDForResource(pResource)); - // we only serialise out unmap - should never hit this on read. - RDCASSERT(m_State >= WRITING); - RDCASSERT(record); if(record->NumSubResources > (int)Subresource) @@ -7372,7 +6619,7 @@ bool WrappedID3D11DeviceContext::Serialise_Map(ID3D11Resource *pResource, UINT S size_t mapLength = (size_t)record->Length; - if(m_State == WRITING_CAPFRAME || (record && !record->DataInSerialiser)) + if(IsActiveCapturing(m_State) || (record && !record->DataInSerialiser)) { ResourceId Resource = GetIDForResource(pResource); @@ -7476,7 +6723,7 @@ bool WrappedID3D11DeviceContext::Serialise_Map(ID3D11Resource *pResource, UINT S m_OpenMaps[MappedResource(Resource, Subresource)] = intercept; } - else if(m_State == WRITING_IDLE) + else if(IsBackgroundCapturing(m_State)) { RDCASSERT(record->DataInSerialiser); @@ -7563,23 +6810,23 @@ HRESULT WrappedID3D11DeviceContext::Map(ID3D11Resource *pResource, UINT Subresou ResourceId id = GetIDForResource(pResource); bool directMap = false; - if(m_HighTrafficResources.find(id) != m_HighTrafficResources.end() && m_State != WRITING_CAPFRAME) + if(m_HighTrafficResources.find(id) != m_HighTrafficResources.end() && !IsActiveCapturing(m_State)) directMap = true; if(m_pDevice->GetResourceManager()->IsResourceDirty(GetIDForResource(pResource)) && - m_State != WRITING_CAPFRAME) + !IsActiveCapturing(m_State)) directMap = true; - if((!directMap && MapType == D3D11_MAP_WRITE_NO_OVERWRITE && m_State != WRITING_CAPFRAME) || + if((!directMap && MapType == D3D11_MAP_WRITE_NO_OVERWRITE && !IsActiveCapturing(m_State)) || m_pRealContext->GetType() == D3D11_DEVICE_CONTEXT_DEFERRED) { directMap = true; m_HighTrafficResources.insert(id); - if(m_State != WRITING_CAPFRAME) + if(!IsActiveCapturing(m_State)) MarkDirtyResource(id); } - if(directMap && m_State == WRITING_IDLE) + if(directMap && IsBackgroundCapturing(m_State)) { return m_pRealContext->Map(m_pDevice->GetResourceManager()->UnwrapResource(pResource), Subresource, MapType, MapFlags, pMappedResource); @@ -7591,9 +6838,9 @@ HRESULT WrappedID3D11DeviceContext::Map(ID3D11Resource *pResource, UINT Subresou MapType == D3D11_MAP_WRITE_NO_OVERWRITE ? D3D11_MAP_WRITE_DISCARD : MapType, MapFlags, pMappedResource); - if(SUCCEEDED(ret)) + if(SUCCEEDED(ret) && IsCaptureMode(m_State)) { - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { if(MapType == D3D11_MAP_READ) { @@ -7607,10 +6854,16 @@ HRESULT WrappedID3D11DeviceContext::Map(ID3D11Resource *pResource, UINT Subresou { m_MissingTracks.insert(GetIDForResource(pResource)); - Serialise_Map(pResource, Subresource, MapType, MapFlags, pMappedResource); + // create a chunk purely for the user's benefit + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::Map); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_Map(GET_SERIALISER, pResource, Subresource, MapType, MapFlags, pMappedResource); + + m_ContextRecord->AddChunk(scope.Get()); } } - else if(m_State >= WRITING) + else // IsIdleCapturing(m_State) { RDCASSERT(WrappedID3D11Buffer::IsAlloc(pResource) || WrappedID3D11Texture1D::IsAlloc(pResource) || @@ -7625,8 +6878,7 @@ HRESULT WrappedID3D11DeviceContext::Map(ID3D11Resource *pResource, UINT Subresou if(record->NumSubResources > (int)Subresource) record = (D3D11ResourceRecord *)record->SubResources[Subresource]; - if(RenderDoc::Inst().GetCaptureOptions().VerifyMapWrites == 0) - record->UpdateCount++; + record->UpdateCount++; if(record->UpdateCount > 60 && RenderDoc::Inst().GetCaptureOptions().VerifyMapWrites == 0) { @@ -7636,67 +6888,70 @@ HRESULT WrappedID3D11DeviceContext::Map(ID3D11Resource *pResource, UINT Subresou return ret; } - Serialise_Map(pResource, Subresource, MapType, MapFlags, pMappedResource); + // don't need to create a chunk but we do need to prepare the map. + Serialise_Map(m_ScratchSerialiser, pResource, Subresource, MapType, MapFlags, pMappedResource); + + // throw away any serialised data + m_ScratchSerialiser.GetWriter()->Rewind(); } } return ret; } -bool WrappedID3D11DeviceContext::Serialise_Unmap(ID3D11Resource *pResource, UINT Subresource_) +template +bool WrappedID3D11DeviceContext::Serialise_Unmap(SerialiserType &ser, ID3D11Resource *pResource, + UINT Subresource) { - MappedResource mapIdx; + SERIALISE_ELEMENT(pResource); + SERIALISE_ELEMENT(Subresource); + MappedResource mapIdx(GetIDForResource(pResource), Subresource); + MapIntercept intercept; + int ctxMapID = 0; D3D11ResourceRecord *record = NULL; - if(m_State >= WRITING) + size_t len = 0; + uint32_t diffStart = 0; + uint32_t diffEnd = 0; + + byte *MapWrittenData = NULL; + + // handle book-keeping during capture mode + if(ser.IsWriting()) { record = m_pDevice->GetResourceManager()->GetResourceRecord(GetIDForResource(pResource)); RDCASSERT(record); - if(record->NumSubResources > (int)Subresource_) - record = (D3D11ResourceRecord *)record->SubResources[Subresource_]; - } + if((int)Subresource < record->NumSubResources) + record = (D3D11ResourceRecord *)record->SubResources[Subresource]; - if(m_State < WRITING || m_State == WRITING_CAPFRAME || !record->DataInSerialiser) - { - SERIALISE_ELEMENT(ResourceId, Resource, GetIDForResource(pResource)); - SERIALISE_ELEMENT(uint32_t, Subresource, Subresource_); + len = (size_t)record->Length; + diffEnd = (uint32_t)len; - mapIdx = MappedResource(Resource, Subresource); - } - else if(m_State == WRITING_IDLE) - { - mapIdx = MappedResource(GetIDForResource(pResource), Subresource_); - } - - MapIntercept intercept; - - int ctxMapID = 0; - - if(m_State >= WRITING) - { + // locate the intercept data and remove it from the open maps list auto it = m_OpenMaps.find(mapIdx); - RDCASSERT(it != m_OpenMaps.end()); - intercept = it->second; - m_OpenMaps.erase(it); + MapWrittenData = (byte *)intercept.app.pData; + + // store the context ID we used for this map's shadow pointers if(GetType() == D3D11_DEVICE_CONTEXT_DEFERRED && - (m_State == WRITING_CAPFRAME || intercept.verifyWrite)) + (IsActiveCapturing(m_State) || intercept.verifyWrite)) { ctxMapID = m_MapResourceRecordAllocs[mapIdx.resource]; RDCASSERT(ctxMapID != 0); } + // if we were verifying this map, then make sure the shadow storage is still safe if(intercept.verifyWrite && record) { if(!record->VerifyShadowStorage(ctxMapID)) { - string msg = StringFormat::Fmt( + std::string msg = StringFormat::Fmt( "Overwrite of %llu byte Map()'d buffer detected\n" "Breakpoint now to see callstack,\nor click 'Yes' to debugbreak.", record->Length); @@ -7706,32 +6961,40 @@ bool WrappedID3D11DeviceContext::Serialise_Unmap(ID3D11Resource *pResource, UINT OS_DEBUG_BREAK(); } } + + if(IsBackgroundCapturing(m_State)) + { + // if there was already backing store then normally the user wrote directly into it so we + // don't even have to update anything, except in the case where we were verifying map + // writes. Then we need to copy from the verification shadow buffer into the backing store. + memcpy(record->GetDataPtr(), intercept.app.pData, len); + } } - } - if(m_State < WRITING || m_State == WRITING_CAPFRAME) - { - size_t len = record ? (size_t)record->Length : 0; + // copy from the intercept buffer that the user wrote into, into D3D's real pointer + intercept.CopyToD3D(); - byte *appWritePtr = NULL; - - appWritePtr = (byte *)intercept.app.pData; - - size_t diffStart = 0; - size_t diffEnd = len; - - if(m_State == WRITING_CAPFRAME && len > 512 && intercept.MapType != D3D11_MAP_WRITE_DISCARD) + // while actively capturing, on large buffers being updated, try to locate the range of data + // being + // updated and update the diffStart/diffEnd/len variables + if(IsActiveCapturing(m_State) && len > 512 && intercept.MapType != D3D11_MAP_WRITE_DISCARD) { - bool found = - FindDiffRange(appWritePtr, record->GetShadowPtr(ctxMapID, 1), len, diffStart, diffEnd); + size_t s = diffStart; + size_t e = diffEnd; + bool found = FindDiffRange(MapWrittenData, record->GetShadowPtr(ctxMapID, 1), len, s, e); + diffStart = (uint32_t)s; + diffEnd = (uint32_t)e; + if(found) { +#if ENABLED(RDOC_DEVEL) static size_t saved = 0; saved += len - (diffEnd - diffStart); RDCDEBUG("Mapped resource size %u, difference: %u -> %u. Total bytes saved so far: %u", (uint32_t)len, (uint32_t)diffStart, (uint32_t)diffEnd, (uint32_t)saved); +#endif len = diffEnd - diffStart; } @@ -7740,146 +7003,121 @@ bool WrappedID3D11DeviceContext::Serialise_Unmap(ID3D11Resource *pResource, UINT diffStart = 0; diffEnd = 0; - len = 1; + len = 0; } + + // update the data pointer to be rebased to the start of the diff data. + MapWrittenData += diffStart; } - appWritePtr += diffStart; - if(m_State == WRITING_CAPFRAME && record->GetShadowPtr(ctxMapID, 1)) + // update shadow stores for future diff'ing + if(IsActiveCapturing(m_State) && record->GetShadowPtr(ctxMapID, 1)) { - memcpy(record->GetShadowPtr(ctxMapID, 1) + diffStart, appWritePtr, diffEnd - diffStart); + memcpy(record->GetShadowPtr(ctxMapID, 1) + diffStart, MapWrittenData, diffEnd - diffStart); } + } // if(ser.IsWriting()) - SERIALISE_ELEMENT(D3D11_MAP, MapType, intercept.MapType); - SERIALISE_ELEMENT(uint32_t, MapFlags, intercept.MapFlags); + // if we're not actively capturing a frame, we'll skip serialising all this data for nothing as we + // aren't going to save the chunk anywhere. The exception is if there's no backing store for this + // resource - then we need to serialise into the chunk to allocate it + bool SerialiseMap = ser.IsReading() || (ser.IsWriting() && IsActiveCapturing(m_State)) || + (ser.IsWriting() && !record->DataInSerialiser); - SERIALISE_ELEMENT(uint32_t, DiffStart, (uint32_t)diffStart); - SERIALISE_ELEMENT(uint32_t, DiffEnd, (uint32_t)diffEnd); + if(SerialiseMap) + { + SERIALISE_ELEMENT(intercept.MapType).Named("MapType"); + SERIALISE_ELEMENT_TYPED(D3D11_MAP_FLAG, intercept.MapFlags).Named("MapFlags"); - if(m_State >= WRITING || m_pDevice->GetLogVersion() >= 0x000007) - m_pSerialiser->AlignNextBuffer(32); + SERIALISE_ELEMENT(diffStart).Named("Byte offset to start of written data"); + SERIALISE_ELEMENT(diffEnd).Named("Byte offset to end of written data"); - m_pSerialiser->SerialiseBuffer("MapData", appWritePtr, len); + SERIALISE_ELEMENT_ARRAY(MapWrittenData, len); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(mapIdx.resource)) + if(ser.IsWriting()) { - intercept.app.pData = appWritePtr; + record->DataInSerialiser = true; + record->SetDataOffset(ser.GetWriter()->GetOffset() - (uint64_t)len); + } + else if(IsReplayingAndReading() && pResource) + { + // steal the allocated buffer, and manually release + intercept.app.pData = MapWrittenData; + MapWrittenData = NULL; + } + } - ID3D11Resource *res = - (ID3D11Resource *)m_pDevice->GetResourceManager()->GetLiveResource(mapIdx.resource); + if(IsReplayingAndReading() && pResource) + { + MapWrittenData = (byte *)intercept.app.pData; - if((m_State == READING) && (DiffStart < DiffEnd)) - RecordUpdateStats(res, DiffEnd - DiffStart, false); + if(IsLoading(m_State) && m_CurEventID > 0 && (diffStart < diffEnd)) + RecordUpdateStats(pResource, diffEnd - diffStart, false); - if(DiffStart >= DiffEnd) + if(diffStart >= diffEnd) + { + // do nothing + } + else if(intercept.MapType == D3D11_MAP_WRITE_NO_OVERWRITE) + { + RDCASSERT(WrappedID3D11Buffer::IsAlloc(pResource)); + ID3D11Buffer *mapContents = NULL; + + D3D11_BUFFER_DESC bdesc; + bdesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + bdesc.ByteWidth = diffEnd - diffStart; + bdesc.CPUAccessFlags = 0; + bdesc.MiscFlags = 0; + bdesc.StructureByteStride = 0; + bdesc.Usage = D3D11_USAGE_IMMUTABLE; + + D3D11_SUBRESOURCE_DATA data; + data.pSysMem = MapWrittenData; + data.SysMemPitch = bdesc.ByteWidth; + data.SysMemSlicePitch = bdesc.ByteWidth; + + HRESULT hr = m_pDevice->GetReal()->CreateBuffer(&bdesc, &data, &mapContents); + + if(FAILED(hr)) { - // do nothing - } - else if(MapType == D3D11_MAP_WRITE_NO_OVERWRITE) - { - RDCASSERT(WrappedID3D11Buffer::IsAlloc(res)); - ID3D11Buffer *mapContents = NULL; - - D3D11_BUFFER_DESC bdesc; - bdesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; - bdesc.ByteWidth = DiffEnd - DiffStart; - bdesc.CPUAccessFlags = 0; - bdesc.MiscFlags = 0; - bdesc.StructureByteStride = 0; - bdesc.Usage = D3D11_USAGE_IMMUTABLE; - - D3D11_SUBRESOURCE_DATA data; - data.pSysMem = appWritePtr; - data.SysMemPitch = bdesc.ByteWidth; - data.SysMemSlicePitch = bdesc.ByteWidth; - - HRESULT hr = m_pDevice->GetReal()->CreateBuffer(&bdesc, &data, &mapContents); - - if(FAILED(hr)) - { - RDCERR("Failed to create temp Unmap() buffer HRESULT: %s", ToStr(hr).c_str()); - } - else - { - m_pRealContext->CopySubresourceRegion(m_pDevice->GetResourceManager()->UnwrapResource(res), - mapIdx.subresource, DiffStart, 0, 0, mapContents, 0, - NULL); - - SAFE_RELEASE(mapContents); - } + RDCERR("Failed to create temp Unmap() buffer HRESULT: %s", ToStr(hr).c_str()); } else { - D3D11_MAPPED_SUBRESOURCE mappedResource; + m_pRealContext->CopySubresourceRegion(GetResourceManager()->UnwrapResource(pResource), + mapIdx.subresource, diffStart, 0, 0, mapContents, 0, + NULL); - UINT flags = MapFlags & ~D3D11_MAP_FLAG_DO_NOT_WAIT; - - HRESULT hr = m_pRealContext->Map(m_pDevice->GetResourceManager()->UnwrapResource(res), - mapIdx.subresource, MapType, flags, &mappedResource); - - RDCASSERT(mappedResource.pData); - - if(FAILED(hr)) - { - RDCERR("Failed to map resource, HRESULT: %s", ToStr(hr).c_str()); - } - else - { - intercept.SetD3D(mappedResource); - intercept.InitWrappedResource(res, mapIdx.subresource, appWritePtr); - - intercept.CopyToD3D(DiffStart, DiffEnd); - - m_pRealContext->Unmap(m_pDevice->GetResourceManager()->UnwrapResource(res), - mapIdx.subresource); - } + SAFE_RELEASE(mapContents); } - - SAFE_DELETE_ARRAY(appWritePtr); } - else if(m_State == WRITING_CAPFRAME) + else { - intercept.CopyToD3D(); + D3D11_MAPPED_SUBRESOURCE mappedResource; + + UINT flags = intercept.MapFlags & ~D3D11_MAP_FLAG_DO_NOT_WAIT; + + HRESULT hr = m_pRealContext->Map(GetResourceManager()->UnwrapResource(pResource), + mapIdx.subresource, intercept.MapType, flags, &mappedResource); + + RDCASSERT(mappedResource.pData); + + if(FAILED(hr)) + { + RDCERR("Failed to map resource, HRESULT: %s", ToStr(hr).c_str()); + } + else + { + intercept.SetD3D(mappedResource); + intercept.InitWrappedResource(pResource, mapIdx.subresource, MapWrittenData); + + intercept.CopyToD3D(diffStart, diffEnd); + + m_pRealContext->Unmap(m_pDevice->GetResourceManager()->UnwrapResource(pResource), + mapIdx.subresource); + } } - } - else if(m_State == WRITING_IDLE) - { - size_t len = (size_t)record->Length; - intercept.CopyToD3D(); - - if(!record->DataInSerialiser) - { - uint32_t diffStart = 0; - uint32_t diffEnd = (uint32_t)len; - - m_pSerialiser->Serialise("MapType", intercept.MapType); - m_pSerialiser->Serialise("MapFlags", intercept.MapFlags); - - m_pSerialiser->Serialise("DiffStart", diffStart); - m_pSerialiser->Serialise("DiffEnd", diffEnd); - - // this is a bit of a hack, but to maintain backwards compatibility we have a - // separate function here that aligns the next serialised buffer to a 32-byte - // boundary in memory while writing (just skips the padding on read). - if(m_State >= WRITING || m_pDevice->GetLogVersion() >= 0x000007) - m_pSerialiser->AlignNextBuffer(32); - - byte *buf = (byte *)intercept.app.pData; - m_pSerialiser->SerialiseBuffer("MapData", buf, len); - - intercept.app.pData = buf; - - record->DataInSerialiser = true; - record->SetDataOffset(m_pSerialiser->GetOffset() - record->Length); - - if(m_State < WRITING) - SAFE_DELETE_ARRAY(buf); - } - else if(intercept.verifyWrite) - { - memcpy(record->GetDataPtr(), intercept.app.pData, len); - } + FreeAlignedBuffer(MapWrittenData); } return true; @@ -7895,7 +7133,7 @@ void WrappedID3D11DeviceContext::Unmap(ID3D11Resource *pResource, UINT Subresour auto it = m_OpenMaps.find(MappedResource(id, Subresource)); - if(m_State == WRITING_IDLE && m_HighTrafficResources.find(id) != m_HighTrafficResources.end()) + if(IsBackgroundCapturing(m_State) && m_HighTrafficResources.find(id) != m_HighTrafficResources.end()) { // we intercepted this, even though we now don't need to serialise it. Time to finish what we // started! @@ -7915,9 +7153,9 @@ void WrappedID3D11DeviceContext::Unmap(ID3D11Resource *pResource, UINT Subresour m_OpenMaps.erase(it); } } - else if(m_State >= WRITING) + else if(IsCaptureMode(m_State)) { - if(it == m_OpenMaps.end() && m_State == WRITING_CAPFRAME) + if(it == m_OpenMaps.end() && IsActiveCapturing(m_State)) { RDCWARN( "Saw an Unmap that we didn't capture the corresponding Map for - this frame is " @@ -7932,18 +7170,19 @@ void WrappedID3D11DeviceContext::Unmap(ID3D11Resource *pResource, UINT Subresour { m_OpenMaps.erase(it); } - else if(m_State == WRITING_CAPFRAME) + else if(IsActiveCapturing(m_State)) { MarkResourceReferenced(it->first.resource, eFrameRef_Read); MarkResourceReferenced(it->first.resource, eFrameRef_Write); - SCOPED_SERIALISE_CONTEXT(UNMAP); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_Unmap(pResource, Subresource); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::Unmap); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_Unmap(GET_SERIALISER, pResource, Subresource); m_ContextRecord->AddChunk(scope.Get()); } - else if(m_State >= WRITING) + else // IsIdleCapturing(m_State) { RDCASSERT(WrappedID3D11Buffer::IsAlloc(pResource) || WrappedID3D11Texture1D::IsAlloc(pResource) || @@ -7961,13 +7200,17 @@ void WrappedID3D11DeviceContext::Unmap(ID3D11Resource *pResource, UINT Subresour if(record->DataInSerialiser) { - Serialise_Unmap(pResource, Subresource); + Serialise_Unmap(m_ScratchSerialiser, pResource, Subresource); + + // throw away any serialised data + m_ScratchSerialiser.GetWriter()->Rewind(); } else { - SCOPED_SERIALISE_CONTEXT(UNMAP); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_Unmap(pResource, Subresource); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D11Chunk::Unmap); + SERIALISE_ELEMENT(m_ResourceID).Named("Context ID"); + Serialise_Unmap(GET_SERIALISER, pResource, Subresource); Chunk *chunk = scope.Get(); diff --git a/renderdoc/driver/d3d11/d3d11_renderstate.cpp b/renderdoc/driver/d3d11/d3d11_renderstate.cpp index f223948f8..e333e3252 100644 --- a/renderdoc/driver/d3d11/d3d11_renderstate.cpp +++ b/renderdoc/driver/d3d11/d3d11_renderstate.cpp @@ -1090,8 +1090,9 @@ void D3D11RenderState::UnbindRangeForRead(const ResourceRange &range) } } -bool D3D11RenderState::ValidOutputMerger(ID3D11RenderTargetView **RTs, ID3D11DepthStencilView *depth, - ID3D11UnorderedAccessView **uavs) +bool D3D11RenderState::ValidOutputMerger(ID3D11RenderTargetView *const RTs[], UINT NumRTs, + ID3D11DepthStencilView *depth, + ID3D11UnorderedAccessView *const uavs[], UINT NumUAVs) { D3D11_RENDER_TARGET_VIEW_DESC RTDescs[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT]; D3D11_DEPTH_STENCIL_VIEW_DESC DepthDesc; @@ -1106,7 +1107,7 @@ bool D3D11RenderState::ValidOutputMerger(ID3D11RenderTargetView **RTs, ID3D11Dep D3D11_RESOURCE_DIMENSION_UNKNOWN}; D3D11_RESOURCE_DIMENSION depthdim = D3D11_RESOURCE_DIMENSION_UNKNOWN; - for(int i = 0; RTs && i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) + for(UINT i = 0; RTs && i < NumRTs; i++) { if(RTs[i]) { @@ -1151,7 +1152,7 @@ bool D3D11RenderState::ValidOutputMerger(ID3D11RenderTargetView **RTs, ID3D11Dep ResourceRange::Null, ResourceRange::Null, ResourceRange::Null, ResourceRange::Null, }; - for(int i = 0; RTs && i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) + for(UINT i = 0; RTs && i < NumRTs; i++) { if(RTs[i]) rtvRanges[i] = GetResourceRange(RTs[i]); @@ -1164,7 +1165,7 @@ bool D3D11RenderState::ValidOutputMerger(ID3D11RenderTargetView **RTs, ID3D11Dep int numUAVs = 0; - for(int i = 0; uavs && i < D3D11_1_UAV_SLOT_COUNT; i++) + for(UINT i = 0; uavs && i < NumUAVs; i++) { if(uavs[i]) { diff --git a/renderdoc/driver/d3d11/d3d11_renderstate.h b/renderdoc/driver/d3d11/d3d11_renderstate.h index 4a7266924..54a600f80 100644 --- a/renderdoc/driver/d3d11/d3d11_renderstate.h +++ b/renderdoc/driver/d3d11/d3d11_renderstate.h @@ -198,8 +198,9 @@ struct D3D11RenderState // that might not be obvious/intended. // validate an output merger combination of render targets and depth view - bool ValidOutputMerger(ID3D11RenderTargetView **RTs, ID3D11DepthStencilView *depth, - ID3D11UnorderedAccessView **uavs); + bool ValidOutputMerger(ID3D11RenderTargetView *const RTs[], UINT NumRTs, + ID3D11DepthStencilView *depth, ID3D11UnorderedAccessView *const uavs[], + UINT NumUAVs); struct inputassembler { @@ -275,7 +276,7 @@ struct D3D11RenderState void SetDevice(WrappedID3D11Device *device) { m_pDevice = device; } void MarkReferenced(WrappedID3D11DeviceContext *ctx, bool initial) const; void CacheViewportPartial(); - + bool IsViewportPartial() { return m_ViewportScissorPartial; } private: void AddRefs(); void ReleaseRefs(); diff --git a/renderdoc/driver/d3d11/d3d11_resources.h b/renderdoc/driver/d3d11/d3d11_resources.h index 1de7cffc1..91a03b081 100644 --- a/renderdoc/driver/d3d11/d3d11_resources.h +++ b/renderdoc/driver/d3d11/d3d11_resources.h @@ -1312,8 +1312,8 @@ public: WrappedID3D11DeviceContext *GetContext() { return m_pContext; } bool IsCaptured() { return m_Successful; } - void SetReferences(set &refs) { m_References.swap(refs); } - void SetDirtyResources(set &dirty) { m_Dirty.swap(dirty); } + void SwapReferences(set &refs) { m_References.swap(refs); } + void SwapDirtyResources(set &dirty) { m_Dirty.swap(dirty); } void MarkDirtyResources(D3D11ResourceManager *manager) { for(auto it = m_Dirty.begin(); it != m_Dirty.end(); ++it)