summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gui/vulkan/qbasicvulkanplatforminstance.cpp24
-rw-r--r--src/gui/vulkan/qbasicvulkanplatforminstance_p.h2
-rw-r--r--src/gui/vulkan/qplatformvulkaninstance.h1
-rw-r--r--src/gui/vulkan/qvulkaninstance.cpp34
-rw-r--r--src/gui/vulkan/qvulkaninstance.h1
-rw-r--r--tests/auto/gui/qvulkan/tst_qvulkan.cpp16
6 files changed, 73 insertions, 5 deletions
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<T_enumerateInstanceVersion>(
+ 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<QVulkanExtension> 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<QVulkanLayer> supportedLayers() const override;
QVulkanInfoVector<QVulkanExtension> 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<QVulkanLayer> m_supportedLayers;
QVulkanInfoVector<QVulkanExtension> 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<QVulkanLayer> supportedLayers() const = 0;
virtual QVulkanInfoVector<QVulkanExtension> 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
@@ -448,6 +448,28 @@ QVulkanInfoVector<QVulkanExtension> QVulkanInstance::supportedExtensions()
}
/*!
+ \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<QVulkanLayer> supportedLayers();
QVulkanInfoVector<QVulkanExtension> supportedExtensions();
+ QVersionNumber supportedApiVersion();
void setVkInstance(VkInstance existingVkInstance);
diff --git a/tests/auto/gui/qvulkan/tst_qvulkan.cpp b/tests/auto/gui/qvulkan/tst_qvulkan.cpp
index 020448af8b..82183c395c 100644
--- a/tests/auto/gui/qvulkan/tst_qvulkan.cpp
+++ b/tests/auto/gui/qvulkan/tst_qvulkan.cpp
@@ -86,8 +86,8 @@ void tst_QVulkan::vulkanInstance()
void tst_QVulkan::vulkanCheckSupported()
{
- // Test the early calls to supportedLayers/extensions that need the library
- // and some basics, but do not initialize the instance.
+ // Test the early calls to supportedLayers/extensions/apiVersion that need
+ // the library and some basics, but do not initialize the instance.
QVulkanInstance inst;
QVERIFY(!inst.isValid());
@@ -103,6 +103,9 @@ void tst_QVulkan::vulkanCheckSupported()
QVERIFY(!ve.isEmpty());
QVERIFY(ve == inst.supportedExtensions());
}
+
+ qDebug() << inst.supportedApiVersion();
+ QVERIFY(inst.supportedApiVersion().majorVersion() >= 1);
}
void tst_QVulkan::vulkanPlainWindow()
@@ -162,6 +165,15 @@ void tst_QVulkan::vulkanVersionRequest()
// succeed for any bogus api version).
if (!result)
QCOMPARE(inst.errorCode(), VK_ERROR_INCOMPATIBLE_DRIVER);
+
+ inst.destroy();
+
+ // Verify that specifying the version returned from supportedApiVersion
+ // (either 1.0.0 or what vkEnumerateInstanceVersion returns in Vulkan 1.1+)
+ // leads to successful instance creation.
+ inst.setApiVersion(inst.supportedApiVersion());
+ result = inst.create();
+ QVERIFY(result);
}
static void waitForUnexposed(QWindow *w)