void WrappedID3D11DeviceContext::BeginCaptureFrame() { SCOPED_SERIALISE_CONTEXT(CONTEXT_CAPTURE_HEADER); m_pSerialiser->Serialise("context", m_ResourceID); Serialise_BeginCaptureFrame(false); { SCOPED_LOCK(m_AnnotLock); m_AnnotationQueue.clear(); } m_ContextRecord->AddChunk(scope.Get(), 1); }
void WrappedID3D11DeviceContext::ReplayLog(LogState readType, uint32_t startEventID, uint32_t endEventID, bool partial) { m_State = readType; m_DoStateVerify = true; D3D11ChunkType header = (D3D11ChunkType)m_pSerialiser->PushContext(NULL, 1, false); RDCASSERT(header == CONTEXT_CAPTURE_HEADER); ResourceId id; m_pSerialiser->Serialise("context", id); WrappedID3D11DeviceContext *context = (WrappedID3D11DeviceContext *)m_pDevice->GetResourceManager()->GetLiveResource(id); RDCASSERT(WrappedID3D11DeviceContext::IsAlloc(context) && context == this); Serialise_BeginCaptureFrame(!partial); m_pSerialiser->PopContext(NULL, header); m_CurEvents.clear(); if(m_State == EXECUTING) { FetchAPIEvent ev = GetEvent(startEventID); m_CurEventID = ev.eventID; m_pSerialiser->SetOffset(ev.fileOffset); } else if(m_State == READING) { m_CurEventID = 1; } if(m_State == EXECUTING) { ClearMaps(); for(size_t i=0; i < m_pDevice->GetNumDeferredContexts(); i++) { WrappedID3D11DeviceContext *defcontext = m_pDevice->GetDeferredContext(i); defcontext->ClearMaps(); } } m_pDevice->GetResourceManager()->MarkInFrame(true); uint64_t startOffset = m_pSerialiser->GetOffset(); while(1) { if(m_State == EXECUTING && m_CurEventID > endEventID) { // we can just break out if we've done all the events desired. break; } uint64_t offset = m_pSerialiser->GetOffset(); D3D11ChunkType chunktype = (D3D11ChunkType)m_pSerialiser->PushContext(NULL, 1, false); ProcessChunk(offset, chunktype, false); RenderDoc::Inst().SetProgress(FrameEventsRead, float(offset - startOffset)/float(m_pSerialiser->GetSize())); // for now just abort after capture scope. Really we'd need to support multiple frames // but for now this will do. if(chunktype == CONTEXT_CAPTURE_FOOTER) break; m_CurEventID++; } if(m_State == READING) { m_pDevice->GetFrameRecord().back().drawcallList = m_ParentDrawcall.Bake(); m_pDevice->GetFrameRecord().back().frameInfo.debugMessages = m_pDevice->GetDebugMessages(); int initialSkips = 0; for(auto it=WrappedID3D11Buffer::m_BufferList.begin(); it != WrappedID3D11Buffer::m_BufferList.end(); ++it) m_ResourceUses[it->first]; for(auto it=WrappedID3D11Texture1D::m_TextureList.begin(); it != WrappedID3D11Texture1D::m_TextureList.end(); ++it) m_ResourceUses[it->first]; for(auto it=WrappedID3D11Texture2D::m_TextureList.begin(); it != WrappedID3D11Texture2D::m_TextureList.end(); ++it) m_ResourceUses[it->first]; for(auto it=WrappedID3D11Texture3D::m_TextureList.begin(); it != WrappedID3D11Texture3D::m_TextureList.end(); ++it) m_ResourceUses[it->first]; // it's easier to remove duplicate usages here than check it as we go. // this means if textures are bound in multiple places in the same draw // we don't have duplicate uses for(auto it = m_ResourceUses.begin(); it != m_ResourceUses.end(); ++it) { vector<EventUsage> &v = it->second; std::sort(v.begin(), v.end()); v.erase( std::unique(v.begin(), v.end()), v.end() ); #if 0 ResourceId resid = m_pDevice->GetResourceManager()->GetOriginalID(it->first); if(m_pDevice->GetResourceManager()->GetInitialContents(resid).resource == NULL) continue; // code disabled for now as skipping these initial states // doesn't seem to produce any measurable improvement in any case // I've checked RDCDEBUG("Resource %llu", resid); if(v.empty()) { RDCDEBUG("Never used!"); initialSkips++; } else { bool written = false; for(auto usit = v.begin(); usit != v.end(); ++usit) { ResourceUsage u = usit->usage; if(u == eUsage_SO || (u >= eUsage_VS_RWResource && u <= eUsage_CS_RWResource) || u == eUsage_DepthStencilTarget || u == eUsage_ColourTarget) { written = true; break; } } if(written) { RDCDEBUG("Written in frame - needs initial state"); } else { RDCDEBUG("Never written to in the frame"); initialSkips++; } } #endif } //RDCDEBUG("Can skip %d initial states.", initialSkips); } m_pDevice->GetResourceManager()->MarkInFrame(false); m_State = READING; m_DoStateVerify = false; }
void WrappedID3D11DeviceContext::ReplayLog(LogState readType, uint32_t startEventID, uint32_t endEventID, bool partial) { m_State = readType; m_DoStateVerify = true; D3D11ChunkType header = (D3D11ChunkType)m_pSerialiser->PushContext(NULL, 1, false); RDCASSERT(header == CONTEXT_CAPTURE_HEADER); ResourceId id; m_pSerialiser->Serialise("context", id); WrappedID3D11DeviceContext *context = (WrappedID3D11DeviceContext *)m_pDevice->GetResourceManager()->GetLiveResource(id); RDCASSERT(WrappedID3D11DeviceContext::IsAlloc(context) && context == this); Serialise_BeginCaptureFrame(!partial); m_pSerialiser->PopContext(NULL, header); m_CurEvents.clear(); if(m_State == EXECUTING) { FetchAPIEvent ev = GetEvent(startEventID); m_CurEventID = ev.eventID; m_pSerialiser->SetOffset(ev.fileOffset); } else if(m_State == READING) { m_CurEventID = 1; } if(m_State == EXECUTING) { ClearMaps(); for(size_t i=0; i < m_pDevice->GetNumDeferredContexts(); i++) { WrappedID3D11DeviceContext *context = m_pDevice->GetDeferredContext(i); context->ClearMaps(); } } m_pDevice->GetResourceManager()->MarkInFrame(true); while(1) { if(m_State == EXECUTING && m_CurEventID > endEventID) { // we can just break out if we've done all the events desired. break; } uint64_t offset = m_pSerialiser->GetOffset(); D3D11ChunkType context = (D3D11ChunkType)m_pSerialiser->PushContext(NULL, 1, false); ProcessChunk(offset, context, false); RenderDoc::Inst().SetProgress(FileInitialRead, float(offset)/float(m_pSerialiser->GetSize())); // for now just abort after capture scope. Really we'd need to support multiple frames // but for now this will do. if(context == CONTEXT_CAPTURE_FOOTER) break; m_CurEventID++; } if(m_State == READING) { m_pDevice->GetFrameRecord().back().drawcallList = m_ParentDrawcall.Bake(); m_ParentDrawcall.children.clear(); int initialSkips = 0; for(auto it=WrappedID3D11Buffer::m_BufferList.begin(); it != WrappedID3D11Buffer::m_BufferList.end(); ++it) m_ResourceUses[it->first]; for(auto it=WrappedID3D11Texture1D::m_TextureList.begin(); it != WrappedID3D11Texture1D::m_TextureList.end(); ++it) m_ResourceUses[it->first]; for(auto it=WrappedID3D11Texture2D::m_TextureList.begin(); it != WrappedID3D11Texture2D::m_TextureList.end(); ++it) m_ResourceUses[it->first]; for(auto it=WrappedID3D11Texture3D::m_TextureList.begin(); it != WrappedID3D11Texture3D::m_TextureList.end(); ++it) m_ResourceUses[it->first]; for(auto it = m_ResourceUses.begin(); it != m_ResourceUses.end(); ++it) { ResourceId id = m_pDevice->GetResourceManager()->GetOriginalID(it->first); if(m_pDevice->GetResourceManager()->GetInitialContents(id) == NULL) continue; RDCDEBUG("Resource %llu", id); if(it->second.empty()) { RDCDEBUG("Never used!"); initialSkips++; } else { bool written = false; for(auto usit = it->second.begin(); usit != it->second.end(); ++usit) { ResourceUsage u = usit->usage; if(u == eUsage_SO || u == eUsage_CS_UAV || u == eUsage_PS_UAV || u == eUsage_OM_DSV || u == eUsage_OM_RTV) { written = true; break; } } if(written) { RDCDEBUG("Written in frame - needs initial state"); } else { RDCDEBUG("Never written to in the frame"); initialSkips++; } } } RDCDEBUG("Can skip %d initial states.", initialSkips); } m_pDevice->GetResourceManager()->MarkInFrame(false); m_State = READING; m_DoStateVerify = false; }