rhi: Make per-frame flags per-pass where appropriate
ExternalContentsInPass becomes a per-pass flag now. Why is this beneficial? Because while Qt Quick has no choice for its render pass, not being able to guess if the application wants to do some native rendering in there, Quick 3D's render passes, all the ones that are under Quick3D's control, do not have native rendering from the application in them, and so using secondary command buffers with Vulkan is not necessary. Introduce something similar for compute and OpenGL. By knowing that none of the resources used in a pass are used with a compute pass (e.g. because we know that there are no compute passes at all) a small amount of time can be saved by skipping tracking buffers and textures because the only purpose of said tracking is to generate barriers that are relevant only to compute. Change-Id: I0eceb4774d87803c73a39db527f5707a9f4d75c1 Reviewed-by: Andy Nichols <andy.nichols@qt.io>bb10
parent
3080194ae4
commit
d92b0e18c1
|
|
@ -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:
|
||||
|
||||
|
|
|
|||
|
|
@ -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<void()> 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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -2751,8 +2751,8 @@ void tst_QRhi::finishWithinSwapchainFrame()
|
|||
QScopedPointer<QRhiBuffer> 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());
|
||||
|
|
|
|||
Loading…
Reference in New Issue