From b083c27d0ab1e436c1b21785c67e2df419c67335 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Wed, 19 Jan 2022 18:47:45 +0100 Subject: [PATCH] QVulkanWindow: make it possible to override the enabled features We already have a precedent for this: the QueueCreateInfoModifier callback. Following the pattern, add a EnabledFeaturesModifier that can alter the VkPhysicalDeviceFeatures that is passed to vkCreateDevice(). [ChangeLog][QtGui][QVulkanWindow] QVulkanWindow can now invoke a callback to alter the VkPhysicalDeviceFeatures object used to create the Vulkan device. This allows enabling 1.1, 1.2, and extension features. Fixes: QTBUG-99803 Change-Id: I5ede0c6bc3430cbb304d4961eb9e44faad5ce4d7 Reviewed-by: Andy Nichols --- src/gui/vulkan/qvulkanwindow.cpp | 48 ++++++++++++++++++++++++++++++-- src/gui/vulkan/qvulkanwindow.h | 3 ++ src/gui/vulkan/qvulkanwindow_p.h | 1 + 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/src/gui/vulkan/qvulkanwindow.cpp b/src/gui/vulkan/qvulkanwindow.cpp index b57046844b3..b901d7af39f 100644 --- a/src/gui/vulkan/qvulkanwindow.cpp +++ b/src/gui/vulkan/qvulkanwindow.cpp @@ -211,6 +211,11 @@ Q_LOGGING_CATEGORY(lcGuiVk, "qt.vulkan") When it comes to device features, QVulkanWindow enables all Vulkan 1.0 features that are reported as supported from vkGetPhysicalDeviceFeatures(). + This is always not sufficient, and therefore full control over the + VkPhysicalDeviceFeatures used for device creation is possible too by + registering a callback function with setEnabledFeaturesModifier(). When set, + the callback function is invoked, letting it alter the + VkPhysicalDeviceFeatures, instead of enabling only the 1.0 features. \sa QVulkanInstance, QWindow */ @@ -729,10 +734,14 @@ void QVulkanWindowPrivate::init() devInfo.enabledExtensionCount = devExts.count(); devInfo.ppEnabledExtensionNames = devExts.constData(); - // Enable all 1.0 features. VkPhysicalDeviceFeatures features; memset(&features, 0, sizeof(features)); - f->vkGetPhysicalDeviceFeatures(physDev, &features); + if (enabledFeaturesModifier) { + enabledFeaturesModifier(features); + } else { + // Enable all 1.0 features. + f->vkGetPhysicalDeviceFeatures(physDev, &features); + } devInfo.pEnabledFeatures = &features; // Device layers are not supported by QVulkanWindow since that's an already deprecated @@ -1634,6 +1643,41 @@ void QVulkanWindow::setQueueCreateInfoModifier(const QueueCreateInfoModifier &mo d->queueCreateInfoModifier = modifier; } +/*! + \typedef QVulkanWindow::EnabledFeaturesModifier + + A function that is called during graphics initialization to alter the + VkPhysicalDeviceFeatures that is passed in when creating a Vulkan device + object. + + By default QVulkanWindow enables all Vulkan 1.0 features the physical + device reports as supported. That is not always sufficient when working + with Vulkan 1.1 or 1.2 features and extensions. Hence this callback + mechanism. + + The VkPhysicalDeviceFeatures reference passed in is all zeroed out at the + point when the function is invoked. It is up to the function to change + members to true, or set up \c pNext chains as it sees fit. + + \note When setting up \c pNext chains, make sure the referenced objects + have a long enough lifetime, for example by storing them as member + variables in the QVulkanWindow subclass. + + \sa setEnabledFeaturesModifier() + */ + +/*! + Sets the enabled device features modification function \a modifier. + + \sa EnabledFeaturesModifier + + \since 6.4 + */ +void QVulkanWindow::setEnabledFeaturesModifier(const EnabledFeaturesModifier &modifier) +{ + Q_D(QVulkanWindow); + d->enabledFeaturesModifier = modifier; +} /*! Returns true if this window has successfully initialized all Vulkan diff --git a/src/gui/vulkan/qvulkanwindow.h b/src/gui/vulkan/qvulkanwindow.h index 4325b6317d5..58816e2f6f4 100644 --- a/src/gui/vulkan/qvulkanwindow.h +++ b/src/gui/vulkan/qvulkanwindow.h @@ -113,6 +113,9 @@ public: QVulkanInfoVector supportedDeviceExtensions(); void setDeviceExtensions(const QByteArrayList &extensions); + typedef std::function EnabledFeaturesModifier; + void setEnabledFeaturesModifier(const EnabledFeaturesModifier &modifier); + void setPreferredColorFormats(const QList &formats); QList supportedSampleCounts(); diff --git a/src/gui/vulkan/qvulkanwindow_p.h b/src/gui/vulkan/qvulkanwindow_p.h index de69b5c9b07..43ff71f8333 100644 --- a/src/gui/vulkan/qvulkanwindow_p.h +++ b/src/gui/vulkan/qvulkanwindow_p.h @@ -103,6 +103,7 @@ public: QList requestedColorFormats; VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT; QVulkanWindow::QueueCreateInfoModifier queueCreateInfoModifier; + QVulkanWindow::EnabledFeaturesModifier enabledFeaturesModifier; VkDevice dev = VK_NULL_HANDLE; QVulkanDeviceFunctions *devFuncs;