diff --git a/src/gui/rhi/qrhi.cpp b/src/gui/rhi/qrhi.cpp index 151e1268f6..0dc3082b03 100644 --- a/src/gui/rhi/qrhi.cpp +++ b/src/gui/rhi/qrhi.cpp @@ -614,11 +614,6 @@ Q_LOGGING_CATEGORY(QRHI_LOG_INFO, "qt.rhi.general") /*! \enum QRhi::BeginFrameFlag Flag values for QRhi::beginFrame() - - \value ExternalContentsInPass Specifies that one or more render or compute - passes in this frame will call QRhiCommandBuffer::beginExternal(). Some - backends, Vulkan in particular, will fail if this flag is not set and - beginExternal() is still called. */ /*! @@ -4090,6 +4085,26 @@ QRhiComputePipeline::QRhiComputePipeline(QRhiImplementation *rhi) \value IndexUInt32 Unsigned 32-bit (quint32) */ +/*! + \enum QRhiCommandBuffer::BeginPassFlag + Flag values for QRhi::beginPass() + + \value ExternalContent Specifies that there will be a call to + QRhiCommandBuffer::beginExternal() in this pass. Some backends, Vulkan in + particular, will fail if this flag is not set and beginExternal() is still + called. + + \value DoNotTrackResourcesForCompute Specifies that there is no need to + track resources used in this pass if the only purpose of such tracking is + to generate barriers for compute. Implies that there are no compute passes + in the frame. This is an optimization hint that may be taken into account + by certain backends, OpenGL in particular, allowing them to skip certain + operations. When this flag is set for a render pass in a frame, calling + \l{QRhiCommandBuffer::beginComputePass()}{beginComputePass()} in that frame + may lead to unexpected behavior, depending on the resource dependencies + between the render and compute passes. + */ + /*! \typedef QRhiCommandBuffer::DynamicOffset @@ -5135,9 +5150,10 @@ void QRhiCommandBuffer::resourceUpdate(QRhiResourceUpdateBatch *resourceUpdates) void QRhiCommandBuffer::beginPass(QRhiRenderTarget *rt, const QColor &colorClearValue, const QRhiDepthStencilClearValue &depthStencilClearValue, - QRhiResourceUpdateBatch *resourceUpdates) + QRhiResourceUpdateBatch *resourceUpdates, + BeginPassFlags flags) { - m_rhi->beginPass(this, rt, colorClearValue, depthStencilClearValue, resourceUpdates); + m_rhi->beginPass(this, rt, colorClearValue, depthStencilClearValue, resourceUpdates, flags); } /*! @@ -5466,9 +5482,9 @@ void QRhiCommandBuffer::debugMarkMsg(const QByteArray &msg) \note Compute is only available when the \l{QRhi::Compute}{Compute} feature is reported as supported. */ -void QRhiCommandBuffer::beginComputePass(QRhiResourceUpdateBatch *resourceUpdates) +void QRhiCommandBuffer::beginComputePass(QRhiResourceUpdateBatch *resourceUpdates, BeginPassFlags flags) { - m_rhi->beginComputePass(this, resourceUpdates); + m_rhi->beginComputePass(this, resourceUpdates, flags); } /*! @@ -5543,10 +5559,10 @@ const QRhiNativeHandles *QRhiCommandBuffer::nativeHandles() enqueue commands to the current pass' command buffer by calling graphics API functions directly. - \note This is only available when the intent was declared up front in - beginFrame(). Therefore this function must only be called when the frame - was started with specifying QRhi::ExternalContentsInPass in the flags - passed to QRhi::beginFrame(). + \note This is only available when the intent was declared upfront in + beginPass() or beginComputePass(). Therefore this function must only be + called when the pass recording was started with specifying + QRhiCommandBuffer::ExternalContent. With Vulkan or Metal one can query the native command buffer or encoder objects via nativeHandles() and enqueue commands to them. With OpenGL or @@ -5993,9 +6009,7 @@ QRhiSwapChain *QRhi::newSwapChain() A frame consists of resource updates and one or more render and compute passes. - \a flags can indicate certain special cases. For example, the fact that - QRhiCommandBuffer::beginExternal() will be called within this new frame - must be declared up front by setting the ExternalContentsInPass flag. + \a flags can indicate certain special cases. The high level pattern of rendering into a QWindow using a swapchain: diff --git a/src/gui/rhi/qrhi_p.h b/src/gui/rhi/qrhi_p.h index d3e32f2723..adbb1b61ff 100644 --- a/src/gui/rhi/qrhi_p.h +++ b/src/gui/rhi/qrhi_p.h @@ -1331,6 +1331,12 @@ public: IndexUInt32 }; + enum BeginPassFlag { + ExternalContent = 0x01, + DoNotTrackResourcesForCompute = 0x02 + }; + Q_DECLARE_FLAGS(BeginPassFlags, BeginPassFlag) + QRhiResource::Type resourceType() const override; void resourceUpdate(QRhiResourceUpdateBatch *resourceUpdates); @@ -1338,7 +1344,8 @@ public: void beginPass(QRhiRenderTarget *rt, const QColor &colorClearValue, const QRhiDepthStencilClearValue &depthStencilClearValue, - QRhiResourceUpdateBatch *resourceUpdates = nullptr); + QRhiResourceUpdateBatch *resourceUpdates = nullptr, + BeginPassFlags flags = {}); void endPass(QRhiResourceUpdateBatch *resourceUpdates = nullptr); void setGraphicsPipeline(QRhiGraphicsPipeline *ps); @@ -1371,7 +1378,7 @@ public: void debugMarkEnd(); void debugMarkMsg(const QByteArray &msg); - void beginComputePass(QRhiResourceUpdateBatch *resourceUpdates = nullptr); + void beginComputePass(QRhiResourceUpdateBatch *resourceUpdates = nullptr, BeginPassFlags flags = {}); void endComputePass(QRhiResourceUpdateBatch *resourceUpdates = nullptr); void setComputePipeline(QRhiComputePipeline *ps); void dispatch(int x, int y, int z); @@ -1384,6 +1391,8 @@ protected: QRhiCommandBuffer(QRhiImplementation *rhi); }; +Q_DECLARE_OPERATORS_FOR_FLAGS(QRhiCommandBuffer::BeginPassFlags) + struct Q_GUI_EXPORT QRhiReadbackResult { std::function completed = nullptr; @@ -1484,7 +1493,6 @@ public: }; enum BeginFrameFlag { - ExternalContentsInPass = 0x01 }; Q_DECLARE_FLAGS(BeginFrameFlags, BeginFrameFlag) @@ -1510,7 +1518,7 @@ public: static QRhi *create(Implementation impl, QRhiInitParams *params, - Flags flags = Flags(), + Flags flags = {}, QRhiNativeHandles *importDevice = nullptr); Implementation backend() const; @@ -1531,13 +1539,13 @@ public: QRhiRenderBuffer *newRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize, int sampleCount = 1, - QRhiRenderBuffer::Flags flags = QRhiRenderBuffer::Flags(), + QRhiRenderBuffer::Flags flags = {}, QRhiTexture::Format backingFormatHint = QRhiTexture::UnknownFormat); QRhiTexture *newTexture(QRhiTexture::Format format, const QSize &pixelSize, int sampleCount = 1, - QRhiTexture::Flags flags = QRhiTexture::Flags()); + QRhiTexture::Flags flags = {}); QRhiSampler *newSampler(QRhiSampler::Filter magFilter, QRhiSampler::Filter minFilter, @@ -1547,16 +1555,16 @@ public: QRhiSampler::AddressMode addressW = QRhiSampler::Repeat); QRhiTextureRenderTarget *newTextureRenderTarget(const QRhiTextureRenderTargetDescription &desc, - QRhiTextureRenderTarget::Flags flags = QRhiTextureRenderTarget::Flags()); + QRhiTextureRenderTarget::Flags flags = {}); QRhiSwapChain *newSwapChain(); - FrameOpResult beginFrame(QRhiSwapChain *swapChain, BeginFrameFlags flags = BeginFrameFlags()); - FrameOpResult endFrame(QRhiSwapChain *swapChain, EndFrameFlags flags = EndFrameFlags()); + FrameOpResult beginFrame(QRhiSwapChain *swapChain, BeginFrameFlags flags = {}); + FrameOpResult endFrame(QRhiSwapChain *swapChain, EndFrameFlags flags = {}); bool isRecordingFrame() const; int currentFrameSlot() const; - FrameOpResult beginOffscreenFrame(QRhiCommandBuffer **cb, BeginFrameFlags flags = BeginFrameFlags()); - FrameOpResult endOffscreenFrame(EndFrameFlags flags = EndFrameFlags()); + FrameOpResult beginOffscreenFrame(QRhiCommandBuffer **cb, BeginFrameFlags flags = {}); + FrameOpResult endOffscreenFrame(EndFrameFlags flags = {}); QRhi::FrameOpResult finish(); @@ -1576,7 +1584,7 @@ public: QMatrix4x4 clipSpaceCorrMatrix() const; - bool isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture::Flags flags = QRhiTexture::Flags()) const; + bool isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture::Flags flags = {}) const; bool isFeatureSupported(QRhi::Feature feature) const; int resourceLimit(ResourceLimit limit) const; diff --git a/src/gui/rhi/qrhi_p_p.h b/src/gui/rhi/qrhi_p_p.h index 1316321694..3a76e9b97b 100644 --- a/src/gui/rhi/qrhi_p_p.h +++ b/src/gui/rhi/qrhi_p_p.h @@ -109,7 +109,8 @@ public: QRhiRenderTarget *rt, const QColor &colorClearValue, const QRhiDepthStencilClearValue &depthStencilClearValue, - QRhiResourceUpdateBatch *resourceUpdates) = 0; + QRhiResourceUpdateBatch *resourceUpdates, + QRhiCommandBuffer::BeginPassFlags flags) = 0; virtual void endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) = 0; virtual void setGraphicsPipeline(QRhiCommandBuffer *cb, @@ -140,7 +141,9 @@ public: virtual void debugMarkEnd(QRhiCommandBuffer *cb) = 0; virtual void debugMarkMsg(QRhiCommandBuffer *cb, const QByteArray &msg) = 0; - virtual void beginComputePass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) = 0; + virtual void beginComputePass(QRhiCommandBuffer *cb, + QRhiResourceUpdateBatch *resourceUpdates, + QRhiCommandBuffer::BeginPassFlags flags) = 0; virtual void endComputePass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) = 0; virtual void setComputePipeline(QRhiCommandBuffer *cb, QRhiComputePipeline *ps) = 0; virtual void dispatch(QRhiCommandBuffer *cb, int x, int y, int z) = 0; diff --git a/src/gui/rhi/qrhid3d11.cpp b/src/gui/rhi/qrhid3d11.cpp index 2fe138dd55..4d00f11c84 100644 --- a/src/gui/rhi/qrhid3d11.cpp +++ b/src/gui/rhi/qrhid3d11.cpp @@ -1711,7 +1711,8 @@ void QRhiD3D11::beginPass(QRhiCommandBuffer *cb, QRhiRenderTarget *rt, const QColor &colorClearValue, const QRhiDepthStencilClearValue &depthStencilClearValue, - QRhiResourceUpdateBatch *resourceUpdates) + QRhiResourceUpdateBatch *resourceUpdates, + QRhiCommandBuffer::BeginPassFlags) { QD3D11CommandBuffer *cbD = QRHI_RES(QD3D11CommandBuffer, cb); Q_ASSERT(cbD->recordingPass == QD3D11CommandBuffer::NoPass); @@ -1822,7 +1823,9 @@ void QRhiD3D11::endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resource enqueueResourceUpdates(cb, resourceUpdates); } -void QRhiD3D11::beginComputePass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) +void QRhiD3D11::beginComputePass(QRhiCommandBuffer *cb, + QRhiResourceUpdateBatch *resourceUpdates, + QRhiCommandBuffer::BeginPassFlags) { QD3D11CommandBuffer *cbD = QRHI_RES(QD3D11CommandBuffer, cb); Q_ASSERT(cbD->recordingPass == QD3D11CommandBuffer::NoPass); diff --git a/src/gui/rhi/qrhid3d11_p_p.h b/src/gui/rhi/qrhid3d11_p_p.h index b89b6f5124..bec263e210 100644 --- a/src/gui/rhi/qrhid3d11_p_p.h +++ b/src/gui/rhi/qrhid3d11_p_p.h @@ -606,7 +606,8 @@ public: QRhiRenderTarget *rt, const QColor &colorClearValue, const QRhiDepthStencilClearValue &depthStencilClearValue, - QRhiResourceUpdateBatch *resourceUpdates) override; + QRhiResourceUpdateBatch *resourceUpdates, + QRhiCommandBuffer::BeginPassFlags flags) override; void endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override; void setGraphicsPipeline(QRhiCommandBuffer *cb, @@ -638,7 +639,9 @@ public: void debugMarkEnd(QRhiCommandBuffer *cb) override; void debugMarkMsg(QRhiCommandBuffer *cb, const QByteArray &msg) override; - void beginComputePass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override; + void beginComputePass(QRhiCommandBuffer *cb, + QRhiResourceUpdateBatch *resourceUpdates, + QRhiCommandBuffer::BeginPassFlags flags) override; void endComputePass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override; void setComputePipeline(QRhiCommandBuffer *cb, QRhiComputePipeline *ps) override; void dispatch(QRhiCommandBuffer *cb, int x, int y, int z) override; diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp index ea949a8af9..02990e8c92 100644 --- a/src/gui/rhi/qrhigles2.cpp +++ b/src/gui/rhi/qrhigles2.cpp @@ -1103,44 +1103,46 @@ void QRhiGles2::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBind hasDynamicOffsetInSrb = true; break; case QRhiShaderResourceBinding::SampledTexture: - for (int elem = 0; elem < b->u.stex.count; ++elem) { - trackedRegisterTexture(&passResTracker, - QRHI_RES(QGles2Texture, b->u.stex.texSamplers[elem].tex), - QRhiPassResourceTracker::TexSample, - QRhiPassResourceTracker::toPassTrackerTextureStage(b->stage)); + if (cbD->passNeedsResourceTracking) { + for (int elem = 0; elem < b->u.stex.count; ++elem) { + trackedRegisterTexture(&passResTracker, + QRHI_RES(QGles2Texture, b->u.stex.texSamplers[elem].tex), + QRhiPassResourceTracker::TexSample, + QRhiPassResourceTracker::toPassTrackerTextureStage(b->stage)); + } } break; case QRhiShaderResourceBinding::ImageLoad: case QRhiShaderResourceBinding::ImageStore: case QRhiShaderResourceBinding::ImageLoadStore: - { - QGles2Texture *texD = QRHI_RES(QGles2Texture, b->u.simage.tex); - QRhiPassResourceTracker::TextureAccess access; - if (b->type == QRhiShaderResourceBinding::ImageLoad) - access = QRhiPassResourceTracker::TexStorageLoad; - else if (b->type == QRhiShaderResourceBinding::ImageStore) - access = QRhiPassResourceTracker::TexStorageStore; - else - access = QRhiPassResourceTracker::TexStorageLoadStore; - trackedRegisterTexture(&passResTracker, texD, access, - QRhiPassResourceTracker::toPassTrackerTextureStage(b->stage)); - } + if (cbD->passNeedsResourceTracking) { + QGles2Texture *texD = QRHI_RES(QGles2Texture, b->u.simage.tex); + QRhiPassResourceTracker::TextureAccess access; + if (b->type == QRhiShaderResourceBinding::ImageLoad) + access = QRhiPassResourceTracker::TexStorageLoad; + else if (b->type == QRhiShaderResourceBinding::ImageStore) + access = QRhiPassResourceTracker::TexStorageStore; + else + access = QRhiPassResourceTracker::TexStorageLoadStore; + trackedRegisterTexture(&passResTracker, texD, access, + QRhiPassResourceTracker::toPassTrackerTextureStage(b->stage)); + } break; case QRhiShaderResourceBinding::BufferLoad: case QRhiShaderResourceBinding::BufferStore: case QRhiShaderResourceBinding::BufferLoadStore: - { - QGles2Buffer *bufD = QRHI_RES(QGles2Buffer, b->u.sbuf.buf); - QRhiPassResourceTracker::BufferAccess access; - if (b->type == QRhiShaderResourceBinding::BufferLoad) - access = QRhiPassResourceTracker::BufStorageLoad; - else if (b->type == QRhiShaderResourceBinding::BufferStore) - access = QRhiPassResourceTracker::BufStorageStore; - else - access = QRhiPassResourceTracker::BufStorageLoadStore; - trackedRegisterBuffer(&passResTracker, bufD, access, - QRhiPassResourceTracker::toPassTrackerBufferStage(b->stage)); - } + if (cbD->passNeedsResourceTracking) { + QGles2Buffer *bufD = QRHI_RES(QGles2Buffer, b->u.sbuf.buf); + QRhiPassResourceTracker::BufferAccess access; + if (b->type == QRhiShaderResourceBinding::BufferLoad) + access = QRhiPassResourceTracker::BufStorageLoad; + else if (b->type == QRhiShaderResourceBinding::BufferStore) + access = QRhiPassResourceTracker::BufStorageStore; + else + access = QRhiPassResourceTracker::BufStorageLoadStore; + trackedRegisterBuffer(&passResTracker, bufD, access, + QRhiPassResourceTracker::toPassTrackerBufferStage(b->stage)); + } break; default: break; @@ -1206,8 +1208,10 @@ void QRhiGles2::setVertexInput(QRhiCommandBuffer *cb, cmd.args.bindVertexBuffer.binding = startBinding + i; cbD->commands.append(cmd); - trackedRegisterBuffer(&passResTracker, bufD, QRhiPassResourceTracker::BufVertexInput, - QRhiPassResourceTracker::BufVertexInputStage); + if (cbD->passNeedsResourceTracking) { + trackedRegisterBuffer(&passResTracker, bufD, QRhiPassResourceTracker::BufVertexInput, + QRhiPassResourceTracker::BufVertexInputStage); + } } if (indexBuf) { @@ -1221,8 +1225,10 @@ void QRhiGles2::setVertexInput(QRhiCommandBuffer *cb, cmd.args.bindIndexBuffer.type = indexFormat == QRhiCommandBuffer::IndexUInt16 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT; cbD->commands.append(cmd); - trackedRegisterBuffer(&passResTracker, ibufD, QRhiPassResourceTracker::BufIndexRead, - QRhiPassResourceTracker::BufVertexInputStage); + if (cbD->passNeedsResourceTracking) { + trackedRegisterBuffer(&passResTracker, ibufD, QRhiPassResourceTracker::BufIndexRead, + QRhiPassResourceTracker::BufVertexInputStage); + } } } @@ -1416,10 +1422,8 @@ void QRhiGles2::endExternal(QRhiCommandBuffer *cb) enqueueBindFramebuffer(cbD->currentTarget, cbD); } -QRhi::FrameOpResult QRhiGles2::beginFrame(QRhiSwapChain *swapChain, QRhi::BeginFrameFlags flags) +QRhi::FrameOpResult QRhiGles2::beginFrame(QRhiSwapChain *swapChain, QRhi::BeginFrameFlags) { - Q_UNUSED(flags); - QGles2SwapChain *swapChainD = QRHI_RES(QGles2SwapChain, swapChain); if (!ensureContext(swapChainD->surface)) return contextLost ? QRhi::FrameOpDeviceLost : QRhi::FrameOpError; @@ -1465,9 +1469,8 @@ QRhi::FrameOpResult QRhiGles2::endFrame(QRhiSwapChain *swapChain, QRhi::EndFrame return QRhi::FrameOpSuccess; } -QRhi::FrameOpResult QRhiGles2::beginOffscreenFrame(QRhiCommandBuffer **cb, QRhi::BeginFrameFlags flags) +QRhi::FrameOpResult QRhiGles2::beginOffscreenFrame(QRhiCommandBuffer **cb, QRhi::BeginFrameFlags) { - Q_UNUSED(flags); if (!ensureContext()) return contextLost ? QRhi::FrameOpDeviceLost : QRhi::FrameOpError; @@ -2593,6 +2596,8 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb) break; case QGles2CommandBuffer::Command::BarriersForPass: { + if (!caps.compute) + break; GLbitfield barriers = 0; QRhiPassResourceTracker &tracker(cbD->passResTrackers[cmd.args.barriersForPass.trackerIndex]); // we only care about after-write, not any other accesses, and @@ -2612,7 +2617,7 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb) if (textureAccessIsWrite(accessBeforePass)) barriers |= GL_ALL_BARRIER_BITS; } - if (barriers && caps.compute) + if (barriers) f->glMemoryBarrier(barriers); } break; @@ -3127,12 +3132,12 @@ QGles2RenderTargetData *QRhiGles2::enqueueBindFramebuffer(QRhiRenderTarget *rt, const QRhiColorAttachment &colorAtt(*it); QGles2Texture *texD = QRHI_RES(QGles2Texture, colorAtt.texture()); QGles2Texture *resolveTexD = QRHI_RES(QGles2Texture, colorAtt.resolveTexture()); - if (texD) { + if (texD && cbD->passNeedsResourceTracking) { trackedRegisterTexture(&passResTracker, texD, QRhiPassResourceTracker::TexColorOutput, QRhiPassResourceTracker::TexColorOutputStage); } - if (resolveTexD) { + if (resolveTexD && cbD->passNeedsResourceTracking) { trackedRegisterTexture(&passResTracker, resolveTexD, QRhiPassResourceTracker::TexColorOutput, QRhiPassResourceTracker::TexColorOutputStage); @@ -3140,7 +3145,7 @@ QGles2RenderTargetData *QRhiGles2::enqueueBindFramebuffer(QRhiRenderTarget *rt, // renderbuffers cannot be written in shaders (no image store) so // they do not matter here } - if (rtTex->m_desc.depthTexture()) { + if (rtTex->m_desc.depthTexture() && cbD->passNeedsResourceTracking) { trackedRegisterTexture(&passResTracker, QRHI_RES(QGles2Texture, rtTex->m_desc.depthTexture()), QRhiPassResourceTracker::TexDepthOutput, QRhiPassResourceTracker::TexDepthOutputStage); @@ -3172,7 +3177,8 @@ void QRhiGles2::beginPass(QRhiCommandBuffer *cb, QRhiRenderTarget *rt, const QColor &colorClearValue, const QRhiDepthStencilClearValue &depthStencilClearValue, - QRhiResourceUpdateBatch *resourceUpdates) + QRhiResourceUpdateBatch *resourceUpdates, + QRhiCommandBuffer::BeginPassFlags flags) { QGles2CommandBuffer *cbD = QRHI_RES(QGles2CommandBuffer, cb); Q_ASSERT(cbD->recordingPass == QGles2CommandBuffer::NoPass); @@ -3203,6 +3209,7 @@ void QRhiGles2::beginPass(QRhiCommandBuffer *cb, cbD->commands.append(clearCmd); cbD->recordingPass = QGles2CommandBuffer::RenderPass; + cbD->passNeedsResourceTracking = !flags.testFlag(QRhiCommandBuffer::DoNotTrackResourcesForCompute); cbD->currentTarget = rt; cbD->resetCachedState(); @@ -3249,7 +3256,9 @@ void QRhiGles2::endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resource enqueueResourceUpdates(cb, resourceUpdates); } -void QRhiGles2::beginComputePass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) +void QRhiGles2::beginComputePass(QRhiCommandBuffer *cb, + QRhiResourceUpdateBatch *resourceUpdates, + QRhiCommandBuffer::BeginPassFlags) { QGles2CommandBuffer *cbD = QRHI_RES(QGles2CommandBuffer, cb); Q_ASSERT(cbD->recordingPass == QGles2CommandBuffer::NoPass); diff --git a/src/gui/rhi/qrhigles2_p_p.h b/src/gui/rhi/qrhigles2_p_p.h index c380f3bc08..95bf85f0b4 100644 --- a/src/gui/rhi/qrhigles2_p_p.h +++ b/src/gui/rhi/qrhigles2_p_p.h @@ -519,6 +519,7 @@ struct QGles2CommandBuffer : public QRhiCommandBuffer int currentPassResTrackerIndex; PassType recordingPass; + bool passNeedsResourceTracking; QRhiRenderTarget *currentTarget; QRhiGraphicsPipeline *currentGraphicsPipeline; QRhiComputePipeline *currentComputePipeline; @@ -611,6 +612,7 @@ struct QGles2CommandBuffer : public QRhiCommandBuffer } void resetState() { recordingPass = NoPass; + passNeedsResourceTracking = true; currentTarget = nullptr; resetCommands(); resetCachedState(); @@ -741,7 +743,8 @@ public: QRhiRenderTarget *rt, const QColor &colorClearValue, const QRhiDepthStencilClearValue &depthStencilClearValue, - QRhiResourceUpdateBatch *resourceUpdates) override; + QRhiResourceUpdateBatch *resourceUpdates, + QRhiCommandBuffer::BeginPassFlags flags) override; void endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override; void setGraphicsPipeline(QRhiCommandBuffer *cb, @@ -773,7 +776,9 @@ public: void debugMarkEnd(QRhiCommandBuffer *cb) override; void debugMarkMsg(QRhiCommandBuffer *cb, const QByteArray &msg) override; - void beginComputePass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override; + void beginComputePass(QRhiCommandBuffer *cb, + QRhiResourceUpdateBatch *resourceUpdates, + QRhiCommandBuffer::BeginPassFlags flags) override; void endComputePass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override; void setComputePipeline(QRhiCommandBuffer *cb, QRhiComputePipeline *ps) override; void dispatch(QRhiCommandBuffer *cb, int x, int y, int z) override; diff --git a/src/gui/rhi/qrhimetal.mm b/src/gui/rhi/qrhimetal.mm index a31d37c01a..4caaca4a3a 100644 --- a/src/gui/rhi/qrhimetal.mm +++ b/src/gui/rhi/qrhimetal.mm @@ -1898,7 +1898,8 @@ void QRhiMetal::beginPass(QRhiCommandBuffer *cb, QRhiRenderTarget *rt, const QColor &colorClearValue, const QRhiDepthStencilClearValue &depthStencilClearValue, - QRhiResourceUpdateBatch *resourceUpdates) + QRhiResourceUpdateBatch *resourceUpdates, + QRhiCommandBuffer::BeginPassFlags) { QMetalCommandBuffer *cbD = QRHI_RES(QMetalCommandBuffer, cb); Q_ASSERT(cbD->recordingPass == QMetalCommandBuffer::NoPass); @@ -2013,7 +2014,9 @@ void QRhiMetal::endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resource enqueueResourceUpdates(cb, resourceUpdates); } -void QRhiMetal::beginComputePass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) +void QRhiMetal::beginComputePass(QRhiCommandBuffer *cb, + QRhiResourceUpdateBatch *resourceUpdates, + QRhiCommandBuffer::BeginPassFlags) { QMetalCommandBuffer *cbD = QRHI_RES(QMetalCommandBuffer, cb); Q_ASSERT(cbD->recordingPass == QMetalCommandBuffer::NoPass); diff --git a/src/gui/rhi/qrhimetal_p_p.h b/src/gui/rhi/qrhimetal_p_p.h index 58d7dec116..a8c342da25 100644 --- a/src/gui/rhi/qrhimetal_p_p.h +++ b/src/gui/rhi/qrhimetal_p_p.h @@ -379,7 +379,8 @@ public: QRhiRenderTarget *rt, const QColor &colorClearValue, const QRhiDepthStencilClearValue &depthStencilClearValue, - QRhiResourceUpdateBatch *resourceUpdates) override; + QRhiResourceUpdateBatch *resourceUpdates, + QRhiCommandBuffer::BeginPassFlags flags) override; void endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override; void setGraphicsPipeline(QRhiCommandBuffer *cb, @@ -411,7 +412,9 @@ public: void debugMarkEnd(QRhiCommandBuffer *cb) override; void debugMarkMsg(QRhiCommandBuffer *cb, const QByteArray &msg) override; - void beginComputePass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override; + void beginComputePass(QRhiCommandBuffer *cb, + QRhiResourceUpdateBatch *resourceUpdates, + QRhiCommandBuffer::BeginPassFlags flags) override; void endComputePass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override; void setComputePipeline(QRhiCommandBuffer *cb, QRhiComputePipeline *ps) override; void dispatch(QRhiCommandBuffer *cb, int x, int y, int z) override; diff --git a/src/gui/rhi/qrhinull.cpp b/src/gui/rhi/qrhinull.cpp index 4c650e68a0..86beb243c6 100644 --- a/src/gui/rhi/qrhinull.cpp +++ b/src/gui/rhi/qrhinull.cpp @@ -522,11 +522,13 @@ void QRhiNull::beginPass(QRhiCommandBuffer *cb, QRhiRenderTarget *rt, const QColor &colorClearValue, const QRhiDepthStencilClearValue &depthStencilClearValue, - QRhiResourceUpdateBatch *resourceUpdates) + QRhiResourceUpdateBatch *resourceUpdates, + QRhiCommandBuffer::BeginPassFlags flags) { Q_UNUSED(rt); Q_UNUSED(colorClearValue); Q_UNUSED(depthStencilClearValue); + Q_UNUSED(flags); if (resourceUpdates) resourceUpdate(cb, resourceUpdates); } @@ -537,8 +539,11 @@ void QRhiNull::endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceU resourceUpdate(cb, resourceUpdates); } -void QRhiNull::beginComputePass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) +void QRhiNull::beginComputePass(QRhiCommandBuffer *cb, + QRhiResourceUpdateBatch *resourceUpdates, + QRhiCommandBuffer::BeginPassFlags flags) { + Q_UNUSED(flags); if (resourceUpdates) resourceUpdate(cb, resourceUpdates); } diff --git a/src/gui/rhi/qrhinull_p_p.h b/src/gui/rhi/qrhinull_p_p.h index 2921d0634e..567b672b3f 100644 --- a/src/gui/rhi/qrhinull_p_p.h +++ b/src/gui/rhi/qrhinull_p_p.h @@ -237,7 +237,8 @@ public: QRhiRenderTarget *rt, const QColor &colorClearValue, const QRhiDepthStencilClearValue &depthStencilClearValue, - QRhiResourceUpdateBatch *resourceUpdates) override; + QRhiResourceUpdateBatch *resourceUpdates, + QRhiCommandBuffer::BeginPassFlags flags) override; void endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override; void setGraphicsPipeline(QRhiCommandBuffer *cb, @@ -269,7 +270,9 @@ public: void debugMarkEnd(QRhiCommandBuffer *cb) override; void debugMarkMsg(QRhiCommandBuffer *cb, const QByteArray &msg) override; - void beginComputePass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override; + void beginComputePass(QRhiCommandBuffer *cb, + QRhiResourceUpdateBatch *resourceUpdates, + QRhiCommandBuffer::BeginPassFlags flags) override; void endComputePass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override; void setComputePipeline(QRhiCommandBuffer *cb, QRhiComputePipeline *ps) override; void dispatch(QRhiCommandBuffer *cb, int x, int y, int z) override; diff --git a/src/gui/rhi/qrhivulkan.cpp b/src/gui/rhi/qrhivulkan.cpp index c0162820b6..d6b1bc0670 100644 --- a/src/gui/rhi/qrhivulkan.cpp +++ b/src/gui/rhi/qrhivulkan.cpp @@ -1624,7 +1624,7 @@ void QRhiVulkan::releaseSwapChainResources(QRhiSwapChain *swapChain) // NB! surface and similar must remain intact } -QRhi::FrameOpResult QRhiVulkan::beginFrame(QRhiSwapChain *swapChain, QRhi::BeginFrameFlags flags) +QRhi::FrameOpResult QRhiVulkan::beginFrame(QRhiSwapChain *swapChain, QRhi::BeginFrameFlags) { QVkSwapChain *swapChainD = QRHI_RES(QVkSwapChain, swapChain); const int frameResIndex = swapChainD->bufferCount > 1 ? swapChainD->currentFrameSlot : 0; @@ -1724,7 +1724,6 @@ QRhi::FrameOpResult QRhiVulkan::beginFrame(QRhiSwapChain *swapChain, QRhi::Begin } swapChainD->cbWrapper.cb = frame.cmdBuf; - swapChainD->cbWrapper.useSecondaryCb = flags.testFlag(QRhi::ExternalContentsInPass); QVkSwapChain::ImageResources &image(swapChainD->imageRes[swapChainD->currentImageIndex]); swapChainD->rtWrapper.d.fb = image.fb; @@ -1971,7 +1970,7 @@ void QRhiVulkan::waitCommandCompletion(int frameSlot) } } -QRhi::FrameOpResult QRhiVulkan::beginOffscreenFrame(QRhiCommandBuffer **cb, QRhi::BeginFrameFlags flags) +QRhi::FrameOpResult QRhiVulkan::beginOffscreenFrame(QRhiCommandBuffer **cb, QRhi::BeginFrameFlags) { QRhi::FrameOpResult cbres = startPrimaryCommandBuffer(&ofr.cbWrapper.cb); if (cbres != QRhi::FrameOpSuccess) @@ -1990,8 +1989,6 @@ QRhi::FrameOpResult QRhiVulkan::beginOffscreenFrame(QRhiCommandBuffer **cb, QRhi if (swapchains.count() > 1) waitCommandCompletion(currentFrameSlot); - ofr.cbWrapper.useSecondaryCb = flags.testFlag(QRhi::ExternalContentsInPass); - prepareNewFrame(&ofr.cbWrapper); ofr.active = true; @@ -2209,7 +2206,8 @@ void QRhiVulkan::beginPass(QRhiCommandBuffer *cb, QRhiRenderTarget *rt, const QColor &colorClearValue, const QRhiDepthStencilClearValue &depthStencilClearValue, - QRhiResourceUpdateBatch *resourceUpdates) + QRhiResourceUpdateBatch *resourceUpdates, + QRhiCommandBuffer::BeginPassFlags flags) { QVkCommandBuffer *cbD = QRHI_RES(QVkCommandBuffer, cb); Q_ASSERT(cbD->recordingPass == QVkCommandBuffer::NoPass); @@ -2245,6 +2243,7 @@ void QRhiVulkan::beginPass(QRhiCommandBuffer *cb, } cbD->recordingPass = QVkCommandBuffer::RenderPass; + cbD->passUsesSecondaryCb = flags.testFlag(QRhiCommandBuffer::ExternalContent); cbD->currentTarget = rt; // No copy operations or image layout transitions allowed after this point @@ -2282,10 +2281,11 @@ void QRhiVulkan::beginPass(QRhiCommandBuffer *cb, cmd.cmd = QVkCommandBuffer::Command::BeginRenderPass; cmd.args.beginRenderPass.desc = rpBeginInfo; cmd.args.beginRenderPass.clearValueIndex = cbD->pools.clearValue.count(); + cmd.args.beginRenderPass.useSecondaryCb = cbD->passUsesSecondaryCb; cbD->pools.clearValue.append(cvs.constData(), cvs.count()); cbD->commands.append(cmd); - if (cbD->useSecondaryCb) + if (cbD->passUsesSecondaryCb) cbD->secondaryCbs.append(startSecondaryCommandBuffer(rtD)); } @@ -2294,7 +2294,7 @@ void QRhiVulkan::endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourc QVkCommandBuffer *cbD = QRHI_RES(QVkCommandBuffer, cb); Q_ASSERT(cbD->recordingPass == QVkCommandBuffer::RenderPass); - if (cbD->useSecondaryCb) { + if (cbD->passUsesSecondaryCb) { VkCommandBuffer secondaryCb = cbD->secondaryCbs.last(); cbD->secondaryCbs.removeLast(); endAndEnqueueSecondaryCommandBuffer(secondaryCb, cbD); @@ -2312,7 +2312,9 @@ void QRhiVulkan::endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourc enqueueResourceUpdates(cbD, resourceUpdates); } -void QRhiVulkan::beginComputePass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) +void QRhiVulkan::beginComputePass(QRhiCommandBuffer *cb, + QRhiResourceUpdateBatch *resourceUpdates, + QRhiCommandBuffer::BeginPassFlags flags) { QVkCommandBuffer *cbD = QRHI_RES(QVkCommandBuffer, cb); Q_ASSERT(cbD->recordingPass == QVkCommandBuffer::NoPass); @@ -2323,10 +2325,11 @@ void QRhiVulkan::beginComputePass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch enqueueTransitionPassResources(cbD); cbD->recordingPass = QVkCommandBuffer::ComputePass; + cbD->passUsesSecondaryCb = flags.testFlag(QRhiCommandBuffer::ExternalContent); cbD->computePassState.reset(); - if (cbD->useSecondaryCb) + if (cbD->passUsesSecondaryCb) cbD->secondaryCbs.append(startSecondaryCommandBuffer()); } @@ -2335,7 +2338,7 @@ void QRhiVulkan::endComputePass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch * QVkCommandBuffer *cbD = QRHI_RES(QVkCommandBuffer, cb); Q_ASSERT(cbD->recordingPass == QVkCommandBuffer::ComputePass); - if (cbD->useSecondaryCb) { + if (cbD->passUsesSecondaryCb) { VkCommandBuffer secondaryCb = cbD->secondaryCbs.last(); cbD->secondaryCbs.removeLast(); endAndEnqueueSecondaryCommandBuffer(secondaryCb, cbD); @@ -2356,7 +2359,7 @@ void QRhiVulkan::setComputePipeline(QRhiCommandBuffer *cb, QRhiComputePipeline * Q_ASSERT(cbD->recordingPass == QVkCommandBuffer::ComputePass); if (cbD->currentComputePipeline != ps || cbD->currentPipelineGeneration != psD->generation) { - if (cbD->useSecondaryCb) { + if (cbD->passUsesSecondaryCb) { df->vkCmdBindPipeline(cbD->secondaryCbs.last(), VK_PIPELINE_BIND_POINT_COMPUTE, psD->pipeline); } else { QVkCommandBuffer::Command cmd; @@ -2485,7 +2488,7 @@ void QRhiVulkan::dispatch(QRhiCommandBuffer *cb, int x, int y, int z) } } - if (cbD->useSecondaryCb) { + if (cbD->passUsesSecondaryCb) { VkCommandBuffer secondaryCb = cbD->secondaryCbs.last(); if (!imageBarriers.isEmpty()) { df->vkCmdPipelineBarrier(secondaryCb, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, @@ -3697,7 +3700,8 @@ void QRhiVulkan::recordPrimaryCommandBuffer(QVkCommandBuffer *cbD) case QVkCommandBuffer::Command::BeginRenderPass: cmd.args.beginRenderPass.desc.pClearValues = cbD->pools.clearValue.constData() + cmd.args.beginRenderPass.clearValueIndex; df->vkCmdBeginRenderPass(cbD->cb, &cmd.args.beginRenderPass.desc, - cbD->useSecondaryCb ? VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS : VK_SUBPASS_CONTENTS_INLINE); + cmd.args.beginRenderPass.useSecondaryCb ? VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS + : VK_SUBPASS_CONTENTS_INLINE); break; case QVkCommandBuffer::Command::EndRenderPass: df->vkCmdEndRenderPass(cbD->cb); @@ -4227,7 +4231,7 @@ void QRhiVulkan::setGraphicsPipeline(QRhiCommandBuffer *cb, QRhiGraphicsPipeline Q_ASSERT(cbD->recordingPass == QVkCommandBuffer::RenderPass); if (cbD->currentGraphicsPipeline != ps || cbD->currentPipelineGeneration != psD->generation) { - if (cbD->useSecondaryCb) { + if (cbD->passUsesSecondaryCb) { df->vkCmdBindPipeline(cbD->secondaryCbs.last(), VK_PIPELINE_BIND_POINT_GRAPHICS, psD->pipeline); } else { QVkCommandBuffer::Command cmd; @@ -4435,7 +4439,7 @@ void QRhiVulkan::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBin } } - if (cbD->useSecondaryCb) { + if (cbD->passUsesSecondaryCb) { df->vkCmdBindDescriptorSets(cbD->secondaryCbs.last(), gfxPsD ? VK_PIPELINE_BIND_POINT_GRAPHICS : VK_PIPELINE_BIND_POINT_COMPUTE, gfxPsD ? gfxPsD->layout : compPsD->layout, @@ -4509,7 +4513,7 @@ void QRhiVulkan::setVertexInput(QRhiCommandBuffer *cb, QRhiPassResourceTracker::BufVertexInputStage); } - if (cbD->useSecondaryCb) { + if (cbD->passUsesSecondaryCb) { df->vkCmdBindVertexBuffers(cbD->secondaryCbs.last(), uint32_t(startBinding), uint32_t(bufs.count()), bufs.constData(), ofs.constData()); } else { @@ -4545,7 +4549,7 @@ void QRhiVulkan::setVertexInput(QRhiCommandBuffer *cb, cbD->currentIndexOffset = indexOffset; cbD->currentIndexFormat = type; - if (cbD->useSecondaryCb) { + if (cbD->passUsesSecondaryCb) { df->vkCmdBindIndexBuffer(cbD->secondaryCbs.last(), vkindexbuf, indexOffset, type); } else { QVkCommandBuffer::Command cmd; @@ -4583,7 +4587,7 @@ void QRhiVulkan::setViewport(QRhiCommandBuffer *cb, const QRhiViewport &viewport vp->minDepth = viewport.minDepth(); vp->maxDepth = viewport.maxDepth(); - if (cbD->useSecondaryCb) { + if (cbD->passUsesSecondaryCb) { df->vkCmdSetViewport(cbD->secondaryCbs.last(), 0, 1, vp); } else { cmd.cmd = QVkCommandBuffer::Command::SetViewport; @@ -4596,7 +4600,7 @@ void QRhiVulkan::setViewport(QRhiCommandBuffer *cb, const QRhiViewport &viewport s->offset.y = int32_t(y); s->extent.width = uint32_t(w); s->extent.height = uint32_t(h); - if (cbD->useSecondaryCb) { + if (cbD->passUsesSecondaryCb) { df->vkCmdSetScissor(cbD->secondaryCbs.last(), 0, 1, s); } else { cmd.cmd = QVkCommandBuffer::Command::SetScissor; @@ -4624,7 +4628,7 @@ void QRhiVulkan::setScissor(QRhiCommandBuffer *cb, const QRhiScissor &scissor) s->extent.width = uint32_t(w); s->extent.height = uint32_t(h); - if (cbD->useSecondaryCb) { + if (cbD->passUsesSecondaryCb) { df->vkCmdSetScissor(cbD->secondaryCbs.last(), 0, 1, s); } else { cmd.cmd = QVkCommandBuffer::Command::SetScissor; @@ -4637,7 +4641,7 @@ void QRhiVulkan::setBlendConstants(QRhiCommandBuffer *cb, const QColor &c) QVkCommandBuffer *cbD = QRHI_RES(QVkCommandBuffer, cb); Q_ASSERT(cbD->recordingPass == QVkCommandBuffer::RenderPass); - if (cbD->useSecondaryCb) { + if (cbD->passUsesSecondaryCb) { float constants[] = { float(c.redF()), float(c.greenF()), float(c.blueF()), float(c.alphaF()) }; df->vkCmdSetBlendConstants(cbD->secondaryCbs.last(), constants); } else { @@ -4656,7 +4660,7 @@ void QRhiVulkan::setStencilRef(QRhiCommandBuffer *cb, quint32 refValue) QVkCommandBuffer *cbD = QRHI_RES(QVkCommandBuffer, cb); Q_ASSERT(cbD->recordingPass == QVkCommandBuffer::RenderPass); - if (cbD->useSecondaryCb) { + if (cbD->passUsesSecondaryCb) { df->vkCmdSetStencilReference(cbD->secondaryCbs.last(), VK_STENCIL_FRONT_AND_BACK, refValue); } else { QVkCommandBuffer::Command cmd; @@ -4672,7 +4676,7 @@ void QRhiVulkan::draw(QRhiCommandBuffer *cb, quint32 vertexCount, QVkCommandBuffer *cbD = QRHI_RES(QVkCommandBuffer, cb); Q_ASSERT(cbD->recordingPass == QVkCommandBuffer::RenderPass); - if (cbD->useSecondaryCb) { + if (cbD->passUsesSecondaryCb) { df->vkCmdDraw(cbD->secondaryCbs.last(), vertexCount, instanceCount, firstVertex, firstInstance); } else { QVkCommandBuffer::Command cmd; @@ -4691,7 +4695,7 @@ void QRhiVulkan::drawIndexed(QRhiCommandBuffer *cb, quint32 indexCount, QVkCommandBuffer *cbD = QRHI_RES(QVkCommandBuffer, cb); Q_ASSERT(cbD->recordingPass == QVkCommandBuffer::RenderPass); - if (cbD->useSecondaryCb) { + if (cbD->passUsesSecondaryCb) { df->vkCmdDrawIndexed(cbD->secondaryCbs.last(), indexCount, instanceCount, firstIndex, vertexOffset, firstInstance); } else { @@ -4716,7 +4720,7 @@ void QRhiVulkan::debugMarkBegin(QRhiCommandBuffer *cb, const QByteArray &name) marker.sType = VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT; QVkCommandBuffer *cbD = QRHI_RES(QVkCommandBuffer, cb); - if (cbD->recordingPass != QVkCommandBuffer::NoPass && cbD->useSecondaryCb) { + if (cbD->recordingPass != QVkCommandBuffer::NoPass && cbD->passUsesSecondaryCb) { marker.pMarkerName = name.constData(); vkCmdDebugMarkerBegin(cbD->secondaryCbs.last(), &marker); } else { @@ -4735,7 +4739,7 @@ void QRhiVulkan::debugMarkEnd(QRhiCommandBuffer *cb) return; QVkCommandBuffer *cbD = QRHI_RES(QVkCommandBuffer, cb); - if (cbD->recordingPass != QVkCommandBuffer::NoPass && cbD->useSecondaryCb) { + if (cbD->recordingPass != QVkCommandBuffer::NoPass && cbD->passUsesSecondaryCb) { vkCmdDebugMarkerEnd(cbD->secondaryCbs.last()); } else { QVkCommandBuffer::Command cmd; @@ -4754,7 +4758,7 @@ void QRhiVulkan::debugMarkMsg(QRhiCommandBuffer *cb, const QByteArray &msg) marker.sType = VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT; QVkCommandBuffer *cbD = QRHI_RES(QVkCommandBuffer, cb); - if (cbD->recordingPass != QVkCommandBuffer::NoPass && cbD->useSecondaryCb) { + if (cbD->recordingPass != QVkCommandBuffer::NoPass && cbD->passUsesSecondaryCb) { marker.pMarkerName = msg.constData(); vkCmdDebugMarkerInsert(cbD->secondaryCbs.last(), &marker); } else { @@ -4812,9 +4816,9 @@ void QRhiVulkan::beginExternal(QRhiCommandBuffer *cb) if (cbD->inExternal) return; - if (!cbD->useSecondaryCb) { + if (!cbD->passUsesSecondaryCb) { qWarning("beginExternal() within a pass is only supported with secondary command buffers. " - "This can be enabled by passing QRhi::ExternalContentsInPass to beginFrame()."); + "This can be enabled by passing QRhiCommandBuffer::ExternalContent to beginPass()."); return; } @@ -6615,10 +6619,14 @@ const QRhiNativeHandles *QVkCommandBuffer::nativeHandles() // secondary command buffer (typically the one started by beginExternal(), // in case we are between beginExternal - endExternal inside a pass). - if (useSecondaryCb && !secondaryCbs.isEmpty()) - nativeHandlesStruct.commandBuffer = secondaryCbs.last(); - else + if (recordingPass == QVkCommandBuffer::NoPass) { nativeHandlesStruct.commandBuffer = cb; + } else { + if (passUsesSecondaryCb && !secondaryCbs.isEmpty()) + nativeHandlesStruct.commandBuffer = secondaryCbs.last(); + else + nativeHandlesStruct.commandBuffer = cb; + } return &nativeHandlesStruct; } diff --git a/src/gui/rhi/qrhivulkan_p_p.h b/src/gui/rhi/qrhivulkan_p_p.h index c590039bc1..a352f3c2f2 100644 --- a/src/gui/rhi/qrhivulkan_p_p.h +++ b/src/gui/rhi/qrhivulkan_p_p.h @@ -329,7 +329,6 @@ struct QVkCommandBuffer : public QRhiCommandBuffer const QRhiNativeHandles *nativeHandles(); VkCommandBuffer cb = VK_NULL_HANDLE; // primary - bool useSecondaryCb = false; QRhiVulkanCommandBufferNativeHandles nativeHandlesStruct; enum PassType { @@ -340,6 +339,7 @@ struct QVkCommandBuffer : public QRhiCommandBuffer void resetState() { recordingPass = NoPass; + passUsesSecondaryCb = false; currentTarget = nullptr; secondaryCbs.clear(); @@ -365,6 +365,7 @@ struct QVkCommandBuffer : public QRhiCommandBuffer } PassType recordingPass; + bool passUsesSecondaryCb; QRhiRenderTarget *currentTarget; QRhiGraphicsPipeline *currentGraphicsPipeline; QRhiComputePipeline *currentComputePipeline; @@ -468,6 +469,7 @@ struct QVkCommandBuffer : public QRhiCommandBuffer struct { VkRenderPassBeginInfo desc; int clearValueIndex; + bool useSecondaryCb; } beginRenderPass; struct { } endRenderPass; @@ -694,7 +696,8 @@ public: QRhiRenderTarget *rt, const QColor &colorClearValue, const QRhiDepthStencilClearValue &depthStencilClearValue, - QRhiResourceUpdateBatch *resourceUpdates) override; + QRhiResourceUpdateBatch *resourceUpdates, + QRhiCommandBuffer::BeginPassFlags flags) override; void endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override; void setGraphicsPipeline(QRhiCommandBuffer *cb, @@ -726,7 +729,9 @@ public: void debugMarkEnd(QRhiCommandBuffer *cb) override; void debugMarkMsg(QRhiCommandBuffer *cb, const QByteArray &msg) override; - void beginComputePass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override; + void beginComputePass(QRhiCommandBuffer *cb, + QRhiResourceUpdateBatch *resourceUpdates, + QRhiCommandBuffer::BeginPassFlags flags) override; void endComputePass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override; void setComputePipeline(QRhiCommandBuffer *cb, QRhiComputePipeline *ps) override; void dispatch(QRhiCommandBuffer *cb, int x, int y, int z) override; diff --git a/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp b/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp index b6351eef45..477b98cc4e 100644 --- a/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp +++ b/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp @@ -2751,8 +2751,8 @@ void tst_QRhi::finishWithinSwapchainFrame() QScopedPointer vbuf(rhi->newBuffer(QRhiBuffer::Immutable, QRhiBuffer::VertexBuffer, sizeof(vertices))); QVERIFY(vbuf->create()); - // exercise begin/endExternal() just a little bit, hence ExternalContentsInPass - QVERIFY(rhi->beginFrame(swapChain.data(), QRhi::ExternalContentsInPass) == QRhi::FrameOpSuccess); + // exercise begin/endExternal() just a little bit, note ExternalContent for beginPass() + QVERIFY(rhi->beginFrame(swapChain.data()) == QRhi::FrameOpSuccess); QRhiCommandBuffer *cb = swapChain->currentFrameCommandBuffer(); QRhiRenderTarget *rt = swapChain->currentFrameRenderTarget(); const QSize outputSize = swapChain->currentPixelSize(); @@ -2763,7 +2763,7 @@ void tst_QRhi::finishWithinSwapchainFrame() QRhiResourceUpdateBatch *updates = rhi->nextResourceUpdateBatch(); updates->uploadStaticBuffer(vbuf.data(), vertices); - cb->beginPass(rt, Qt::blue, { 1.0f, 0 }, updates); + cb->beginPass(rt, Qt::blue, { 1.0f, 0 }, updates, QRhiCommandBuffer::ExternalContent); // just have some commands, do not bother with draw calls cb->setGraphicsPipeline(pipeline.data());