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 <andy.nichols@qt.io>
This commit is contained in:
Laszlo Agocs 2022-01-19 18:47:45 +01:00
parent 79aad61fc1
commit b083c27d0a
3 changed files with 50 additions and 2 deletions

View File

@ -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

View File

@ -113,6 +113,9 @@ public:
QVulkanInfoVector<QVulkanExtension> supportedDeviceExtensions();
void setDeviceExtensions(const QByteArrayList &extensions);
typedef std::function<void(VkPhysicalDeviceFeatures &)> EnabledFeaturesModifier;
void setEnabledFeaturesModifier(const EnabledFeaturesModifier &modifier);
void setPreferredColorFormats(const QList<VkFormat> &formats);
QList<int> supportedSampleCounts();

View File

@ -103,6 +103,7 @@ public:
QList<VkFormat> requestedColorFormats;
VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
QVulkanWindow::QueueCreateInfoModifier queueCreateInfoModifier;
QVulkanWindow::EnabledFeaturesModifier enabledFeaturesModifier;
VkDevice dev = VK_NULL_HANDLE;
QVulkanDeviceFunctions *devFuncs;