rhi: vulkan: Fix multisample resolve with multiview
Task-number: QTBUG-114790 Change-Id: I3afccc3f7ae2d05aa9aa0e0943aeadc080016f0e Reviewed-by: Andy Nichols <andy.nichols@qt.io>bb10
parent
003c29511d
commit
2f619c2ddf
|
|
@ -2284,16 +2284,40 @@ QRhiColorAttachment::QRhiColorAttachment(QRhiRenderBuffer *renderBuffer)
|
||||||
\nullptr if there is none.
|
\nullptr if there is none.
|
||||||
|
|
||||||
Setting a non-null resolve texture is applicable when the attachment
|
Setting a non-null resolve texture is applicable when the attachment
|
||||||
references a multisample, color renderbuffer. (i.e., renderBuffer() is set)
|
references a multisample texture or renderbuffer. The QRhiTexture in the
|
||||||
The QRhiTexture in the resolveTexture() is then a regular, 2D,
|
resolveTexture() is then a non-multisample 2D texture (or texture array)
|
||||||
non-multisample texture with the same size (but a sample count of 1). The
|
with the same size (but a sample count of 1). The multisample content is
|
||||||
multisample content is automatically resolved into this texture at the end
|
automatically resolved into this texture at the end of each render pass.
|
||||||
of each render pass.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\fn void QRhiColorAttachment::setResolveTexture(QRhiTexture *tex)
|
\fn void QRhiColorAttachment::setResolveTexture(QRhiTexture *tex)
|
||||||
|
|
||||||
Sets the resolve texture \a tex.
|
Sets the resolve texture \a tex.
|
||||||
|
|
||||||
|
\a tex is expected to be a 2D texture or a 2D texture array. In either
|
||||||
|
case, resolving targets a single mip level of a single layer (array
|
||||||
|
element) of \a tex. The mip level and array layer are specified by
|
||||||
|
resolveLevel() and resolveLayer().
|
||||||
|
|
||||||
|
An exception is \l{setMultiViewCount()}{multiview}: when the color
|
||||||
|
attachment is associated with a texture array and multiview is enabled, the
|
||||||
|
resolve texture must also be a texture array with sufficient elements for
|
||||||
|
all views. In this case all elements that correspond to views are resolved
|
||||||
|
automatically; the behavior is similar to the following pseudo-code:
|
||||||
|
\badcode
|
||||||
|
for (i = 0; i < multiViewCount(); ++i)
|
||||||
|
resolve texture's layer() + i into resolveTexture's resolveLayer() + i
|
||||||
|
\endcode
|
||||||
|
|
||||||
|
Setting a non-multisample texture to resolve a multisample texture or
|
||||||
|
renderbuffer automatically at the end of the render pass is often
|
||||||
|
preferable to working with multisample textures (and not setting a resolve
|
||||||
|
texture), because it avoids the need for writing dedicated fragment shaders
|
||||||
|
that work exclusively with multisample textures (\c sampler2DMS, \c
|
||||||
|
texelFetch, etc.), and rather allows using the same shader as one would if
|
||||||
|
the attachment's texture was not multisampled to begin with. This comes at
|
||||||
|
the expense of an additional resource (the non-multisample \a tex).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
|
||||||
|
|
@ -6723,6 +6723,7 @@ bool QVkTextureRenderTarget::create()
|
||||||
|
|
||||||
QRHI_RES_RHI(QRhiVulkan);
|
QRHI_RES_RHI(QRhiVulkan);
|
||||||
QVarLengthArray<VkImageView, 8> views;
|
QVarLengthArray<VkImageView, 8> views;
|
||||||
|
uint32_t multiViewCount = 0;
|
||||||
|
|
||||||
d.colorAttCount = 0;
|
d.colorAttCount = 0;
|
||||||
int attIndex = 0;
|
int attIndex = 0;
|
||||||
|
|
@ -6735,6 +6736,8 @@ bool QVkTextureRenderTarget::create()
|
||||||
Q_ASSERT(texD->flags().testFlag(QRhiTexture::RenderTarget));
|
Q_ASSERT(texD->flags().testFlag(QRhiTexture::RenderTarget));
|
||||||
const bool is1D = texD->flags().testFlag(QRhiTexture::OneDimensional);
|
const bool is1D = texD->flags().testFlag(QRhiTexture::OneDimensional);
|
||||||
const bool isMultiView = it->multiViewCount() >= 2;
|
const bool isMultiView = it->multiViewCount() >= 2;
|
||||||
|
if (isMultiView && multiViewCount == 0)
|
||||||
|
multiViewCount = uint32_t(it->multiViewCount());
|
||||||
VkImageViewCreateInfo viewInfo = {};
|
VkImageViewCreateInfo viewInfo = {};
|
||||||
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||||
viewInfo.image = texD->image;
|
viewInfo.image = texD->image;
|
||||||
|
|
@ -6795,6 +6798,7 @@ bool QVkTextureRenderTarget::create()
|
||||||
|
|
||||||
d.resolveAttCount = 0;
|
d.resolveAttCount = 0;
|
||||||
attIndex = 0;
|
attIndex = 0;
|
||||||
|
Q_ASSERT(multiViewCount == 0 || multiViewCount >= 2);
|
||||||
for (auto it = m_desc.cbeginColorAttachments(), itEnd = m_desc.cendColorAttachments(); it != itEnd; ++it, ++attIndex) {
|
for (auto it = m_desc.cbeginColorAttachments(), itEnd = m_desc.cendColorAttachments(); it != itEnd; ++it, ++attIndex) {
|
||||||
if (it->resolveTexture()) {
|
if (it->resolveTexture()) {
|
||||||
QVkTexture *resTexD = QRHI_RES(QVkTexture, it->resolveTexture());
|
QVkTexture *resTexD = QRHI_RES(QVkTexture, it->resolveTexture());
|
||||||
|
|
@ -6804,7 +6808,8 @@ bool QVkTextureRenderTarget::create()
|
||||||
VkImageViewCreateInfo viewInfo = {};
|
VkImageViewCreateInfo viewInfo = {};
|
||||||
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||||
viewInfo.image = resTexD->image;
|
viewInfo.image = resTexD->image;
|
||||||
viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
viewInfo.viewType = multiViewCount ? VK_IMAGE_VIEW_TYPE_2D_ARRAY
|
||||||
|
: VK_IMAGE_VIEW_TYPE_2D;
|
||||||
viewInfo.format = resTexD->vkformat;
|
viewInfo.format = resTexD->vkformat;
|
||||||
viewInfo.components.r = VK_COMPONENT_SWIZZLE_R;
|
viewInfo.components.r = VK_COMPONENT_SWIZZLE_R;
|
||||||
viewInfo.components.g = VK_COMPONENT_SWIZZLE_G;
|
viewInfo.components.g = VK_COMPONENT_SWIZZLE_G;
|
||||||
|
|
@ -6814,7 +6819,7 @@ bool QVkTextureRenderTarget::create()
|
||||||
viewInfo.subresourceRange.baseMipLevel = uint32_t(it->resolveLevel());
|
viewInfo.subresourceRange.baseMipLevel = uint32_t(it->resolveLevel());
|
||||||
viewInfo.subresourceRange.levelCount = 1;
|
viewInfo.subresourceRange.levelCount = 1;
|
||||||
viewInfo.subresourceRange.baseArrayLayer = uint32_t(it->resolveLayer());
|
viewInfo.subresourceRange.baseArrayLayer = uint32_t(it->resolveLayer());
|
||||||
viewInfo.subresourceRange.layerCount = 1;
|
viewInfo.subresourceRange.layerCount = qMax(1u, multiViewCount);
|
||||||
VkResult err = rhiD->df->vkCreateImageView(rhiD->dev, &viewInfo, nullptr, &resrtv[attIndex]);
|
VkResult err = rhiD->df->vkCreateImageView(rhiD->dev, &viewInfo, nullptr, &resrtv[attIndex]);
|
||||||
if (err != VK_SUCCESS) {
|
if (err != VK_SUCCESS) {
|
||||||
qWarning("Failed to create render target resolve image view: %d", err);
|
qWarning("Failed to create render target resolve image view: %d", err);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue