rhi: vulkan: Include multiViewCount in renderpass compatibility
Change-Id: I3185ce27c52c138053fee4805eccbe3575b9433a Reviewed-by: Andy Nichols <andy.nichols@qt.io>
This commit is contained in:
parent
ee736717d3
commit
0e80b3b527
@ -1285,6 +1285,7 @@ bool QRhiVulkan::createDefaultRenderPass(QVkRenderPassDescriptor *rpD, bool hasD
|
||||
rpD->colorRefs.append({ 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL });
|
||||
|
||||
rpD->hasDepthStencil = hasDepthStencil;
|
||||
rpD->multiViewCount = 0;
|
||||
|
||||
if (hasDepthStencil) {
|
||||
// clear on load + no store + lazy alloc + transient image should play
|
||||
@ -1397,6 +1398,7 @@ bool QRhiVulkan::createOffscreenRenderPass(QVkRenderPassDescriptor *rpD,
|
||||
}
|
||||
}
|
||||
Q_ASSERT(multiViewCount == 0 || multiViewCount >= 2);
|
||||
rpD->multiViewCount = uint32_t(multiViewCount);
|
||||
|
||||
rpD->hasDepthStencil = depthStencilBuffer || depthTexture;
|
||||
if (rpD->hasDepthStencil) {
|
||||
@ -6504,6 +6506,8 @@ bool QVkRenderPassDescriptor::isCompatible(const QRhiRenderPassDescriptor *other
|
||||
return false;
|
||||
if (hasDepthStencil != o->hasDepthStencil)
|
||||
return false;
|
||||
if (multiViewCount != o->multiViewCount)
|
||||
return false;
|
||||
|
||||
for (int i = 0, ie = colorRefs.size(); i != ie; ++i) {
|
||||
const uint32_t attIdx = colorRefs[i].attachment;
|
||||
@ -6543,6 +6547,7 @@ void QVkRenderPassDescriptor::updateSerializedFormat()
|
||||
*p++ = colorRefs.size();
|
||||
*p++ = resolveRefs.size();
|
||||
*p++ = hasDepthStencil;
|
||||
*p++ = multiViewCount;
|
||||
|
||||
auto serializeAttachmentData = [this, &p](uint32_t attIdx) {
|
||||
const bool used = attIdx != VK_ATTACHMENT_UNUSED;
|
||||
@ -6586,6 +6591,7 @@ QRhiRenderPassDescriptor *QVkRenderPassDescriptor::newCompatibleRenderPassDescri
|
||||
rpD->resolveRefs = resolveRefs;
|
||||
rpD->subpassDeps = subpassDeps;
|
||||
rpD->hasDepthStencil = hasDepthStencil;
|
||||
rpD->multiViewCount = multiViewCount;
|
||||
rpD->dsRef = dsRef;
|
||||
|
||||
VkRenderPassCreateInfo rpInfo;
|
||||
@ -6723,7 +6729,7 @@ bool QVkTextureRenderTarget::create()
|
||||
|
||||
QRHI_RES_RHI(QRhiVulkan);
|
||||
QVarLengthArray<VkImageView, 8> views;
|
||||
uint32_t multiViewCount = 0;
|
||||
d.multiViewCount = 0;
|
||||
|
||||
d.colorAttCount = 0;
|
||||
int attIndex = 0;
|
||||
@ -6736,8 +6742,8 @@ bool QVkTextureRenderTarget::create()
|
||||
Q_ASSERT(texD->flags().testFlag(QRhiTexture::RenderTarget));
|
||||
const bool is1D = texD->flags().testFlag(QRhiTexture::OneDimensional);
|
||||
const bool isMultiView = it->multiViewCount() >= 2;
|
||||
if (isMultiView && multiViewCount == 0)
|
||||
multiViewCount = uint32_t(it->multiViewCount());
|
||||
if (isMultiView && d.multiViewCount == 0)
|
||||
d.multiViewCount = it->multiViewCount();
|
||||
VkImageViewCreateInfo viewInfo = {};
|
||||
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||
viewInfo.image = texD->image;
|
||||
@ -6798,7 +6804,7 @@ bool QVkTextureRenderTarget::create()
|
||||
|
||||
d.resolveAttCount = 0;
|
||||
attIndex = 0;
|
||||
Q_ASSERT(multiViewCount == 0 || multiViewCount >= 2);
|
||||
Q_ASSERT(d.multiViewCount == 0 || d.multiViewCount >= 2);
|
||||
for (auto it = m_desc.cbeginColorAttachments(), itEnd = m_desc.cendColorAttachments(); it != itEnd; ++it, ++attIndex) {
|
||||
if (it->resolveTexture()) {
|
||||
QVkTexture *resTexD = QRHI_RES(QVkTexture, it->resolveTexture());
|
||||
@ -6808,8 +6814,8 @@ bool QVkTextureRenderTarget::create()
|
||||
VkImageViewCreateInfo viewInfo = {};
|
||||
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||
viewInfo.image = resTexD->image;
|
||||
viewInfo.viewType = multiViewCount ? VK_IMAGE_VIEW_TYPE_2D_ARRAY
|
||||
: VK_IMAGE_VIEW_TYPE_2D;
|
||||
viewInfo.viewType = d.multiViewCount ? VK_IMAGE_VIEW_TYPE_2D_ARRAY
|
||||
: VK_IMAGE_VIEW_TYPE_2D;
|
||||
viewInfo.format = resTexD->vkformat;
|
||||
viewInfo.components.r = VK_COMPONENT_SWIZZLE_R;
|
||||
viewInfo.components.g = VK_COMPONENT_SWIZZLE_G;
|
||||
@ -6819,7 +6825,7 @@ bool QVkTextureRenderTarget::create()
|
||||
viewInfo.subresourceRange.baseMipLevel = uint32_t(it->resolveLevel());
|
||||
viewInfo.subresourceRange.levelCount = 1;
|
||||
viewInfo.subresourceRange.baseArrayLayer = uint32_t(it->resolveLayer());
|
||||
viewInfo.subresourceRange.layerCount = qMax(1u, multiViewCount);
|
||||
viewInfo.subresourceRange.layerCount = qMax<uint32_t>(1, d.multiViewCount);
|
||||
VkResult err = rhiD->df->vkCreateImageView(rhiD->dev, &viewInfo, nullptr, &resrtv[attIndex]);
|
||||
if (err != VK_SUCCESS) {
|
||||
qWarning("Failed to create render target resolve image view: %d", err);
|
||||
|
@ -162,6 +162,7 @@ struct QVkRenderPassDescriptor : public QRhiRenderPassDescriptor
|
||||
QVarLengthArray<VkAttachmentReference, 8> resolveRefs;
|
||||
QVarLengthArray<VkSubpassDependency, 2> subpassDeps;
|
||||
bool hasDepthStencil = false;
|
||||
uint32_t multiViewCount = 0;
|
||||
VkAttachmentReference dsRef;
|
||||
QVector<quint32> serializedFormatData;
|
||||
QRhiVulkanRenderPassNativeHandles nativeHandlesStruct;
|
||||
@ -178,6 +179,7 @@ struct QVkRenderTargetData
|
||||
int colorAttCount = 0;
|
||||
int dsAttCount = 0;
|
||||
int resolveAttCount = 0;
|
||||
int multiViewCount = 0;
|
||||
QRhiRenderTargetAttachmentTracker::ResIdList currentResIdList;
|
||||
static const int MAX_COLOR_ATTACHMENTS = 8;
|
||||
};
|
||||
|
@ -4582,6 +4582,59 @@ void tst_QRhi::renderPassDescriptorCompatibility()
|
||||
} else {
|
||||
qDebug("Skipping texture format dependent tests");
|
||||
}
|
||||
|
||||
if (rhi->isFeatureSupported(QRhi::MultiView)) {
|
||||
{
|
||||
QScopedPointer<QRhiTexture> texArr(rhi->newTextureArray(QRhiTexture::RGBA8, 2, QSize(512, 512), 1, QRhiTexture::RenderTarget));
|
||||
QVERIFY(texArr->create());
|
||||
QRhiColorAttachment multiViewAtt(texArr.data());
|
||||
multiViewAtt.setMultiViewCount(2);
|
||||
QRhiTextureRenderTargetDescription rtDesc(multiViewAtt);
|
||||
QScopedPointer<QRhiTextureRenderTarget> rt(rhi->newTextureRenderTarget(rtDesc));
|
||||
QScopedPointer<QRhiRenderPassDescriptor> rpDesc(rt->newCompatibleRenderPassDescriptor());
|
||||
rt->setRenderPassDescriptor(rpDesc.data());
|
||||
QVERIFY(rt->create());
|
||||
|
||||
QScopedPointer<QRhiTextureRenderTarget> rt2(rhi->newTextureRenderTarget(rtDesc));
|
||||
QScopedPointer<QRhiRenderPassDescriptor> rpDesc2(rt2->newCompatibleRenderPassDescriptor());
|
||||
rt2->setRenderPassDescriptor(rpDesc2.data());
|
||||
QVERIFY(rt2->create());
|
||||
|
||||
QVERIFY(rpDesc->isCompatible(rpDesc2.data()));
|
||||
QVERIFY(rpDesc2->isCompatible(rpDesc.data()));
|
||||
QCOMPARE(rpDesc->serializedFormat(), rpDesc2->serializedFormat());
|
||||
|
||||
QScopedPointer<QRhiRenderPassDescriptor> rpDescClone(rpDesc->newCompatibleRenderPassDescriptor());
|
||||
QVERIFY(rpDesc->isCompatible(rpDescClone.data()));
|
||||
QVERIFY(rpDesc2->isCompatible(rpDescClone.data()));
|
||||
QCOMPARE(rpDesc->serializedFormat(), rpDescClone->serializedFormat());
|
||||
|
||||
// With Vulkan the multiViewCount really matters since it is baked
|
||||
// in to underlying native object (VkRenderPass). Verify that the
|
||||
// compatibility check fails when the view count differs. Other
|
||||
// backends cannot do this test since they will likely report the
|
||||
// rps being compatible regardless.
|
||||
if (impl == QRhi::Vulkan) {
|
||||
QRhiColorAttachment nonMultiViewAtt(texArr.data());
|
||||
QRhiTextureRenderTargetDescription rtDesc3(nonMultiViewAtt);
|
||||
QScopedPointer<QRhiTextureRenderTarget> rt3(rhi->newTextureRenderTarget(rtDesc3));
|
||||
QScopedPointer<QRhiRenderPassDescriptor> rpDesc3(rt3->newCompatibleRenderPassDescriptor());
|
||||
rt3->setRenderPassDescriptor(rpDesc3.data());
|
||||
QVERIFY(rt3->create());
|
||||
|
||||
QVERIFY(!rpDesc->isCompatible(rpDesc3.data()));
|
||||
QVERIFY(!rpDesc2->isCompatible(rpDesc3.data()));
|
||||
QVERIFY(rpDesc->serializedFormat() != rpDesc3->serializedFormat());
|
||||
|
||||
QScopedPointer<QRhiRenderPassDescriptor> rpDesc3Clone(rpDesc3->newCompatibleRenderPassDescriptor());
|
||||
QVERIFY(!rpDesc->isCompatible(rpDesc3Clone.data()));
|
||||
QVERIFY(!rpDesc2->isCompatible(rpDesc3Clone.data()));
|
||||
QVERIFY(rpDesc->serializedFormat() != rpDesc3Clone->serializedFormat());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
qDebug("Skipping multiview dependent tests");
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QRhi::renderPassDescriptorClone_data()
|
||||
|
Loading…
Reference in New Issue
Block a user