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.
This commit is contained in:
baldurk
2018-01-24 11:38:37 +00:00
parent 8c25630369
commit 5150a9531b
12 changed files with 128 additions and 105 deletions
+7 -6
View File
@@ -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());
});
}
}
@@ -587,6 +587,38 @@
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="numFramesLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string># Frames:</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="numFrames">
<property name="minimumSize">
<size>
<width>45</width>
<height>0</height>
</size>
</property>
<property name="decimals">
<number>0</number>
</property>
<property name="minimum">
<double>1.000000000000000</double>
</property>
<property name="maximum">
<double>4.000000000000000</double>
</property>
</widget>
</item>
<item>
<spacer name="ActionsSpacer">
<property name="orientation">
+11 -13
View File
@@ -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())
+2 -2
View File
@@ -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;
+38 -56
View File
@@ -177,27 +177,7 @@
<string>Tools</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="1" column="2" colspan="3">
<widget class="QDoubleSpinBox" name="captureFrame">
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="decimals">
<number>0</number>
</property>
<property name="maximum">
<double>10000.000000000000000</double>
</property>
</widget>
</item>
<item row="1" column="5">
<widget class="QPushButton" name="queueCap">
<property name="text">
<string>Queue Capture</string>
</property>
</widget>
</item>
<item row="0" column="2">
<item row="1" column="1">
<widget class="QDoubleSpinBox" name="captureDelay">
<property name="baseSize">
<size>
@@ -219,7 +199,34 @@
</property>
</widget>
</item>
<item row="0" column="4">
<item row="4" column="1">
<widget class="QDoubleSpinBox" name="captureFrame">
<property name="prefix">
<string>Frame </string>
</property>
<property name="decimals">
<number>0</number>
</property>
<property name="maximum">
<double>10000.000000000000000</double>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QPushButton" name="triggerCapture">
<property name="text">
<string>Trigger After Delay</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QPushButton" name="queueCap">
<property name="text">
<string>Queue Specific Frame</string>
</property>
</widget>
</item>
<item row="0" column="0" colspan="2">
<widget class="QDoubleSpinBox" name="numFrames">
<property name="minimumSize">
<size>
@@ -227,6 +234,12 @@
<height>0</height>
</size>
</property>
<property name="prefix">
<string>Capture </string>
</property>
<property name="suffix">
<string> Sequential Frame(s)</string>
</property>
<property name="decimals">
<number>0</number>
</property>
@@ -236,43 +249,12 @@
<property name="maximum">
<double>4.000000000000000</double>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="capDelayLabel">
<property name="text">
<string>Capture Delay</string>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QLabel" name="numFramesLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string># Frames:</string>
</property>
</widget>
</item>
<item row="0" column="5">
<widget class="QPushButton" name="triggerCapture">
<property name="text">
<string>Trigger Capture</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="capFrameLabel">
<property name="text">
<string>Capture Frame #</string>
</property>
</widget>
</item>
<item row="2" column="2">
<item row="5" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
+6 -1
View File
@@ -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.
+1 -1
View File
@@ -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;
+8 -4
View File
@@ -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);
+6 -6
View File
@@ -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();
+5 -5
View File
@@ -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);
+7 -6
View File
@@ -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();
+5 -5
View File
@@ -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);