summaryrefslogtreecommitdiffstats
path: root/src/gui/rhi
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2024-02-01 18:53:05 +0100
committerLaszlo Agocs <laszlo.agocs@qt.io>2024-02-02 12:59:35 +0100
commit90a94527d2728f6deeff00a4583dd62332d0aec9 (patch)
tree5731d9eb2faf96b3c6783749e2d0f94f10f54b7d /src/gui/rhi
parent8c178a540faf27fdab6977b13507d94735f89e21 (diff)
rhi: vulkan: Query and enable multiview features when API is 1.1
Meaning a Vulkan implementation that is not 1.0, not 1.2, not 1.3, but 1.1. This does not have the 1.2+ versioning mechanisms. Change-Id: I9d9346d505162adc0e03aa04217930d41c72027f Reviewed-by: Andy Nichols <andy.nichols@qt.io>
Diffstat (limited to 'src/gui/rhi')
-rw-r--r--src/gui/rhi/qrhivulkan.cpp93
-rw-r--r--src/gui/rhi/qrhivulkan_p.h5
2 files changed, 75 insertions, 23 deletions
diff --git a/src/gui/rhi/qrhivulkan.cpp b/src/gui/rhi/qrhivulkan.cpp
index 242263a080..111fefe7a9 100644
--- a/src/gui/rhi/qrhivulkan.cpp
+++ b/src/gui/rhi/qrhivulkan.cpp
@@ -529,30 +529,64 @@ bool QRhiVulkan::create(QRhi::Flags flags)
driverInfoStruct.vendorId = physDevProperties.vendorID;
driverInfoStruct.deviceType = toRhiDeviceType(physDevProperties.deviceType);
-#ifdef VK_VERSION_1_2 // Vulkan11Features is only in Vulkan 1.2
+ bool featuresQueried = false;
+#ifdef VK_VERSION_1_1
VkPhysicalDeviceFeatures2 physDevFeaturesChainable = {};
physDevFeaturesChainable.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
- physDevFeatures11 = {};
- physDevFeatures11.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES;
- physDevFeatures12 = {};
- physDevFeatures12.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES;
+#endif
+
+ // Vulkan >=1.2 headers at build time, >=1.2 implementation at run time
+#ifdef VK_VERSION_1_2
+ if (!featuresQueried) {
+ // Vulkan11Features, Vulkan12Features, etc. are only in Vulkan 1.2 and newer.
+ if (caps.apiVersion >= QVersionNumber(1, 2)) {
+ physDevFeatures11IfApi12OrNewer = {};
+ physDevFeatures11IfApi12OrNewer.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES;
+ physDevFeatures12 = {};
+ physDevFeatures12.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES;
#ifdef VK_VERSION_1_3
- physDevFeatures13 = {};
- physDevFeatures13.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES;
+ physDevFeatures13 = {};
+ physDevFeatures13.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES;
#endif
- if (caps.apiVersion >= QVersionNumber(1, 2)) {
- physDevFeaturesChainable.pNext = &physDevFeatures11;
- physDevFeatures11.pNext = &physDevFeatures12;
+ physDevFeaturesChainable.pNext = &physDevFeatures11IfApi12OrNewer;
+ physDevFeatures11IfApi12OrNewer.pNext = &physDevFeatures12;
#ifdef VK_VERSION_1_3
- if (caps.apiVersion >= QVersionNumber(1, 3))
- physDevFeatures12.pNext = &physDevFeatures13;
+ if (caps.apiVersion >= QVersionNumber(1, 3))
+ physDevFeatures12.pNext = &physDevFeatures13;
#endif
- f->vkGetPhysicalDeviceFeatures2(physDev, &physDevFeaturesChainable);
- memcpy(&physDevFeatures, &physDevFeaturesChainable.features, sizeof(VkPhysicalDeviceFeatures));
- } else
+ f->vkGetPhysicalDeviceFeatures2(physDev, &physDevFeaturesChainable);
+ memcpy(&physDevFeatures, &physDevFeaturesChainable.features, sizeof(VkPhysicalDeviceFeatures));
+ featuresQueried = true;
+ }
+ }
#endif // VK_VERSION_1_2
- {
+
+ // Vulkan >=1.1 headers at build time, 1.1 implementation at run time
+#ifdef VK_VERSION_1_1
+ if (!featuresQueried) {
+ // Vulkan versioning nightmares: if the runtime API version is 1.1,
+ // there is no Vulkan11Features (introduced in 1.2+, the headers might
+ // have the types and structs, but the Vulkan implementation version at
+ // run time is what matters). But there are individual feature structs.
+ // For multiview, it is important to get this right since at the time of
+ // writing Quest 3 Android is a Vulkan 1.1 implementation at run time on
+ // the headset.
+ if (caps.apiVersion == QVersionNumber(1, 1)) {
+ multiviewFeaturesIfApi11 = {};
+ multiviewFeaturesIfApi11.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES;
+ physDevFeaturesChainable.pNext = &multiviewFeaturesIfApi11;
+ f->vkGetPhysicalDeviceFeatures2(physDev, &physDevFeaturesChainable);
+ memcpy(&physDevFeatures, &physDevFeaturesChainable.features, sizeof(VkPhysicalDeviceFeatures));
+ featuresQueried = true;
+ }
+ }
+#endif
+
+ if (!featuresQueried) {
+ // If the API version at run time is 1.0 (or we are building with
+ // ancient 1.0 headers), then do the Vulkan 1.0 query.
f->vkGetPhysicalDeviceFeatures(physDev, &physDevFeatures);
+ featuresQueried = true;
}
// Choose queue and create device, unless the device was specified in importParams.
@@ -686,15 +720,24 @@ bool QRhiVulkan::create(QRhi::Flags flags)
// tessellationShader, geometryShader
// textureCompressionETC2, textureCompressionASTC_LDR, textureCompressionBC
-#ifdef VK_VERSION_1_2
- if (caps.apiVersion >= QVersionNumber(1, 2)) {
- physDevFeaturesChainable.features.robustBufferAccess = VK_FALSE;
+#ifdef VK_VERSION_1_1
+ physDevFeaturesChainable.features.robustBufferAccess = VK_FALSE;
+#endif
#ifdef VK_VERSION_1_3
- physDevFeatures13.robustImageAccess = VK_FALSE;
+ physDevFeatures13.robustImageAccess = VK_FALSE;
#endif
+
+#ifdef VK_VERSION_1_1
+ if (caps.apiVersion >= QVersionNumber(1, 1)) {
+ // For a >=1.2 implementation at run time, this will enable all
+ // (1.0-1.3) features reported as supported, except the ones we turn
+ // off explicitly above. For a 1.1 implementation at run time, this
+ // only enables the 1.0 and multiview features reported as
+ // supported. We will not be bothering with the Vulkan 1.1
+ // individual feature struct nonsense.
devInfo.pNext = &physDevFeaturesChainable;
} else
-#endif // VK_VERSION_1_2
+#endif
{
physDevFeatures.robustBufferAccess = VK_FALSE;
devInfo.pEnabledFeatures = &physDevFeatures;
@@ -755,7 +798,13 @@ bool QRhiVulkan::create(QRhi::Flags flags)
caps.nonFillPolygonMode = physDevFeatures.fillModeNonSolid;
#ifdef VK_VERSION_1_2
- caps.multiView = caps.apiVersion >= QVersionNumber(1, 1) && physDevFeatures11.multiview;
+ if (caps.apiVersion >= QVersionNumber(1, 2))
+ caps.multiView = physDevFeatures11IfApi12OrNewer.multiview;
+#endif
+
+#ifdef VK_VERSION_1_1
+ if (caps.apiVersion == QVersionNumber(1, 1))
+ caps.multiView = multiviewFeaturesIfApi11.multiview;
#endif
if (!importedAllocator) {
diff --git a/src/gui/rhi/qrhivulkan_p.h b/src/gui/rhi/qrhivulkan_p.h
index 66e7882ad8..d2b91a424e 100644
--- a/src/gui/rhi/qrhivulkan_p.h
+++ b/src/gui/rhi/qrhivulkan_p.h
@@ -840,8 +840,11 @@ public:
QVulkanDeviceFunctions *df = nullptr;
QRhi::Flags rhiFlags;
VkPhysicalDeviceFeatures physDevFeatures;
+#ifdef VK_VERSION_1_1
+ VkPhysicalDeviceMultiviewFeatures multiviewFeaturesIfApi11;
+#endif
#ifdef VK_VERSION_1_2
- VkPhysicalDeviceVulkan11Features physDevFeatures11;
+ VkPhysicalDeviceVulkan11Features physDevFeatures11IfApi12OrNewer;
VkPhysicalDeviceVulkan12Features physDevFeatures12;
#endif
#ifdef VK_VERSION_1_3