From 5150a9531b61aba4f927b49c92712efeabecb1e5 Mon Sep 17 00:00:00 2001 From: baldurk Date: Wed, 24 Jan 2018 11:38:37 +0000 Subject: [PATCH] Allow queuing a sequence of frames both before capture, or while running * We also make the frame counting consistent: Frame 0 is the frame from device initialisation to first present, Frame 1 is from first present to second, and so on after that. --- qrenderdoc/Windows/Dialogs/CaptureDialog.cpp | 13 +-- qrenderdoc/Windows/Dialogs/CaptureDialog.ui | 32 +++++++ qrenderdoc/Windows/Dialogs/LiveCapture.cpp | 24 +++-- qrenderdoc/Windows/Dialogs/LiveCapture.h | 4 +- qrenderdoc/Windows/Dialogs/LiveCapture.ui | 94 ++++++++------------ renderdoc/api/replay/renderdoc_replay.h | 7 +- renderdoc/core/core.cpp | 2 +- renderdoc/core/target_control.cpp | 12 ++- renderdoc/driver/d3d11/d3d11_device.cpp | 12 +-- renderdoc/driver/d3d12/d3d12_device.cpp | 10 +-- renderdoc/driver/gl/gl_driver.cpp | 13 +-- renderdoc/driver/vulkan/vk_core.cpp | 10 +-- 12 files changed, 128 insertions(+), 105 deletions(-) diff --git a/qrenderdoc/Windows/Dialogs/CaptureDialog.cpp b/qrenderdoc/Windows/Dialogs/CaptureDialog.cpp index 1791e5e36..b00b147ef 100644 --- a/qrenderdoc/Windows/Dialogs/CaptureDialog.cpp +++ b/qrenderdoc/Windows/Dialogs/CaptureDialog.cpp @@ -1108,11 +1108,11 @@ void CaptureDialog::TriggerCapture() QString name = m_ProcessModel->data(m_ProcessModel->index(item.row(), 0)).toString(); uint32_t PID = m_ProcessModel->data(m_ProcessModel->index(item.row(), 1)).toUInt(); - m_InjectCallback(PID, Settings().environment, name, Settings().options, - [this](LiveCapture *live) { - if(ui->queueFrameCap->isChecked()) - live->QueueCapture((int)ui->queuedFrame->value()); - }); + m_InjectCallback( + PID, Settings().environment, name, Settings().options, [this](LiveCapture *live) { + if(ui->queueFrameCap->isChecked()) + live->QueueCapture((int)ui->queuedFrame->value(), (int)ui->numFrames->value()); + }); } } else @@ -1148,7 +1148,8 @@ void CaptureDialog::TriggerCapture() m_CaptureCallback(exe, workingDir, cmdLine, Settings().environment, Settings().options, [this](LiveCapture *live) { if(ui->queueFrameCap->isChecked()) - live->QueueCapture((int)ui->queuedFrame->value()); + live->QueueCapture((int)ui->queuedFrame->value(), + (int)ui->numFrames->value()); }); } } diff --git a/qrenderdoc/Windows/Dialogs/CaptureDialog.ui b/qrenderdoc/Windows/Dialogs/CaptureDialog.ui index 00fdc7ad1..0d300e754 100644 --- a/qrenderdoc/Windows/Dialogs/CaptureDialog.ui +++ b/qrenderdoc/Windows/Dialogs/CaptureDialog.ui @@ -587,6 +587,38 @@ + + + + + 0 + 0 + + + + # Frames: + + + + + + + + 45 + 0 + + + + 0 + + + 1.000000000000000 + + + 4.000000000000000 + + + diff --git a/qrenderdoc/Windows/Dialogs/LiveCapture.cpp b/qrenderdoc/Windows/Dialogs/LiveCapture.cpp index b5c3cf4af..853b14b5d 100644 --- a/qrenderdoc/Windows/Dialogs/LiveCapture.cpp +++ b/qrenderdoc/Windows/Dialogs/LiveCapture.cpp @@ -185,9 +185,10 @@ LiveCapture::~LiveCapture() delete ui; } -void LiveCapture::QueueCapture(int frameNumber) +void LiveCapture::QueueCapture(int frameNumber, int numFrames) { - m_CaptureFrameNum = frameNumber; + m_QueueCaptureFrameNum = frameNumber; + m_CaptureNumFrames = numFrames; m_QueueCapture = true; } @@ -275,13 +276,13 @@ void LiveCapture::on_childProcesses_itemActivated(QListWidgetItem *item) void LiveCapture::on_queueCap_clicked() { - m_CaptureFrameNum = (int)ui->captureFrame->value(); + m_CaptureNumFrames = (int)ui->numFrames->value(); + m_QueueCaptureFrameNum = (int)ui->captureFrame->value(); m_QueueCapture = true; } void LiveCapture::on_triggerCapture_clicked() { - m_CaptureNumFrames = (int)ui->numFrames->value(); if(ui->captureDelay->value() == 0.0) { m_TriggerCapture = true; @@ -482,8 +483,9 @@ void LiveCapture::captureCountdownTick() if(m_CaptureCounter == 0) { m_TriggerCapture = true; + m_CaptureNumFrames = (int)ui->numFrames->value(); ui->triggerCapture->setEnabled(true); - ui->triggerCapture->setText(tr("Trigger Capture")); + ui->triggerCapture->setText(tr("Trigger After Delay")); } else { @@ -700,12 +702,6 @@ bool LiveCapture::checkAllowClose() return false; } } - - if(res == QMessageBox::No) - { - // treat this capture as saved now, so we don't prompt about it again. - cap->saved = true; - } } m_IgnoreThreadClosed = false; @@ -1097,13 +1093,15 @@ void LiveCapture::connectionThreadEntry() { m_Connection->TriggerCapture((uint)m_CaptureNumFrames); m_TriggerCapture = false; + m_CaptureNumFrames = 1; } if(m_QueueCapture) { - m_Connection->QueueCapture((uint)m_CaptureFrameNum); + m_Connection->QueueCapture((uint32_t)m_QueueCaptureFrameNum, (uint32_t)m_CaptureNumFrames); m_QueueCapture = false; - m_CaptureFrameNum = 0; + m_QueueCaptureFrameNum = 0; + m_CaptureNumFrames = 1; } if(!m_CopyCaptureLocalPath.isEmpty()) diff --git a/qrenderdoc/Windows/Dialogs/LiveCapture.h b/qrenderdoc/Windows/Dialogs/LiveCapture.h index 0e7d9f8e9..35511b107 100644 --- a/qrenderdoc/Windows/Dialogs/LiveCapture.h +++ b/qrenderdoc/Windows/Dialogs/LiveCapture.h @@ -57,7 +57,7 @@ public: ~LiveCapture(); - void QueueCapture(int frameNumber); + void QueueCapture(int frameNumber, int numFrames); const QString &hostname() { return m_Hostname; } void cleanItems(); @@ -161,7 +161,7 @@ private: bool m_TriggerCapture = false; bool m_QueueCapture = false; int m_CaptureNumFrames = 1; - int m_CaptureFrameNum = 0; + int m_QueueCaptureFrameNum = 0; int m_CaptureCounter = 0; QSemaphore m_Disconnect; ITargetControl *m_Connection = NULL; diff --git a/qrenderdoc/Windows/Dialogs/LiveCapture.ui b/qrenderdoc/Windows/Dialogs/LiveCapture.ui index 53c67dad9..2f8496f06 100644 --- a/qrenderdoc/Windows/Dialogs/LiveCapture.ui +++ b/qrenderdoc/Windows/Dialogs/LiveCapture.ui @@ -177,27 +177,7 @@ Tools - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - 0 - - - 10000.000000000000000 - - - - - - - Queue Capture - - - - + @@ -219,7 +199,34 @@ - + + + + Frame + + + 0 + + + 10000.000000000000000 + + + + + + + Trigger After Delay + + + + + + + Queue Specific Frame + + + + @@ -227,6 +234,12 @@ 0 + + Capture + + + Sequential Frame(s) + 0 @@ -236,43 +249,12 @@ 4.000000000000000 - - - - - - Capture Delay + + 1.000000000000000 - - - - - 0 - 0 - - - - # Frames: - - - - - - - Trigger Capture - - - - - - - Capture Frame # - - - - + Qt::Vertical diff --git a/renderdoc/api/replay/renderdoc_replay.h b/renderdoc/api/replay/renderdoc_replay.h index 40872bb42..54cb981e2 100644 --- a/renderdoc/api/replay/renderdoc_replay.h +++ b/renderdoc/api/replay/renderdoc_replay.h @@ -1170,9 +1170,14 @@ next after that. DOCUMENT(R"(Queue up a capture to happen on a particular frame number. When this frame is about to begin a capture is begun, and it ends when this frame number ends. +.. note:: Frame 0 is defined as starting when the device is created, up to the first swapchain + present defined frame boundary. + :param int frameNumber: The number of the frame to capture on. +:param int numFrames: How many frames to capture. These will be captured sequentially and + independently to separate files. )"); - virtual void QueueCapture(uint32_t frameNumber) = 0; + virtual void QueueCapture(uint32_t frameNumber, uint32_t numFrames) = 0; DOCUMENT(R"(Begin copying a given capture stored on a remote machine to the local machine over the target control connection. diff --git a/renderdoc/core/core.cpp b/renderdoc/core/core.cpp index 9eb14beac..d913bc144 100644 --- a/renderdoc/core/core.cpp +++ b/renderdoc/core/core.cpp @@ -682,7 +682,7 @@ bool RenderDoc::ShouldTriggerCapture(uint32_t frameNumber) { // discard, this frame is past. } - else if((*it) - 1 == frameNumber) + else if((*it) == frameNumber) { // we want to capture the next frame ret = true; diff --git a/renderdoc/core/target_control.cpp b/renderdoc/core/target_control.cpp index e9fef191d..f4cb3ee7b 100644 --- a/renderdoc/core/target_control.cpp +++ b/renderdoc/core/target_control.cpp @@ -249,7 +249,7 @@ void RenderDoc::TargetControlClientThread(uint32_t version, Network::Socket *cli if(type == ePacket_TriggerCapture) { - uint32_t numFrames; + uint32_t numFrames = 1; READ_DATA_SCOPE(); SERIALISE_ELEMENT(numFrames); @@ -258,12 +258,15 @@ void RenderDoc::TargetControlClientThread(uint32_t version, Network::Socket *cli } else if(type == ePacket_QueueCapture) { - uint32_t frameNum; + uint32_t frameNum = 0; + uint32_t numFrames = 1; READ_DATA_SCOPE(); SERIALISE_ELEMENT(frameNum); + SERIALISE_ELEMENT(numFrames); - RenderDoc::Inst().QueueCapture(frameNum); + for(uint32_t f = 0; f < numFrames; f++) + RenderDoc::Inst().QueueCapture(frameNum + f); } else if(type == ePacket_DeleteCapture) { @@ -537,12 +540,13 @@ public: SAFE_DELETE(m_Socket); } - void QueueCapture(uint32_t frameNumber) + void QueueCapture(uint32_t frameNumber, uint32_t numFrames) { WRITE_DATA_SCOPE(); SCOPED_SERIALISE_CHUNK(ePacket_QueueCapture); SERIALISE_ELEMENT(frameNumber); + SERIALISE_ELEMENT(numFrames); if(ser.IsErrored()) SAFE_DELETE(m_Socket); diff --git a/renderdoc/driver/d3d11/d3d11_device.cpp b/renderdoc/driver/d3d11/d3d11_device.cpp index 8c068decc..690bf9990 100644 --- a/renderdoc/driver/d3d11/d3d11_device.cpp +++ b/renderdoc/driver/d3d11/d3d11_device.cpp @@ -1356,10 +1356,10 @@ void WrappedID3D11Device::StartFrameCapture(void *dev, void *wnd) m_FailedFrame = 0; m_FailedReason = CaptureSucceeded; - m_FrameCounter = RDCMAX(1 + (uint32_t)m_CapturedFrames.size(), m_FrameCounter); + m_FrameCounter = RDCMAX((uint32_t)m_CapturedFrames.size(), m_FrameCounter); FrameDescription frame; - frame.frameNumber = m_FrameCounter + 1; + frame.frameNumber = m_FrameCounter; frame.captureTime = Timing::GetUnixTimestamp(); m_CapturedFrames.push_back(frame); @@ -1650,8 +1650,8 @@ bool WrappedID3D11Device::EndFrameCapture(void *dev, void *wnd) } } - RDCFile *rdc = RenderDoc::Inst().CreateRDC(RDCDriver::D3D11, m_FrameCounter, jpgbuf, len, - thwidth, thheight); + RDCFile *rdc = RenderDoc::Inst().CreateRDC( + RDCDriver::D3D11, m_CapturedFrames.back().frameNumber, jpgbuf, len, thwidth, thheight); SAFE_DELETE_ARRAY(jpgbuf); SAFE_DELETE_ARRAY(thpixels); @@ -1744,7 +1744,7 @@ bool WrappedID3D11Device::EndFrameCapture(void *dev, void *wnd) UnlockForChunkFlushing(); } - RenderDoc::Inst().FinishCaptureWriting(rdc, m_FrameCounter); + RenderDoc::Inst().FinishCaptureWriting(rdc, m_CapturedFrames.back().frameNumber); m_State = CaptureState::BackgroundCapturing; @@ -1803,7 +1803,7 @@ bool WrappedID3D11Device::EndFrameCapture(void *dev, void *wnd) old.ApplyState(m_pImmediateContext); } - m_CapturedFrames.back().frameNumber = m_FrameCounter + 1; + m_CapturedFrames.back().frameNumber = m_FrameCounter; m_pImmediateContext->CleanupCapture(); diff --git a/renderdoc/driver/d3d12/d3d12_device.cpp b/renderdoc/driver/d3d12/d3d12_device.cpp index 85b2fd63f..f7abad992 100644 --- a/renderdoc/driver/d3d12/d3d12_device.cpp +++ b/renderdoc/driver/d3d12/d3d12_device.cpp @@ -1247,10 +1247,10 @@ void WrappedID3D12Device::StartFrameCapture(void *dev, void *wnd) m_SubmitCounter = 0; - m_FrameCounter = RDCMAX(1 + (uint32_t)m_CapturedFrames.size(), m_FrameCounter); + m_FrameCounter = RDCMAX((uint32_t)m_CapturedFrames.size(), m_FrameCounter); FrameDescription frame; - frame.frameNumber = m_FrameCounter + 1; + frame.frameNumber = m_FrameCounter; frame.captureTime = Timing::GetUnixTimestamp(); RDCEraseEl(frame.stats); m_CapturedFrames.push_back(frame); @@ -1580,8 +1580,8 @@ bool WrappedID3D12Device::EndFrameCapture(void *dev, void *wnd) if((*it)->GetResourceRecord()->ContainsExecuteIndirect) WrappedID3D12Resource::RefBuffers(GetResourceManager()); - rdc = RenderDoc::Inst().CreateRDC(RDCDriver::D3D12, m_FrameCounter, jpgbuf, len, thwidth, - thheight); + rdc = RenderDoc::Inst().CreateRDC(RDCDriver::D3D12, m_CapturedFrames.back().frameNumber, jpgbuf, + len, thwidth, thheight); SAFE_DELETE_ARRAY(jpgbuf); SAFE_DELETE_ARRAY(thpixels); @@ -1684,7 +1684,7 @@ bool WrappedID3D12Device::EndFrameCapture(void *dev, void *wnd) RDCDEBUG("Done"); } - RenderDoc::Inst().FinishCaptureWriting(rdc, m_FrameCounter); + RenderDoc::Inst().FinishCaptureWriting(rdc, m_CapturedFrames.back().frameNumber); SAFE_DELETE(m_HeaderChunk); diff --git a/renderdoc/driver/gl/gl_driver.cpp b/renderdoc/driver/gl/gl_driver.cpp index b9852697c..57a77508a 100644 --- a/renderdoc/driver/gl/gl_driver.cpp +++ b/renderdoc/driver/gl/gl_driver.cpp @@ -1560,10 +1560,10 @@ void WrappedOpenGL::StartFrameCapture(void *dev, void *wnd) GLWindowingData switchctx = prevctx; MakeValidContextCurrent(switchctx, wnd); - m_FrameCounter = RDCMAX(1 + (uint32_t)m_CapturedFrames.size(), m_FrameCounter); + m_FrameCounter = RDCMAX((uint32_t)m_CapturedFrames.size(), m_FrameCounter); FrameDescription frame; - frame.frameNumber = m_FrameCounter + 1; + frame.frameNumber = m_FrameCounter; frame.captureTime = Timing::GetUnixTimestamp(); RDCEraseEl(frame.stats); m_CapturedFrames.push_back(frame); @@ -1641,8 +1641,9 @@ bool WrappedOpenGL::EndFrameCapture(void *dev, void *wnd) if(bbim == NULL) bbim = SaveBackbufferImage(); - RDCFile *rdc = RenderDoc::Inst().CreateRDC(GetDriverType(), m_FrameCounter, bbim->jpgbuf, - bbim->len, bbim->thwidth, bbim->thheight); + RDCFile *rdc = + RenderDoc::Inst().CreateRDC(GetDriverType(), m_CapturedFrames.back().frameNumber, + bbim->jpgbuf, bbim->len, bbim->thwidth, bbim->thheight); SAFE_DELETE(bbim); @@ -1730,7 +1731,7 @@ bool WrappedOpenGL::EndFrameCapture(void *dev, void *wnd) } } - RenderDoc::Inst().FinishCaptureWriting(rdc, m_FrameCounter); + RenderDoc::Inst().FinishCaptureWriting(rdc, m_CapturedFrames.back().frameNumber); m_State = CaptureState::BackgroundCapturing; @@ -1773,7 +1774,7 @@ bool WrappedOpenGL::EndFrameCapture(void *dev, void *wnd) ClearGLErrors(m_Real); } - m_CapturedFrames.back().frameNumber = m_FrameCounter + 1; + m_CapturedFrames.back().frameNumber = m_FrameCounter; CleanupCapture(); diff --git a/renderdoc/driver/vulkan/vk_core.cpp b/renderdoc/driver/vulkan/vk_core.cpp index 41e1839d1..77d640f9c 100644 --- a/renderdoc/driver/vulkan/vk_core.cpp +++ b/renderdoc/driver/vulkan/vk_core.cpp @@ -927,10 +927,10 @@ void WrappedVulkan::StartFrameCapture(void *dev, void *wnd) m_SubmitCounter = 0; - m_FrameCounter = RDCMAX(1 + (uint32_t)m_CapturedFrames.size(), m_FrameCounter); + m_FrameCounter = RDCMAX((uint32_t)m_CapturedFrames.size(), m_FrameCounter); FrameDescription frame; - frame.frameNumber = m_FrameCounter + 1; + frame.frameNumber = m_FrameCounter; frame.captureTime = Timing::GetUnixTimestamp(); RDCEraseEl(frame.stats); m_CapturedFrames.push_back(frame); @@ -1335,8 +1335,8 @@ bool WrappedVulkan::EndFrameCapture(void *dev, void *wnd) } } - RDCFile *rdc = - RenderDoc::Inst().CreateRDC(RDCDriver::Vulkan, m_FrameCounter, jpgbuf, len, thwidth, thheight); + RDCFile *rdc = RenderDoc::Inst().CreateRDC(RDCDriver::Vulkan, m_CapturedFrames.back().frameNumber, + jpgbuf, len, thwidth, thheight); SAFE_DELETE_ARRAY(jpgbuf); SAFE_DELETE_ARRAY(thpixels); @@ -1429,7 +1429,7 @@ bool WrappedVulkan::EndFrameCapture(void *dev, void *wnd) } } - RenderDoc::Inst().FinishCaptureWriting(rdc, m_FrameCounter); + RenderDoc::Inst().FinishCaptureWriting(rdc, m_CapturedFrames.back().frameNumber); SAFE_DELETE(m_HeaderChunk);