RHI: Fix running with Vulkan on Wayland

When the Wayland client plugin is in use, the capabilities
for the surface may report a minimum image count of 4. The
internal "maximum minimum count" of 3, was arbitrary and
only used for sizing buffers. To be more friendly to different
setups, we remove the restriction and use QVarLengthArrays
instead.

We also set the initial size of the buffers to 4 so that we
can run with Wayland without any resizing, but now the arrays
will also grow to be safe for cases where 4 is not sufficient.

Change-Id: Iba5434e84417d36b70f2655b152e816f04650ce4
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
This commit is contained in:
Eskil Abrahamsen Blomfeldt 2020-03-30 12:28:49 +02:00
parent adc205631b
commit 3abacf39de
2 changed files with 12 additions and 19 deletions

View File

@ -1296,16 +1296,11 @@ bool QRhiVulkan::recreateSwapChain(QRhiSwapChain *swapChain)
VkSurfaceCapabilitiesKHR surfaceCaps;
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physDev, swapChainD->surface, &surfaceCaps);
quint32 reqBufferCount;
if (swapChainD->m_flags.testFlag(QRhiSwapChain::MinimalBufferCount)) {
if (swapChainD->m_flags.testFlag(QRhiSwapChain::MinimalBufferCount) || surfaceCaps.maxImageCount == 0) {
reqBufferCount = qMax<quint32>(2, surfaceCaps.minImageCount);
} else {
const quint32 maxBuffers = QVkSwapChain::MAX_BUFFER_COUNT;
if (surfaceCaps.maxImageCount)
reqBufferCount = qMax(qMin(surfaceCaps.maxImageCount, maxBuffers), surfaceCaps.minImageCount);
else
reqBufferCount = qMax<quint32>(2, surfaceCaps.minImageCount);
reqBufferCount = qMax(qMin<quint32>(surfaceCaps.maxImageCount, 3), surfaceCaps.minImageCount);
}
VkSurfaceTransformFlagBitsKHR preTransform =
(surfaceCaps.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR)
? VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR
@ -1389,23 +1384,19 @@ bool QRhiVulkan::recreateSwapChain(QRhiSwapChain *swapChain)
return false;
}
if (actualSwapChainBufferCount > QVkSwapChain::MAX_BUFFER_COUNT) {
qWarning("Too many swapchain buffers (%u)", actualSwapChainBufferCount);
return false;
}
if (actualSwapChainBufferCount != reqBufferCount)
qCDebug(QRHI_LOG_INFO, "Actual swapchain buffer count is %u", actualSwapChainBufferCount);
swapChainD->bufferCount = int(actualSwapChainBufferCount);
VkImage swapChainImages[QVkSwapChain::MAX_BUFFER_COUNT];
err = vkGetSwapchainImagesKHR(dev, swapChainD->sc, &actualSwapChainBufferCount, swapChainImages);
QVarLengthArray<VkImage, QVkSwapChain::EXPECTED_MAX_BUFFER_COUNT> swapChainImages(actualSwapChainBufferCount);
err = vkGetSwapchainImagesKHR(dev, swapChainD->sc, &actualSwapChainBufferCount, swapChainImages.data());
if (err != VK_SUCCESS) {
qWarning("Failed to get swapchain images: %d", err);
return false;
}
VkImage msaaImages[QVkSwapChain::MAX_BUFFER_COUNT];
VkImageView msaaViews[QVkSwapChain::MAX_BUFFER_COUNT];
QVarLengthArray<VkImage, QVkSwapChain::EXPECTED_MAX_BUFFER_COUNT> msaaImages(swapChainD->bufferCount);
QVarLengthArray<VkImageView, QVkSwapChain::EXPECTED_MAX_BUFFER_COUNT> msaaViews(swapChainD->bufferCount);
if (swapChainD->samples > VK_SAMPLE_COUNT_1_BIT) {
if (!createTransientImage(swapChainD->colorFormat,
swapChainD->pixelSize,
@ -1413,8 +1404,8 @@ bool QRhiVulkan::recreateSwapChain(QRhiSwapChain *swapChain)
VK_IMAGE_ASPECT_COLOR_BIT,
swapChainD->samples,
&swapChainD->msaaImageMem,
msaaImages,
msaaViews,
msaaImages.data(),
msaaViews.data(),
swapChainD->bufferCount))
{
qWarning("Failed to create transient image for MSAA color buffer");
@ -1427,6 +1418,7 @@ bool QRhiVulkan::recreateSwapChain(QRhiSwapChain *swapChain)
fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
swapChainD->imageRes.resize(swapChainD->bufferCount);
for (int i = 0; i < swapChainD->bufferCount; ++i) {
QVkSwapChain::ImageResources &image(swapChainD->imageRes[i]);
image.image = swapChainImages[i];

View File

@ -587,7 +587,7 @@ struct QVkSwapChain : public QRhiSwapChain
bool ensureSurface();
static const quint32 MAX_BUFFER_COUNT = 3;
static const quint32 EXPECTED_MAX_BUFFER_COUNT = 4;
QWindow *window = nullptr;
QSize pixelSize;
@ -617,7 +617,8 @@ struct QVkSwapChain : public QRhiSwapChain
ScImageUseTransferSource
};
LastUse lastUse = ScImageUseNone;
} imageRes[MAX_BUFFER_COUNT];
};
QVarLengthArray<ImageResources, EXPECTED_MAX_BUFFER_COUNT> imageRes;
struct FrameResources {
VkFence imageFence = VK_NULL_HANDLE;