Skip to content

Commit

Permalink
rhi: vulkan: Query and enable multiview features when API is 1.1
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
alpqr committed Feb 2, 2024
1 parent 8c178a5 commit 90a9452
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 23 deletions.
93 changes: 71 additions & 22 deletions src/gui/rhi/qrhivulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down
5 changes: 4 additions & 1 deletion src/gui/rhi/qrhivulkan_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -840,8 +840,11 @@ class QRhiVulkan : public QRhiImplementation
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
Expand Down

0 comments on commit 90a9452

Please sign in to comment.