From 7d378bd7804343652fdf1e28744523382280e90e Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Thu, 14 Jan 2021 17:42:47 +0100 Subject: vulkan: Add instance-level version getter ...as described in the Vulkan >= 1.1 spec. One can now call supportedApiVersion() (before create(), similarly to the other supported* functions) to determine the available Vulkan (instance-level) version. Fixes: QTBUG-90333 Change-Id: Ibe8482402b7f07e4abc48c88252ff0365e4e2faa Reviewed-by: Andy Nichols --- src/gui/vulkan/qbasicvulkanplatforminstance.cpp | 24 +++++++++++++++++ src/gui/vulkan/qbasicvulkanplatforminstance_p.h | 2 ++ src/gui/vulkan/qplatformvulkaninstance.h | 1 + src/gui/vulkan/qvulkaninstance.cpp | 34 ++++++++++++++++++++++--- src/gui/vulkan/qvulkaninstance.h | 1 + 5 files changed, 59 insertions(+), 3 deletions(-) (limited to 'src/gui') diff --git a/src/gui/vulkan/qbasicvulkanplatforminstance.cpp b/src/gui/vulkan/qbasicvulkanplatforminstance.cpp index 01d6179166..abb17e9d6d 100644 --- a/src/gui/vulkan/qbasicvulkanplatforminstance.cpp +++ b/src/gui/vulkan/qbasicvulkanplatforminstance.cpp @@ -135,6 +135,25 @@ void QBasicPlatformVulkanInstance::init(QLibrary *lib) return; } + // Do not rely on non-1.0 header typedefs here. + typedef VkResult (VKAPI_PTR *T_enumerateInstanceVersion)(uint32_t* pApiVersion); + // Determine instance-level version as described in the Vulkan 1.2 spec. + T_enumerateInstanceVersion enumerateInstanceVersion = reinterpret_cast( + m_vkGetInstanceProcAddr(VK_NULL_HANDLE, "vkEnumerateInstanceVersion")); + if (enumerateInstanceVersion) { + uint32_t ver = 0; + if (enumerateInstanceVersion(&ver) == VK_SUCCESS) { + m_supportedApiVersion = QVersionNumber(VK_VERSION_MAJOR(ver), + VK_VERSION_MINOR(ver), + VK_VERSION_PATCH(ver)); + } else { + m_supportedApiVersion = QVersionNumber(1, 0, 0); + } + } else { + // Vulkan 1.0 + m_supportedApiVersion = QVersionNumber(1, 0, 0); + } + uint32_t layerCount = 0; m_vkEnumerateInstanceLayerProperties(&layerCount, nullptr); if (layerCount) { @@ -180,6 +199,11 @@ QVulkanInfoVector QBasicPlatformVulkanInstance::supportedExten return m_supportedExtensions; } +QVersionNumber QBasicPlatformVulkanInstance::supportedApiVersion() const +{ + return m_supportedApiVersion; +} + void QBasicPlatformVulkanInstance::initInstance(QVulkanInstance *instance, const QByteArrayList &extraExts) { if (!m_vkGetInstanceProcAddr) { diff --git a/src/gui/vulkan/qbasicvulkanplatforminstance_p.h b/src/gui/vulkan/qbasicvulkanplatforminstance_p.h index 8c01af2a8f..39ce71b4d3 100644 --- a/src/gui/vulkan/qbasicvulkanplatforminstance_p.h +++ b/src/gui/vulkan/qbasicvulkanplatforminstance_p.h @@ -68,6 +68,7 @@ public: QVulkanInfoVector supportedLayers() const override; QVulkanInfoVector supportedExtensions() const override; + QVersionNumber supportedApiVersion() const override; bool isValid() const override; VkResult errorCode() const override; VkInstance vkInstance() const override; @@ -99,6 +100,7 @@ private: VkResult m_errorCode; QVulkanInfoVector m_supportedLayers; QVulkanInfoVector m_supportedExtensions; + QVersionNumber m_supportedApiVersion; QByteArrayList m_enabledLayers; QByteArrayList m_enabledExtensions; diff --git a/src/gui/vulkan/qplatformvulkaninstance.h b/src/gui/vulkan/qplatformvulkaninstance.h index d9c219198f..b918632b57 100644 --- a/src/gui/vulkan/qplatformvulkaninstance.h +++ b/src/gui/vulkan/qplatformvulkaninstance.h @@ -69,6 +69,7 @@ public: virtual QVulkanInfoVector supportedLayers() const = 0; virtual QVulkanInfoVector supportedExtensions() const = 0; + virtual QVersionNumber supportedApiVersion() const = 0; virtual void createOrAdoptInstance() = 0; virtual bool isValid() const = 0; virtual VkResult errorCode() const = 0; diff --git a/src/gui/vulkan/qvulkaninstance.cpp b/src/gui/vulkan/qvulkaninstance.cpp index 31f971b570..e0f1b1a5f3 100644 --- a/src/gui/vulkan/qvulkaninstance.cpp +++ b/src/gui/vulkan/qvulkaninstance.cpp @@ -447,6 +447,28 @@ QVulkanInfoVector QVulkanInstance::supportedExtensions() return d_ptr->ensureVulkan() ? d_ptr->platformInst->supportedExtensions() : QVulkanInfoVector(); } +/*! + \return the version of instance-level functionality supported by the Vulkan + implementation. + + In practice this is either the value returned from + vkEnumerateInstanceVersion, if that function is available (with Vulkan 1.1 + and newer), or 1.0. + + Applications that want to branch in their Vulkan feature and API usage + based on what Vulkan version is available at run time, can use this function + to determine what version to pass in to setApiVersion() before calling + create(). + + \note This function can be called before create(). + + \sa setApiVersion() + */ +QVersionNumber QVulkanInstance::supportedApiVersion() +{ + return d_ptr->ensureVulkan() ? d_ptr->platformInst->supportedApiVersion() : QVersionNumber(); +} + /*! Makes QVulkanInstance adopt an existing VkInstance handle instead of creating a new one. @@ -524,10 +546,9 @@ void QVulkanInstance::setExtensions(const QByteArrayList &extensions) } /*! - Specifies the Vulkan API against which the application expects to run. + Specifies the highest Vulkan API version the application is designed to use. - By default no \a vulkanVersion is specified, and so no version check is performed - during Vulkan instance creation. + By default \a vulkanVersion is 0, which maps to Vulkan 1.0. \note This function can only be called before create() and has no effect if called afterwards. @@ -538,6 +559,13 @@ void QVulkanInstance::setExtensions(const QByteArrayList &extensions) as was mandated by the specification. Starting with Vulkan 1.1, the specification disallows this, the driver must accept any version without failing the instance creation. + + Application developers are advised to familiarize themselves with the \c + apiVersion notes in + \l{https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VkApplicationInfo.html}{the + Vulkan specification}. + + \sa supportedApiVersion() */ void QVulkanInstance::setApiVersion(const QVersionNumber &vulkanVersion) { diff --git a/src/gui/vulkan/qvulkaninstance.h b/src/gui/vulkan/qvulkaninstance.h index 58948854b4..3e597f9c87 100644 --- a/src/gui/vulkan/qvulkaninstance.h +++ b/src/gui/vulkan/qvulkaninstance.h @@ -176,6 +176,7 @@ public: QVulkanInfoVector supportedLayers(); QVulkanInfoVector supportedExtensions(); + QVersionNumber supportedApiVersion(); void setVkInstance(VkInstance existingVkInstance); -- cgit v1.2.3