summaryrefslogtreecommitdiffstats
path: root/src/gui/rhi/qrhivulkan.cpp
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2023-06-20 13:18:25 +0200
committerLaszlo Agocs <laszlo.agocs@qt.io>2023-06-22 15:20:26 +0200
commit1d9bf6ea38f12f55acc00cfd1072b1ef040a4cc4 (patch)
tree357c796c55fbc249a5de57c748918937fffd353a /src/gui/rhi/qrhivulkan.cpp
parentf9d90c6fbab1d4f66dcc3fbc06f7f157693d04d1 (diff)
rhi: vulkan: Implement multiview support
Fixes: QTBUG-114771 Change-Id: I8408b84c5ce01df94d68167d557393af919864d3 Reviewed-by: Andy Nichols <andy.nichols@qt.io>
Diffstat (limited to 'src/gui/rhi/qrhivulkan.cpp')
-rw-r--r--src/gui/rhi/qrhivulkan.cpp50
1 files changed, 45 insertions, 5 deletions
diff --git a/src/gui/rhi/qrhivulkan.cpp b/src/gui/rhi/qrhivulkan.cpp
index ae0e705106..484f304858 100644
--- a/src/gui/rhi/qrhivulkan.cpp
+++ b/src/gui/rhi/qrhivulkan.cpp
@@ -754,6 +754,10 @@ bool QRhiVulkan::create(QRhi::Flags flags)
caps.nonFillPolygonMode = physDevFeatures.fillModeNonSolid;
+#ifdef VK_VERSION_1_2
+ caps.multiView = caps.apiVersion >= QVersionNumber(1, 1) && physDevFeatures11.multiview;
+#endif
+
if (!importedAllocator) {
VmaVulkanFunctions funcs = {};
funcs.vkGetInstanceProcAddr = wrap_vkGetInstanceProcAddr;
@@ -1360,6 +1364,7 @@ bool QRhiVulkan::createOffscreenRenderPass(QVkRenderPassDescriptor *rpD,
{
// attachment list layout is color (0-8), ds (0-1), resolve (0-8)
+ int multiViewCount = 0;
for (auto it = firstColorAttachment; it != lastColorAttachment; ++it) {
QVkTexture *texD = QRHI_RES(QVkTexture, it->texture());
QVkRenderBuffer *rbD = QRHI_RES(QVkRenderBuffer, it->renderBuffer());
@@ -1381,7 +1386,17 @@ bool QRhiVulkan::createOffscreenRenderPass(QVkRenderPassDescriptor *rpD,
const VkAttachmentReference ref = { uint32_t(rpD->attDescs.size() - 1), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL };
rpD->colorRefs.append(ref);
+
+ if (it->multiViewCount() >= 2) {
+ if (multiViewCount > 0 && multiViewCount != it->multiViewCount())
+ qWarning("Inconsistent multiViewCount in color attachment set");
+ else
+ multiViewCount = it->multiViewCount();
+ } else if (multiViewCount > 0) {
+ qWarning("Mixing non-multiview color attachments within a multiview render pass");
+ }
}
+ Q_ASSERT(multiViewCount == 0 || multiViewCount >= 2);
rpD->hasDepthStencil = depthStencilBuffer || depthTexture;
if (rpD->hasDepthStencil) {
@@ -1451,6 +1466,29 @@ bool QRhiVulkan::createOffscreenRenderPass(QVkRenderPassDescriptor *rpD,
VkSubpassDescription subpassDesc;
fillRenderPassCreateInfo(&rpInfo, &subpassDesc, rpD);
+#ifdef VK_VERSION_1_1
+ VkRenderPassMultiviewCreateInfo multiViewInfo = {};
+ uint32_t allViewsMask = 0;
+ for (uint32_t i = 0; i < uint32_t(multiViewCount); ++i)
+ allViewsMask |= (1 << i);
+ uint32_t multiViewMasks[] = { allViewsMask };
+ uint32_t multiViewCorrelationMasks[] = { allViewsMask };
+#endif
+ if (multiViewCount > 0) {
+ if (!caps.multiView) {
+ qWarning("Cannot create multiview render pass without support for the Vulkan 1.1 multiview feature");
+ return false;
+ }
+#ifdef VK_VERSION_1_1
+ multiViewInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO;
+ multiViewInfo.subpassCount = 1;
+ multiViewInfo.pViewMasks = multiViewMasks;
+ multiViewInfo.correlationMaskCount = 1;
+ multiViewInfo.pCorrelationMasks = multiViewCorrelationMasks;
+ rpInfo.pNext = &multiViewInfo;
+#endif
+ }
+
VkResult err = df->vkCreateRenderPass(dev, &rpInfo, nullptr, &rpD->rp);
if (err != VK_SUCCESS) {
qWarning("Failed to create renderpass: %d", err);
@@ -4438,7 +4476,7 @@ bool QRhiVulkan::isFeatureSupported(QRhi::Feature feature) const
case QRhi::ThreeDimensionalTextureMipmaps:
return true;
case QRhi::MultiView:
- return false;
+ return caps.multiView;
default:
Q_UNREACHABLE_RETURN(false);
}
@@ -6695,12 +6733,14 @@ bool QVkTextureRenderTarget::create()
Q_ASSERT(texD || rbD);
if (texD) {
Q_ASSERT(texD->flags().testFlag(QRhiTexture::RenderTarget));
+ const bool is1D = texD->flags().testFlag(QRhiTexture::OneDimensional);
+ const bool isMultiView = it->multiViewCount() >= 2;
VkImageViewCreateInfo viewInfo = {};
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
viewInfo.image = texD->image;
- viewInfo.viewType = texD->flags().testFlag(QRhiTexture::OneDimensional)
- ? VK_IMAGE_VIEW_TYPE_1D
- : VK_IMAGE_VIEW_TYPE_2D;
+ viewInfo.viewType = is1D ? VK_IMAGE_VIEW_TYPE_1D
+ : (isMultiView ? VK_IMAGE_VIEW_TYPE_2D_ARRAY
+ : VK_IMAGE_VIEW_TYPE_2D);
viewInfo.format = texD->vkformat;
viewInfo.components.r = VK_COMPONENT_SWIZZLE_R;
viewInfo.components.g = VK_COMPONENT_SWIZZLE_G;
@@ -6710,7 +6750,7 @@ bool QVkTextureRenderTarget::create()
viewInfo.subresourceRange.baseMipLevel = uint32_t(it->level());
viewInfo.subresourceRange.levelCount = 1;
viewInfo.subresourceRange.baseArrayLayer = uint32_t(it->layer());
- viewInfo.subresourceRange.layerCount = 1;
+ viewInfo.subresourceRange.layerCount = uint32_t(isMultiView ? it->multiViewCount() : 1);
VkResult err = rhiD->df->vkCreateImageView(rhiD->dev, &viewInfo, nullptr, &rtv[attIndex]);
if (err != VK_SUCCESS) {
qWarning("Failed to create render target image view: %d", err);