Commit e356ce28 authored by Laszlo Agocs's avatar Laszlo Agocs
Browse files

Evolve the api, introduce finish()

parent 969214c6
......@@ -108,9 +108,10 @@ int main(int argc, char **argv)
r->readback(cb, rb, &rbResult);
qDebug("Submit and wait");
r->endAndWaitOffscreenFrame();
r->endOffscreenFrame();
// here it's simple, no need to bother with the completed callback of rbResult
// No finish() or waiting for the completed callback is needed here
// since the endOffscreenFrame() implies a wait for completion.
qDebug() << rbResult.data.size();
}
......
......@@ -420,9 +420,19 @@ QRhi::FrameOpResult QRhi::beginOffscreenFrame(QRhiCommandBuffer **cb)
return d->beginOffscreenFrame(cb);
}
QRhi::FrameOpResult QRhi::endAndWaitOffscreenFrame()
QRhi::FrameOpResult QRhi::endOffscreenFrame()
{
return d->endAndWaitOffscreenFrame();
return d->endOffscreenFrame();
}
void QRhi::readback(QRhiCommandBuffer *cb, const QRhiReadbackDescription &rb, QRhiReadbackResult *result)
{
d->readback(cb, rb, result);
}
QRhi::FrameOpResult QRhi::finish()
{
return d->finish();
}
void QRhi::beginPass(QRhiRenderTarget *rt,
......@@ -487,11 +497,6 @@ void QRhi::drawIndexed(QRhiCommandBuffer *cb, quint32 indexCount,
d->drawIndexed(cb, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);
}
void QRhi::readback(QRhiCommandBuffer *cb, const QRhiReadbackDescription &rb, QRhiReadbackResult *result)
{
d->readback(cb, rb, result);
}
QVector<int> QRhi::supportedSampleCounts() const
{
return d->supportedSampleCounts();
......
......@@ -986,21 +986,35 @@ public:
FrameOpResult endFrame(QRhiSwapChain *swapChain);
/*
Rendering without a swapchain is possible as well. This is synchronous in
the sense that end will wait for completion of the submitted commands.
The typical use case is to use it in completely offscreen applications,
e.g. to generate image sequences by rendering and reading back without
ever showing a window.
Rendering without a swapchain is possible as well. The typical use case
is to use it in completely offscreen applications, e.g. to generate image
sequences by rendering and reading back without ever showing a window.
Usage in on-screen applications (so beginFrame, endFrame,
beginOffscreenFrame, endOffscreenFrame, beginFrame, ...) is possible too but
it does break parallelism so should be done only infrequently.
QRhiReadbackResult rbResult;
QRhiCommandBuffer *cb; // not owned
beginOffscreenFrame(&cb);
// ... the usual, set up a QRhiTextureRenderTarget, beginPass-endPass, etc.
readback(cb, rb, &rbResult);
endAndWaitOffscreenFrame();
endOffscreenFrame();
// image data available in rbResult
*/
FrameOpResult beginOffscreenFrame(QRhiCommandBuffer **cb);
FrameOpResult endAndWaitOffscreenFrame();
FrameOpResult endOffscreenFrame();
// Cannot be inside a pass.
void readback(QRhiCommandBuffer *cb, const QRhiReadbackDescription &rb, QRhiReadbackResult *result);
// Waits for any work on the graphics queue (where applicable) to complete,
// then forcibly executes all deferred operations, like completing
// readbacks and resource releases. This should _not_ be used in practice,
// except in infrequent special cases, like when the results of a readback
// are needed right away. Can be called inside and outside of a frame, but
// not inside a pass. Inside a frame it implies submitting any work on the
// command buffer. Unnecessary in combination with begin/endOffscreenFrame
// because ending an offscreen frame implies waiting for completion.
QRhi::FrameOpResult finish();
// Returns an instance to which updates can be queued. Batch instances are
// pooled and never owned by the application. An instance is returned to
......@@ -1049,9 +1063,6 @@ public:
quint32 instanceCount = 1, quint32 firstIndex = 0,
qint32 vertexOffset = 0, quint32 firstInstance = 0);
// Cannot be mixed with beginPass-endPass.
void readback(QRhiCommandBuffer *cb, const QRhiReadbackDescription &rb, QRhiReadbackResult *result);
QVector<int> supportedSampleCounts() const;
int ubufAlignment() const;
......
......@@ -84,7 +84,9 @@ public:
virtual QRhi::FrameOpResult beginFrame(QRhiSwapChain *swapChain) = 0;
virtual QRhi::FrameOpResult endFrame(QRhiSwapChain *swapChain) = 0;
virtual QRhi::FrameOpResult beginOffscreenFrame(QRhiCommandBuffer **cb) = 0;
virtual QRhi::FrameOpResult endAndWaitOffscreenFrame() = 0;
virtual QRhi::FrameOpResult endOffscreenFrame() = 0;
virtual void readback(QRhiCommandBuffer *cb, const QRhiReadbackDescription &rb, QRhiReadbackResult *result) = 0;
virtual QRhi::FrameOpResult finish() = 0;
virtual void beginPass(QRhiRenderTarget *rt,
QRhiCommandBuffer *cb,
......@@ -113,8 +115,6 @@ public:
quint32 instanceCount, quint32 firstIndex,
qint32 vertexOffset, quint32 firstInstance) = 0;
virtual void readback(QRhiCommandBuffer *cb, const QRhiReadbackDescription &rb, QRhiReadbackResult *result) = 0;
virtual QVector<int> supportedSampleCounts() const = 0;
virtual int ubufAlignment() const = 0;
virtual bool isYUpInFramebuffer() const = 0;
......
......@@ -453,13 +453,6 @@ void QRhiD3D11::drawIndexed(QRhiCommandBuffer *cb, quint32 indexCount,
cbD->commands.append(cmd);
}
void QRhiD3D11::readback(QRhiCommandBuffer *cb, const QRhiReadbackDescription &rb, QRhiReadbackResult *result)
{
Q_UNUSED(cb);
Q_UNUSED(rb);
Q_UNUSED(result);
}
QRhi::FrameOpResult QRhiD3D11::beginFrame(QRhiSwapChain *swapChain)
{
Q_ASSERT(!inFrame);
......@@ -510,11 +503,27 @@ QRhi::FrameOpResult QRhiD3D11::beginOffscreenFrame(QRhiCommandBuffer **cb)
return QRhi::FrameOpError;
}
QRhi::FrameOpResult QRhiD3D11::endAndWaitOffscreenFrame()
QRhi::FrameOpResult QRhiD3D11::endOffscreenFrame()
{
return QRhi::FrameOpError;
}
void QRhiD3D11::readback(QRhiCommandBuffer *cb, const QRhiReadbackDescription &rb, QRhiReadbackResult *result)
{
Q_UNUSED(cb);
Q_UNUSED(rb);
Q_UNUSED(result);
Q_ASSERT(inFrame && !inPass);
}
QRhi::FrameOpResult QRhiD3D11::finish()
{
Q_ASSERT(!inPass);
return QRhi::FrameOpSuccess;
}
static inline bool isCompressedFormat(QRhiTexture::Format format)
{
return format >= QRhiTexture::BC1 && format <= QRhiTexture::BC7;
......
......@@ -375,7 +375,9 @@ public:
QRhi::FrameOpResult beginFrame(QRhiSwapChain *swapChain) override;
QRhi::FrameOpResult endFrame(QRhiSwapChain *swapChain) override;
QRhi::FrameOpResult beginOffscreenFrame(QRhiCommandBuffer **cb) override;
QRhi::FrameOpResult endAndWaitOffscreenFrame() override;
QRhi::FrameOpResult endOffscreenFrame() override;
void readback(QRhiCommandBuffer *cb, const QRhiReadbackDescription &rb, QRhiReadbackResult *result) override;
QRhi::FrameOpResult finish() override;
void beginPass(QRhiRenderTarget *rt,
QRhiCommandBuffer *cb,
......@@ -405,8 +407,6 @@ public:
quint32 instanceCount, quint32 firstIndex,
qint32 vertexOffset, quint32 firstInstance) override;
void readback(QRhiCommandBuffer *cb, const QRhiReadbackDescription &rb, QRhiReadbackResult *result) override;
QVector<int> supportedSampleCounts() const override;
int ubufAlignment() const override;
bool isYUpInFramebuffer() const override;
......
......@@ -366,13 +366,6 @@ void QRhiGles2::drawIndexed(QRhiCommandBuffer *cb, quint32 indexCount,
cbD->commands.append(cmd);
}
void QRhiGles2::readback(QRhiCommandBuffer *cb, const QRhiReadbackDescription &rb, QRhiReadbackResult *result)
{
Q_UNUSED(cb);
Q_UNUSED(rb);
Q_UNUSED(result);
}
QRhi::FrameOpResult QRhiGles2::beginFrame(QRhiSwapChain *swapChain)
{
Q_ASSERT(!inFrame);
......@@ -412,11 +405,27 @@ QRhi::FrameOpResult QRhiGles2::beginOffscreenFrame(QRhiCommandBuffer **cb)
return QRhi::FrameOpError;
}
QRhi::FrameOpResult QRhiGles2::endAndWaitOffscreenFrame()
QRhi::FrameOpResult QRhiGles2::endOffscreenFrame()
{
return QRhi::FrameOpError;
}
void QRhiGles2::readback(QRhiCommandBuffer *cb, const QRhiReadbackDescription &rb, QRhiReadbackResult *result)
{
Q_UNUSED(cb);
Q_UNUSED(rb);
Q_UNUSED(result);
Q_ASSERT(inFrame && !inPass);
}
QRhi::FrameOpResult QRhiGles2::finish()
{
Q_ASSERT(!inPass);
return QRhi::FrameOpSuccess;
}
void QRhiGles2::commitResourceUpdates(QRhiResourceUpdateBatch *resourceUpdates)
{
QRhiResourceUpdateBatchPrivate *ud = QRhiResourceUpdateBatchPrivate::get(resourceUpdates);
......
......@@ -333,7 +333,9 @@ public:
QRhi::FrameOpResult beginFrame(QRhiSwapChain *swapChain) override;
QRhi::FrameOpResult endFrame(QRhiSwapChain *swapChain) override;
QRhi::FrameOpResult beginOffscreenFrame(QRhiCommandBuffer **cb) override;
QRhi::FrameOpResult endAndWaitOffscreenFrame() override;
QRhi::FrameOpResult endOffscreenFrame() override;
void readback(QRhiCommandBuffer *cb, const QRhiReadbackDescription &rb, QRhiReadbackResult *result) override;
QRhi::FrameOpResult finish() override;
void beginPass(QRhiRenderTarget *rt,
QRhiCommandBuffer *cb,
......@@ -363,8 +365,6 @@ public:
quint32 instanceCount, quint32 firstIndex,
qint32 vertexOffset, quint32 firstInstance) override;
void readback(QRhiCommandBuffer *cb, const QRhiReadbackDescription &rb, QRhiReadbackResult *result) override;
QVector<int> supportedSampleCounts() const override;
int ubufAlignment() const override;
bool isYUpInFramebuffer() const override;
......
......@@ -496,13 +496,6 @@ void QRhiMetal::drawIndexed(QRhiCommandBuffer *cb, quint32 indexCount,
baseInstance: firstInstance];
}
void QRhiMetal::readback(QRhiCommandBuffer *cb, const QRhiReadbackDescription &rb, QRhiReadbackResult *result)
{
Q_UNUSED(cb);
Q_UNUSED(rb);
Q_UNUSED(result);
}
QRhi::FrameOpResult QRhiMetal::beginFrame(QRhiSwapChain *swapChain)
{
Q_ASSERT(!inFrame);
......@@ -570,11 +563,27 @@ QRhi::FrameOpResult QRhiMetal::beginOffscreenFrame(QRhiCommandBuffer **cb)
return QRhi::FrameOpError;
}
QRhi::FrameOpResult QRhiMetal::endAndWaitOffscreenFrame()
QRhi::FrameOpResult QRhiMetal::endOffscreenFrame()
{
return QRhi::FrameOpError;
}
void QRhiMetal::readback(QRhiCommandBuffer *cb, const QRhiReadbackDescription &rb, QRhiReadbackResult *result)
{
Q_UNUSED(cb);
Q_UNUSED(rb);
Q_UNUSED(result);
Q_ASSERT(inFrame && !inPass);
}
QRhi::FrameOpResult QRhiMetal::finish()
{
Q_ASSERT(!inPass);
return QRhi::FrameOpSuccess;
}
MTLRenderPassDescriptor *QRhiMetalData::createDefaultRenderPass(bool hasDepthStencil,
const QRhiColorClearValue &colorClearValue,
const QRhiDepthStencilClearValue &depthStencilClearValue)
......
......@@ -264,7 +264,9 @@ public:
QRhi::FrameOpResult beginFrame(QRhiSwapChain *swapChain) override;
QRhi::FrameOpResult endFrame(QRhiSwapChain *swapChain) override;
QRhi::FrameOpResult beginOffscreenFrame(QRhiCommandBuffer **cb) override;
QRhi::FrameOpResult endAndWaitOffscreenFrame() override;
QRhi::FrameOpResult endOffscreenFrame() override;
void readback(QRhiCommandBuffer *cb, const QRhiReadbackDescription &rb, QRhiReadbackResult *result) override;
QRhi::FrameOpResult finish() override;
void beginPass(QRhiRenderTarget *rt,
QRhiCommandBuffer *cb,
......@@ -294,8 +296,6 @@ public:
quint32 instanceCount, quint32 firstIndex,
qint32 vertexOffset, quint32 firstInstance) override;
void readback(QRhiCommandBuffer *cb, const QRhiReadbackDescription &rb, QRhiReadbackResult *result) override;
QVector<int> supportedSampleCounts() const override;
int ubufAlignment() const override;
bool isYUpInFramebuffer() const override;
......
......@@ -1121,6 +1121,7 @@ QRhi::FrameOpResult QRhiVulkan::beginWrapperFrame(QRhiSwapChain *swapChain)
swapChainD->m_requestedPixelSize = swapChainD->pixelSize = swapChainD->rtWrapper.d.pixelSize = w->swapChainImageSize();
currentFrameSlot = w->currentFrame();
currentSwapChain = swapChainD;
prepareNewFrame(&swapChainD->cbWrapper);
......@@ -1131,7 +1132,88 @@ QRhi::FrameOpResult QRhiVulkan::endWrapperFrame(QRhiSwapChain *swapChain)
{
Q_UNUSED(swapChain);
finishFrame();
prepareFrameEnd();
currentSwapChain = nullptr;
return QRhi::FrameOpSuccess;
}
QRhi::FrameOpResult QRhiVulkan::startCommandBuffer(VkCommandBuffer *cb)
{
if (*cb) {
df->vkFreeCommandBuffers(dev, cmdPool, 1, cb);
*cb = VK_NULL_HANDLE;
}
VkCommandBufferAllocateInfo cmdBufInfo;
memset(&cmdBufInfo, 0, sizeof(cmdBufInfo));
cmdBufInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
cmdBufInfo.commandPool = cmdPool;
cmdBufInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
cmdBufInfo.commandBufferCount = 1;
VkResult err = df->vkAllocateCommandBuffers(dev, &cmdBufInfo, cb);
if (err != VK_SUCCESS) {
if (checkDeviceLost(err))
return QRhi::FrameOpDeviceLost;
else
qWarning("Failed to allocate frame command buffer: %d", err);
return QRhi::FrameOpError;
}
VkCommandBufferBeginInfo cmdBufBeginInfo;
memset(&cmdBufBeginInfo, 0, sizeof(cmdBufBeginInfo));
cmdBufBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
err = df->vkBeginCommandBuffer(*cb, &cmdBufBeginInfo);
if (err != VK_SUCCESS) {
if (checkDeviceLost(err))
return QRhi::FrameOpDeviceLost;
else
qWarning("Failed to begin frame command buffer: %d", err);
return QRhi::FrameOpError;
}
return QRhi::FrameOpSuccess;
}
QRhi::FrameOpResult QRhiVulkan::endAndSubmitCommandBuffer(VkCommandBuffer cb, VkFence cmdFence,
VkSemaphore *waitSem, VkSemaphore *signalSem)
{
VkResult err = df->vkEndCommandBuffer(cb);
if (err != VK_SUCCESS) {
if (checkDeviceLost(err))
return QRhi::FrameOpDeviceLost;
else
qWarning("Failed to end frame command buffer: %d", err);
return QRhi::FrameOpError;
}
VkSubmitInfo submitInfo;
memset(&submitInfo, 0, sizeof(submitInfo));
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &cb;
if (waitSem) {
submitInfo.waitSemaphoreCount = 1;
submitInfo.pWaitSemaphores = waitSem;
}
if (signalSem) {
submitInfo.signalSemaphoreCount = 1;
submitInfo.pSignalSemaphores = signalSem;
}
VkPipelineStageFlags psf = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
submitInfo.pWaitDstStageMask = &psf;
err = df->vkQueueSubmit(gfxQueue, 1, &submitInfo, cmdFence);
if (err != VK_SUCCESS) {
if (checkDeviceLost(err))
return QRhi::FrameOpDeviceLost;
else
qWarning("Failed to submit to graphics queue: %d", err);
return QRhi::FrameOpError;
}
return QRhi::FrameOpSuccess;
}
......@@ -1176,45 +1258,16 @@ QRhi::FrameOpResult QRhiVulkan::beginNonWrapperFrame(QRhiSwapChain *swapChain)
}
// build new draw command buffer
if (image.cmdBuf) {
df->vkFreeCommandBuffers(dev, cmdPool, 1, &image.cmdBuf);
image.cmdBuf = VK_NULL_HANDLE;
}
VkCommandBufferAllocateInfo cmdBufInfo;
memset(&cmdBufInfo, 0, sizeof(cmdBufInfo));
cmdBufInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
cmdBufInfo.commandPool = cmdPool;
cmdBufInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
cmdBufInfo.commandBufferCount = 1;
VkResult err = df->vkAllocateCommandBuffers(dev, &cmdBufInfo, &image.cmdBuf);
if (err != VK_SUCCESS) {
if (checkDeviceLost(err))
return QRhi::FrameOpDeviceLost;
else
qWarning("Failed to allocate frame command buffer: %d", err);
return QRhi::FrameOpError;
}
VkCommandBufferBeginInfo cmdBufBeginInfo;
memset(&cmdBufBeginInfo, 0, sizeof(cmdBufBeginInfo));
cmdBufBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
err = df->vkBeginCommandBuffer(image.cmdBuf, &cmdBufBeginInfo);
if (err != VK_SUCCESS) {
if (checkDeviceLost(err))
return QRhi::FrameOpDeviceLost;
else
qWarning("Failed to begin frame command buffer: %d", err);
return QRhi::FrameOpError;
}
QRhi::FrameOpResult cbres = startCommandBuffer(&image.cmdBuf);
if (cbres != QRhi::FrameOpSuccess)
return cbres;
swapChainD->cbWrapper.cb = image.cmdBuf;
swapChainD->rtWrapper.d.fb = image.fb;
currentFrameSlot = swapChainD->currentFrame;
currentSwapChain = swapChainD;
if (swapChainD->ds)
swapChainD->ds->lastActiveFrameSlot = currentFrameSlot;
......@@ -1227,50 +1280,24 @@ QRhi::FrameOpResult QRhiVulkan::endNonWrapperFrame(QRhiSwapChain *swapChain)
{
QVkSwapChain *swapChainD = QRHI_RES(QVkSwapChain, swapChain);
finishFrame();
prepareFrameEnd();
QVkSwapChain::FrameResources &frame(swapChainD->frameRes[swapChainD->currentFrame]);
QVkSwapChain::ImageResources &image(swapChainD->imageRes[swapChainD->currentImage]);
VkResult err = df->vkEndCommandBuffer(image.cmdBuf);
if (err != VK_SUCCESS) {
if (checkDeviceLost(err))
return QRhi::FrameOpDeviceLost;
else
qWarning("Failed to end frame command buffer: %d", err);
return QRhi::FrameOpError;
}
// submit draw calls
VkSubmitInfo submitInfo;
memset(&submitInfo, 0, sizeof(submitInfo));
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &image.cmdBuf;
if (frame.imageSemWaitable) {
submitInfo.waitSemaphoreCount = 1;
submitInfo.pWaitSemaphores = &frame.imageSem;
}
submitInfo.signalSemaphoreCount = 1;
submitInfo.pSignalSemaphores = &frame.drawSem;
VkPipelineStageFlags psf = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
submitInfo.pWaitDstStageMask = &psf;
// stop recording and submit to the queue
Q_ASSERT(!image.cmdFenceWaitable);
QRhi::FrameOpResult submitres = endAndSubmitCommandBuffer(image.cmdBuf,
image.cmdFence,
frame.imageSemWaitable ? &frame.imageSem : nullptr,
&frame.drawSem);
if (submitres != QRhi::FrameOpSuccess)
return submitres;
err = df->vkQueueSubmit(gfxQueue, 1, &submitInfo, image.cmdFence);
if (err == VK_SUCCESS) {
frame.imageSemWaitable = false;
image.cmdFenceWaitable = true;
} else {
if (checkDeviceLost(err))
return QRhi::FrameOpDeviceLost;
else
qWarning("Failed to submit to graphics queue: %d", err);
return QRhi::FrameOpError;
}
frame.imageSemWaitable = false;
image.cmdFenceWaitable = true;
// add the Present to the queue
VkPresentInfoKHR presInfo;
memset(&presInfo, 0, sizeof(presInfo));
presInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
......@@ -1280,7 +1307,7 @@ QRhi::FrameOpResult QRhiVulkan::endNonWrapperFrame(QRhiSwapChain *swapChain)
presInfo.waitSemaphoreCount = 1;
presInfo.pWaitSemaphores = &frame.drawSem; // gfxQueueFamilyIdx == presQueueFamilyIdx ? &frame.drawSem : &frame.presTransSem;
err = vkQueuePresentKHR(gfxQueue, &presInfo);
VkResult err = vkQueuePresentKHR(gfxQueue, &presInfo);
if (err != VK_SUCCESS) {
if (err == VK_ERROR_OUT_OF_DATE_KHR) {
return QRhi::FrameOpSwapChainOutOfDate;
......@@ -1297,44 +1324,16 @@ QRhi::FrameOpResult QRhiVulkan::endNonWrapperFrame(QRhiSwapChain *swapChain)
swapChainD->currentFrame = (swapChainD->currentFrame + 1) % QVK_FRAMES_IN_FLIGHT;
currentSwapChain = nullptr;
return QRhi::FrameOpSuccess;
}
QRhi::FrameOpResult QRhiVulkan::beginOffscreenFrame(QRhiCommandBuffer **cb)
{
if (ofr.cbWrapper.cb) {
df->vkFreeCommandBuffers(dev, cmdPool, 1, &ofr.cbWrapper.cb);
ofr.cbWrapper.cb = VK_NULL_HANDLE;
}
VkCommandBufferAllocateInfo cmdBufInfo;
memset(&cmdBufInfo, 0, sizeof(cmdBufInfo));
cmdBufInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
cmdBufInfo.commandPool = cmdPool;
cmdBufInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
cmdBufInfo.commandBufferCount = 1;
VkResult err = df->vkAllocateCommandBuffers(dev, &cmdBufInfo, &ofr.cbWrapper.cb);
if (err != VK_SUCCESS) {
if (checkDeviceLost(err))
return QRhi::FrameOpDeviceLost;
else
qWarning("Failed to allocate offscreen frame command buffer: %d", err);
return QRhi::FrameOpError;
}
VkCommandBufferBeginInfo cmdBufBeginInfo;
memset(&cmdBufBeginInfo, 0, sizeof(cmdBufBeginInfo));
cmdBufBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
err = df->vkBeginCommandBuffer(ofr.cbWrapper.cb, &cmdBufBeginInfo);
if (err != VK_SUCCESS) {
if (checkDeviceLost(err))
return QRhi::FrameOpDeviceLost;
else
qWarning("Failed to begin offscreen frame command buffer: %d", err);
return QRhi::FrameOpError;
}
QRhi::FrameOpResult cbres = startCommandBuffer(&ofr.cbWrapper.cb);
if (cbres != QRhi::FrameOpSuccess)
return cbres;
// Switch to the next slot manually. Swapchains do not know about this
// which is good. So for example a - unusual but possible - onscreen,
......@@ -1346,51 +1345,31 @@ QRhi::FrameOpResult QRhiVulkan::beginOffscreenFrame(QRhiCommandBuffer **cb)
currentFrameSlot = (currentFrameSlot + 1) % QVK_FRAMES_IN_FLIGHT;
prepareNewFrame(&ofr.cbWrapper);
ofr.active = true;
*cb = &ofr.cbWrapper;
return QRhi::FrameOpSuccess;
}
QRhi::FrameOpResult QRhiVulkan::endAndWaitOffscreenFrame()
QRhi::FrameOpResult QRhiVulkan::endOffscreenFrame()
{
finishFrame();
VkResult err = df->vkEndCommandBuffer(ofr.cbWrapper.cb);
if (err != VK_SUCCESS) {
if (checkDeviceLost(err))
return QRhi::FrameOpDeviceLost;
else
qWarning("Failed to end offscreen frame command buffer: %d", err);
return QRhi::FrameOpError;
}
ofr.active = false;
prepareFrameEnd();
if (!ofr.cmdFence) {
VkFenceCreateInfo fenceInfo;
memset(&fenceInfo, 0, sizeof(fenceInfo));
fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
err = df->vkCreateFence(dev, &fenceInfo, nullptr, &ofr.cmdFence);
VkResult err = df->vkCreateFence(dev, &fenceInfo, nullptr, &ofr.cmdFence);
if (err != VK_SUCCESS) {
qWarning("Failed to create command buffer fence: %d", err);
return QRhi::FrameOpError;