rhi: vulkan: metal: Ensure ms color data is written out on PreserveColor
Fixes: QTBUG-123211 Pick-to: 6.7 6.6 Change-Id: Id037f8c5a69c2b0ec18d92fe8bb5a34a0a2b0ea0 Reviewed-by: Andy Nichols <andy.nichols@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
parent
bc61d6fcfa
commit
1b374fc4c1
@ -2545,9 +2545,10 @@ QRhiColorAttachment::QRhiColorAttachment(QRhiRenderBuffer *renderBuffer)
|
|||||||
\note when multisample resolving is enabled, the multisample data may not be
|
\note when multisample resolving is enabled, the multisample data may not be
|
||||||
written out at all. This means that the multisample texture in a color
|
written out at all. This means that the multisample texture in a color
|
||||||
attachment must not be used afterwards with shaders for sampling (or other
|
attachment must not be used afterwards with shaders for sampling (or other
|
||||||
puroses) whenever a resolve texture is set, since the multisample color
|
purposes) whenever a resolve texture is set, since the multisample color
|
||||||
buffer is merely an intermediate storage then that gets no data written back
|
buffer is merely an intermediate storage then that gets no data written back
|
||||||
on some GPU architectures at all.
|
on some GPU architectures at all. See
|
||||||
|
\l{QRhiTextureRenderTarget::Flag}{PreserveColorContents} for more details.
|
||||||
|
|
||||||
\note When using setDepthTexture(), not setDepthStencilBuffer(), and the
|
\note When using setDepthTexture(), not setDepthStencilBuffer(), and the
|
||||||
depth (stencil) data is not of interest afterwards, set the
|
depth (stencil) data is not of interest afterwards, set the
|
||||||
@ -5063,7 +5064,19 @@ QRhiResource::Type QRhiSwapChainRenderTarget::resourceType() const
|
|||||||
\value PreserveColorContents Indicates that the contents of the color
|
\value PreserveColorContents Indicates that the contents of the color
|
||||||
attachments is to be loaded when starting a render pass, instead of
|
attachments is to be loaded when starting a render pass, instead of
|
||||||
clearing. This is potentially more expensive, especially on mobile (tiled)
|
clearing. This is potentially more expensive, especially on mobile (tiled)
|
||||||
GPUs, but allows preserving the existing contents between passes.
|
GPUs, but allows preserving the existing contents between passes. When doing
|
||||||
|
multisample rendering with a resolve texture set, setting this flag also
|
||||||
|
requests the multisample color data to be stored (written out) to the
|
||||||
|
multisample texture or render buffer. (for non-multisample rendering the
|
||||||
|
color data is always stored, but for MSAA storing the multisample data
|
||||||
|
decreases efficiency for certain GPU architectures, hence defaulting to not
|
||||||
|
writing it out) Note however that this is non-portable: in some cases there
|
||||||
|
is no intermediate multisample texture on the graphics API level, e.g. when
|
||||||
|
using OpenGL ES's \c{GL_EXT_multisampled_render_to_texture} as it is all
|
||||||
|
implicit, handled by the OpenGL ES implementation. In that case,
|
||||||
|
PreserveColorContents will likely have no effect. Therefore, avoid relying
|
||||||
|
on this flag when using multisample rendering and the color attachment is
|
||||||
|
using a multisample QRhiTexture (not QRhiRenderBuffer).
|
||||||
|
|
||||||
\value PreserveDepthStencilContents Indicates that the contents of the
|
\value PreserveDepthStencilContents Indicates that the contents of the
|
||||||
depth texture is to be loaded when starting a render pass, instead
|
depth texture is to be loaded when starting a render pass, instead
|
||||||
|
@ -365,6 +365,8 @@ struct QMetalRenderTargetData
|
|||||||
id<MTLTexture> dsTex = nil;
|
id<MTLTexture> dsTex = nil;
|
||||||
bool hasStencil = false;
|
bool hasStencil = false;
|
||||||
bool depthNeedsStore = false;
|
bool depthNeedsStore = false;
|
||||||
|
bool preserveColor = false;
|
||||||
|
bool preserveDs = false;
|
||||||
} fb;
|
} fb;
|
||||||
|
|
||||||
QRhiRenderTargetAttachmentTracker::ResIdList currentResIdList;
|
QRhiRenderTargetAttachmentTracker::ResIdList currentResIdList;
|
||||||
@ -2952,11 +2954,11 @@ void QRhiMetal::beginPass(QRhiCommandBuffer *cb,
|
|||||||
if (!QRhiRenderTargetAttachmentTracker::isUpToDate<QMetalTexture, QMetalRenderBuffer>(rtTex->description(), rtD->currentResIdList))
|
if (!QRhiRenderTargetAttachmentTracker::isUpToDate<QMetalTexture, QMetalRenderBuffer>(rtTex->description(), rtD->currentResIdList))
|
||||||
rtTex->create();
|
rtTex->create();
|
||||||
cbD->d->currentPassRpDesc = d->createDefaultRenderPass(rtD->dsAttCount, colorClearValue, depthStencilClearValue, rtD->colorAttCount);
|
cbD->d->currentPassRpDesc = d->createDefaultRenderPass(rtD->dsAttCount, colorClearValue, depthStencilClearValue, rtD->colorAttCount);
|
||||||
if (rtTex->m_flags.testFlag(QRhiTextureRenderTarget::PreserveColorContents)) {
|
if (rtD->fb.preserveColor) {
|
||||||
for (uint i = 0; i < uint(rtD->colorAttCount); ++i)
|
for (uint i = 0; i < uint(rtD->colorAttCount); ++i)
|
||||||
cbD->d->currentPassRpDesc.colorAttachments[i].loadAction = MTLLoadActionLoad;
|
cbD->d->currentPassRpDesc.colorAttachments[i].loadAction = MTLLoadActionLoad;
|
||||||
}
|
}
|
||||||
if (rtD->dsAttCount && rtTex->m_flags.testFlag(QRhiTextureRenderTarget::PreserveDepthStencilContents)) {
|
if (rtD->dsAttCount && rtD->fb.preserveDs) {
|
||||||
cbD->d->currentPassRpDesc.depthAttachment.loadAction = MTLLoadActionLoad;
|
cbD->d->currentPassRpDesc.depthAttachment.loadAction = MTLLoadActionLoad;
|
||||||
cbD->d->currentPassRpDesc.stencilAttachment.loadAction = MTLLoadActionLoad;
|
cbD->d->currentPassRpDesc.stencilAttachment.loadAction = MTLLoadActionLoad;
|
||||||
}
|
}
|
||||||
@ -2990,7 +2992,8 @@ void QRhiMetal::beginPass(QRhiCommandBuffer *cb,
|
|||||||
cbD->d->currentPassRpDesc.colorAttachments[i].depthPlane = NSUInteger(rtD->fb.colorAtt[i].slice);
|
cbD->d->currentPassRpDesc.colorAttachments[i].depthPlane = NSUInteger(rtD->fb.colorAtt[i].slice);
|
||||||
cbD->d->currentPassRpDesc.colorAttachments[i].level = NSUInteger(rtD->fb.colorAtt[i].level);
|
cbD->d->currentPassRpDesc.colorAttachments[i].level = NSUInteger(rtD->fb.colorAtt[i].level);
|
||||||
if (rtD->fb.colorAtt[i].resolveTex) {
|
if (rtD->fb.colorAtt[i].resolveTex) {
|
||||||
cbD->d->currentPassRpDesc.colorAttachments[i].storeAction = MTLStoreActionMultisampleResolve;
|
cbD->d->currentPassRpDesc.colorAttachments[i].storeAction = rtD->fb.preserveColor ? MTLStoreActionStoreAndMultisampleResolve
|
||||||
|
: MTLStoreActionMultisampleResolve;
|
||||||
cbD->d->currentPassRpDesc.colorAttachments[i].resolveTexture = rtD->fb.colorAtt[i].resolveTex;
|
cbD->d->currentPassRpDesc.colorAttachments[i].resolveTexture = rtD->fb.colorAtt[i].resolveTex;
|
||||||
cbD->d->currentPassRpDesc.colorAttachments[i].resolveSlice = NSUInteger(rtD->fb.colorAtt[i].resolveLayer);
|
cbD->d->currentPassRpDesc.colorAttachments[i].resolveSlice = NSUInteger(rtD->fb.colorAtt[i].resolveLayer);
|
||||||
cbD->d->currentPassRpDesc.colorAttachments[i].resolveLevel = NSUInteger(rtD->fb.colorAtt[i].resolveLevel);
|
cbD->d->currentPassRpDesc.colorAttachments[i].resolveLevel = NSUInteger(rtD->fb.colorAtt[i].resolveLevel);
|
||||||
@ -4227,6 +4230,7 @@ bool QMetalTextureRenderTarget::create()
|
|||||||
d->fb.dsTex = depthTexD->d->tex;
|
d->fb.dsTex = depthTexD->d->tex;
|
||||||
d->fb.hasStencil = rhiD->isStencilSupportingFormat(depthTexD->format());
|
d->fb.hasStencil = rhiD->isStencilSupportingFormat(depthTexD->format());
|
||||||
d->fb.depthNeedsStore = !m_flags.testFlag(DoNotStoreDepthStencilContents);
|
d->fb.depthNeedsStore = !m_flags.testFlag(DoNotStoreDepthStencilContents);
|
||||||
|
d->fb.preserveDs = m_flags.testFlag(QRhiTextureRenderTarget::PreserveDepthStencilContents);
|
||||||
if (d->colorAttCount == 0) {
|
if (d->colorAttCount == 0) {
|
||||||
d->pixelSize = depthTexD->pixelSize();
|
d->pixelSize = depthTexD->pixelSize();
|
||||||
d->sampleCount = depthTexD->samples;
|
d->sampleCount = depthTexD->samples;
|
||||||
@ -4236,6 +4240,7 @@ bool QMetalTextureRenderTarget::create()
|
|||||||
d->fb.dsTex = depthRbD->d->tex;
|
d->fb.dsTex = depthRbD->d->tex;
|
||||||
d->fb.hasStencil = true;
|
d->fb.hasStencil = true;
|
||||||
d->fb.depthNeedsStore = false;
|
d->fb.depthNeedsStore = false;
|
||||||
|
d->fb.preserveDs = false;
|
||||||
if (d->colorAttCount == 0) {
|
if (d->colorAttCount == 0) {
|
||||||
d->pixelSize = depthRbD->pixelSize();
|
d->pixelSize = depthRbD->pixelSize();
|
||||||
d->sampleCount = depthRbD->samples;
|
d->sampleCount = depthRbD->samples;
|
||||||
@ -4246,6 +4251,9 @@ bool QMetalTextureRenderTarget::create()
|
|||||||
d->dsAttCount = 0;
|
d->dsAttCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (d->colorAttCount > 0)
|
||||||
|
d->fb.preserveColor = m_flags.testFlag(QRhiTextureRenderTarget::PreserveColorContents);
|
||||||
|
|
||||||
QRhiRenderTargetAttachmentTracker::updateResIdList<QMetalTexture, QMetalRenderBuffer>(m_desc, &d->currentResIdList);
|
QRhiRenderTargetAttachmentTracker::updateResIdList<QMetalTexture, QMetalRenderBuffer>(m_desc, &d->currentResIdList);
|
||||||
|
|
||||||
rhiD->registerResource(this, false);
|
rhiD->registerResource(this, false);
|
||||||
|
@ -1457,7 +1457,7 @@ bool QRhiVulkan::createOffscreenRenderPass(QVkRenderPassDescriptor *rpD,
|
|||||||
attDesc.format = vkformat;
|
attDesc.format = vkformat;
|
||||||
attDesc.samples = samples;
|
attDesc.samples = samples;
|
||||||
attDesc.loadOp = preserveColor ? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_CLEAR;
|
attDesc.loadOp = preserveColor ? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||||
attDesc.storeOp = it->resolveTexture() ? VK_ATTACHMENT_STORE_OP_DONT_CARE : VK_ATTACHMENT_STORE_OP_STORE;
|
attDesc.storeOp = (it->resolveTexture() && !preserveColor) ? VK_ATTACHMENT_STORE_OP_DONT_CARE : VK_ATTACHMENT_STORE_OP_STORE;
|
||||||
attDesc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
attDesc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||||
attDesc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
attDesc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||||
// this has to interact correctly with activateTextureRenderTarget(), hence leaving in COLOR_ATT
|
// this has to interact correctly with activateTextureRenderTarget(), hence leaving in COLOR_ATT
|
||||||
|
Loading…
x
Reference in New Issue
Block a user