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:
parent
adc205631b
commit
3abacf39de
@ -1296,16 +1296,11 @@ bool QRhiVulkan::recreateSwapChain(QRhiSwapChain *swapChain)
|
|||||||
VkSurfaceCapabilitiesKHR surfaceCaps;
|
VkSurfaceCapabilitiesKHR surfaceCaps;
|
||||||
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physDev, swapChainD->surface, &surfaceCaps);
|
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physDev, swapChainD->surface, &surfaceCaps);
|
||||||
quint32 reqBufferCount;
|
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);
|
reqBufferCount = qMax<quint32>(2, surfaceCaps.minImageCount);
|
||||||
} else {
|
} else {
|
||||||
const quint32 maxBuffers = QVkSwapChain::MAX_BUFFER_COUNT;
|
reqBufferCount = qMax(qMin<quint32>(surfaceCaps.maxImageCount, 3), surfaceCaps.minImageCount);
|
||||||
if (surfaceCaps.maxImageCount)
|
|
||||||
reqBufferCount = qMax(qMin(surfaceCaps.maxImageCount, maxBuffers), surfaceCaps.minImageCount);
|
|
||||||
else
|
|
||||||
reqBufferCount = qMax<quint32>(2, surfaceCaps.minImageCount);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VkSurfaceTransformFlagBitsKHR preTransform =
|
VkSurfaceTransformFlagBitsKHR preTransform =
|
||||||
(surfaceCaps.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR)
|
(surfaceCaps.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR)
|
||||||
? VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR
|
? VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR
|
||||||
@ -1389,23 +1384,19 @@ bool QRhiVulkan::recreateSwapChain(QRhiSwapChain *swapChain)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (actualSwapChainBufferCount > QVkSwapChain::MAX_BUFFER_COUNT) {
|
|
||||||
qWarning("Too many swapchain buffers (%u)", actualSwapChainBufferCount);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (actualSwapChainBufferCount != reqBufferCount)
|
if (actualSwapChainBufferCount != reqBufferCount)
|
||||||
qCDebug(QRHI_LOG_INFO, "Actual swapchain buffer count is %u", actualSwapChainBufferCount);
|
qCDebug(QRHI_LOG_INFO, "Actual swapchain buffer count is %u", actualSwapChainBufferCount);
|
||||||
swapChainD->bufferCount = int(actualSwapChainBufferCount);
|
swapChainD->bufferCount = int(actualSwapChainBufferCount);
|
||||||
|
|
||||||
VkImage swapChainImages[QVkSwapChain::MAX_BUFFER_COUNT];
|
QVarLengthArray<VkImage, QVkSwapChain::EXPECTED_MAX_BUFFER_COUNT> swapChainImages(actualSwapChainBufferCount);
|
||||||
err = vkGetSwapchainImagesKHR(dev, swapChainD->sc, &actualSwapChainBufferCount, swapChainImages);
|
err = vkGetSwapchainImagesKHR(dev, swapChainD->sc, &actualSwapChainBufferCount, swapChainImages.data());
|
||||||
if (err != VK_SUCCESS) {
|
if (err != VK_SUCCESS) {
|
||||||
qWarning("Failed to get swapchain images: %d", err);
|
qWarning("Failed to get swapchain images: %d", err);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkImage msaaImages[QVkSwapChain::MAX_BUFFER_COUNT];
|
QVarLengthArray<VkImage, QVkSwapChain::EXPECTED_MAX_BUFFER_COUNT> msaaImages(swapChainD->bufferCount);
|
||||||
VkImageView msaaViews[QVkSwapChain::MAX_BUFFER_COUNT];
|
QVarLengthArray<VkImageView, QVkSwapChain::EXPECTED_MAX_BUFFER_COUNT> msaaViews(swapChainD->bufferCount);
|
||||||
if (swapChainD->samples > VK_SAMPLE_COUNT_1_BIT) {
|
if (swapChainD->samples > VK_SAMPLE_COUNT_1_BIT) {
|
||||||
if (!createTransientImage(swapChainD->colorFormat,
|
if (!createTransientImage(swapChainD->colorFormat,
|
||||||
swapChainD->pixelSize,
|
swapChainD->pixelSize,
|
||||||
@ -1413,8 +1404,8 @@ bool QRhiVulkan::recreateSwapChain(QRhiSwapChain *swapChain)
|
|||||||
VK_IMAGE_ASPECT_COLOR_BIT,
|
VK_IMAGE_ASPECT_COLOR_BIT,
|
||||||
swapChainD->samples,
|
swapChainD->samples,
|
||||||
&swapChainD->msaaImageMem,
|
&swapChainD->msaaImageMem,
|
||||||
msaaImages,
|
msaaImages.data(),
|
||||||
msaaViews,
|
msaaViews.data(),
|
||||||
swapChainD->bufferCount))
|
swapChainD->bufferCount))
|
||||||
{
|
{
|
||||||
qWarning("Failed to create transient image for MSAA color buffer");
|
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.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
||||||
fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
|
fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
|
||||||
|
|
||||||
|
swapChainD->imageRes.resize(swapChainD->bufferCount);
|
||||||
for (int i = 0; i < swapChainD->bufferCount; ++i) {
|
for (int i = 0; i < swapChainD->bufferCount; ++i) {
|
||||||
QVkSwapChain::ImageResources &image(swapChainD->imageRes[i]);
|
QVkSwapChain::ImageResources &image(swapChainD->imageRes[i]);
|
||||||
image.image = swapChainImages[i];
|
image.image = swapChainImages[i];
|
||||||
|
@ -587,7 +587,7 @@ struct QVkSwapChain : public QRhiSwapChain
|
|||||||
|
|
||||||
bool ensureSurface();
|
bool ensureSurface();
|
||||||
|
|
||||||
static const quint32 MAX_BUFFER_COUNT = 3;
|
static const quint32 EXPECTED_MAX_BUFFER_COUNT = 4;
|
||||||
|
|
||||||
QWindow *window = nullptr;
|
QWindow *window = nullptr;
|
||||||
QSize pixelSize;
|
QSize pixelSize;
|
||||||
@ -617,7 +617,8 @@ struct QVkSwapChain : public QRhiSwapChain
|
|||||||
ScImageUseTransferSource
|
ScImageUseTransferSource
|
||||||
};
|
};
|
||||||
LastUse lastUse = ScImageUseNone;
|
LastUse lastUse = ScImageUseNone;
|
||||||
} imageRes[MAX_BUFFER_COUNT];
|
};
|
||||||
|
QVarLengthArray<ImageResources, EXPECTED_MAX_BUFFER_COUNT> imageRes;
|
||||||
|
|
||||||
struct FrameResources {
|
struct FrameResources {
|
||||||
VkFence imageFence = VK_NULL_HANDLE;
|
VkFence imageFence = VK_NULL_HANDLE;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user