diff --git a/qrenderdoc/Code/CaptureContext.cpp b/qrenderdoc/Code/CaptureContext.cpp index 5fadd91fa..5b9bcae56 100644 --- a/qrenderdoc/Code/CaptureContext.cpp +++ b/qrenderdoc/Code/CaptureContext.cpp @@ -139,11 +139,10 @@ void CaptureContext::LoadLogfile(const QString &logFile, const QString &origFile QVector logviewers(m_LogViewers); // make sure we're on a consistent event before invoking log viewer forms - const DrawcallDescription *draw = &m_Drawcalls.back(); - while(!draw->children.empty()) - draw = &draw->children.back(); - - SetEventID(logviewers, draw->eventID, true); + if(m_LastDrawcall) + SetEventID(logviewers, m_LastDrawcall->eventID, true); + else if(!m_Drawcalls.empty()) + SetEventID(logviewers, m_Drawcalls.back().eventID, true); GUIInvoke::blockcall([&logviewers]() { // notify all the registers log viewers that a log has been loaded @@ -205,6 +204,8 @@ void CaptureContext::LoadLogfileThreaded(const QString &logFile, const QString & m_EventID = 0; + m_FirstDrawcall = m_LastDrawcall = NULL; + // fetch initial data like drawcalls, textures and buffers m_Renderer.BlockInvoke([this](IReplayController *r) { m_FrameInfo = r->GetFrameInfo(); @@ -217,6 +218,14 @@ void CaptureContext::LoadLogfileThreaded(const QString &logFile, const QString & AddFakeProfileMarkers(); + m_FirstDrawcall = &m_Drawcalls[0]; + while(!m_FirstDrawcall->children.empty()) + m_FirstDrawcall = &m_FirstDrawcall->children[0]; + + m_LastDrawcall = &m_Drawcalls.back(); + while(!m_LastDrawcall->children.empty()) + m_LastDrawcall = &m_LastDrawcall->children.back(); + m_PostloadProgress = 0.4f; m_WinSystems = r->GetSupportedWindowSystems(); @@ -522,6 +531,9 @@ void CaptureContext::CloseLogfile() m_Textures.clear(); m_TextureList.clear(); + m_Drawcalls.clear(); + m_FirstDrawcall = m_LastDrawcall = NULL; + m_CurD3D11PipelineState = D3D11Pipe::State(); m_CurD3D12PipelineState = D3D12Pipe::State(); m_CurGLPipelineState = GLPipe::State(); diff --git a/qrenderdoc/Code/CaptureContext.h b/qrenderdoc/Code/CaptureContext.h index 63e82d29d..e0dab166f 100644 --- a/qrenderdoc/Code/CaptureContext.h +++ b/qrenderdoc/Code/CaptureContext.h @@ -105,6 +105,8 @@ public: return GetDrawcall(CurSelectedEvent()); } const DrawcallDescription *CurDrawcall() override { return GetDrawcall(CurEvent()); } + const DrawcallDescription *GetFirstDrawcall() override { return m_FirstDrawcall; }; + const DrawcallDescription *GetLastDrawcall() override { return m_LastDrawcall; }; const rdctype::array &CurDrawcalls() override { return m_Drawcalls; } TextureDescription *GetTexture(ResourceId id) override { return m_Textures[id]; } const rdctype::array &GetTextures() override { return m_TextureList; } @@ -248,6 +250,8 @@ private: APIProperties m_APIProps; FrameDescription m_FrameInfo; + DrawcallDescription *m_FirstDrawcall = NULL; + DrawcallDescription *m_LastDrawcall = NULL; QMap m_Textures; rdctype::array m_TextureList; diff --git a/qrenderdoc/Code/Interface/QRDInterface.h b/qrenderdoc/Code/Interface/QRDInterface.h index 247fca9c4..5e8682c8e 100644 --- a/qrenderdoc/Code/Interface/QRDInterface.h +++ b/qrenderdoc/Code/Interface/QRDInterface.h @@ -960,11 +960,25 @@ more information for how this differs. DOCUMENT(R"(Retrieve the current drawcall. -:return: The current drawcall. +:return: The current drawcall, or ``None`` if no drawcall is selected. :rtype: ~renderdoc.DrawcallDescription )"); virtual const DrawcallDescription *CurDrawcall() = 0; + DOCUMENT(R"(Retrieve the first drawcall in the capture. + +:return: The first drawcall. +:rtype: ~renderdoc.DrawcallDescription +)"); + virtual const DrawcallDescription *GetFirstDrawcall() = 0; + + DOCUMENT(R"(Retrieve the last drawcall in the capture. + +:return: The last drawcall. +:rtype: ~renderdoc.DrawcallDescription +)"); + virtual const DrawcallDescription *GetLastDrawcall() = 0; + DOCUMENT(R"(Retrieve the root list of drawcalls in the current capture. :return: The root drawcalls. diff --git a/qrenderdoc/Windows/EventBrowser.cpp b/qrenderdoc/Windows/EventBrowser.cpp index f69a1c51e..e33517efd 100644 --- a/qrenderdoc/Windows/EventBrowser.cpp +++ b/qrenderdoc/Windows/EventBrowser.cpp @@ -175,7 +175,7 @@ void EventBrowser::OnLogfileLoaded() RDTreeWidgetItem *framestart = new RDTreeWidgetItem({tr("Frame Start"), lit("0"), lit("0"), QString()}); - framestart->setTag(QVariant::fromValue(EventItemTag())); + framestart->setTag(QVariant::fromValue(EventItemTag(0, 0))); frame->addChild(framestart); @@ -403,6 +403,14 @@ void EventBrowser::on_events_currentItemChanged(RDTreeWidgetItem *current, RDTre ui->stepPrev->setEnabled(draw && draw->previous); ui->stepNext->setEnabled(draw && draw->next); + // special case for the first draw in the frame + if(tag.lastEID == 0) + ui->stepNext->setEnabled(true); + + // special case for the first 'virtual' draw at EID 0 + if(tag.lastEID == m_Ctx.GetFirstDrawcall()->eventID) + ui->stepPrev->setEnabled(true); + highlightBookmarks(); } @@ -502,6 +510,10 @@ void EventBrowser::on_stepNext_clicked() if(draw && draw->next > 0) SelectEvent(draw->next); + + // special case for the first 'virtual' draw at EID 0 + if(m_Ctx.CurEvent() == 0) + SelectEvent(m_Ctx.GetFirstDrawcall()->eventID); } void EventBrowser::on_stepPrev_clicked() @@ -513,6 +525,10 @@ void EventBrowser::on_stepPrev_clicked() if(draw && draw->previous > 0) SelectEvent(draw->previous); + + // special case for the first 'virtual' draw at EID 0 + if(m_Ctx.CurEvent() == m_Ctx.GetFirstDrawcall()->eventID) + SelectEvent(0); } void EventBrowser::on_exportDraws_clicked() diff --git a/qrenderdoc/Windows/PythonShell.cpp b/qrenderdoc/Windows/PythonShell.cpp index f9b26e986..fe02d4943 100644 --- a/qrenderdoc/Windows/PythonShell.cpp +++ b/qrenderdoc/Windows/PythonShell.cpp @@ -68,6 +68,11 @@ struct CaptureContextInvoker : ICaptureContext return m_Ctx.CurSelectedDrawcall(); } virtual const DrawcallDescription *CurDrawcall() override { return m_Ctx.CurDrawcall(); } + virtual const DrawcallDescription *GetFirstDrawcall() override + { + return m_Ctx.GetFirstDrawcall(); + } + virtual const DrawcallDescription *GetLastDrawcall() override { return m_Ctx.GetLastDrawcall(); } virtual const rdctype::array &CurDrawcalls() override { return m_Ctx.CurDrawcalls(); diff --git a/qrenderdoc/Windows/StatisticsViewer.cpp b/qrenderdoc/Windows/StatisticsViewer.cpp index be8c08a03..bb1f67d27 100644 --- a/qrenderdoc/Windows/StatisticsViewer.cpp +++ b/qrenderdoc/Windows/StatisticsViewer.cpp @@ -686,17 +686,14 @@ void StatisticsViewer::GenerateReport() { const rdctype::array &curDraws = m_Ctx.CurDrawcalls(); - const DrawcallDescription *lastDraw = &curDraws.back(); - while(!lastDraw->children.empty()) - lastDraw = &lastDraw->children.back(); - uint32_t drawCount = 0; uint32_t dispatchCount = 0; uint32_t diagnosticCount = 0; for(const DrawcallDescription &d : curDraws) CountContributingEvents(d, drawCount, dispatchCount, diagnosticCount); - uint32_t numAPIcalls = lastDraw->eventID - (drawCount + dispatchCount + diagnosticCount); + uint32_t numAPIcalls = + m_Ctx.GetLastDrawcall()->eventID - (drawCount + dispatchCount + diagnosticCount); int numTextures = m_Ctx.GetTextures().count; int numBuffers = m_Ctx.GetBuffers().count;