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);