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 <andy.nichols@qt.io>
This commit is contained in:
parent
9573441236
commit
7d378bd780
@ -135,6 +135,25 @@ void QBasicPlatformVulkanInstance::init(QLibrary *lib)
|
|||||||
return;
|
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;
|
uint32_t layerCount = 0;
|
||||||
m_vkEnumerateInstanceLayerProperties(&layerCount, nullptr);
|
m_vkEnumerateInstanceLayerProperties(&layerCount, nullptr);
|
||||||
if (layerCount) {
|
if (layerCount) {
|
||||||
@ -180,6 +199,11 @@ QVulkanInfoVector<QVulkanExtension> QBasicPlatformVulkanInstance::supportedExten
|
|||||||
return m_supportedExtensions;
|
return m_supportedExtensions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QVersionNumber QBasicPlatformVulkanInstance::supportedApiVersion() const
|
||||||
|
{
|
||||||
|
return m_supportedApiVersion;
|
||||||
|
}
|
||||||
|
|
||||||
void QBasicPlatformVulkanInstance::initInstance(QVulkanInstance *instance, const QByteArrayList &extraExts)
|
void QBasicPlatformVulkanInstance::initInstance(QVulkanInstance *instance, const QByteArrayList &extraExts)
|
||||||
{
|
{
|
||||||
if (!m_vkGetInstanceProcAddr) {
|
if (!m_vkGetInstanceProcAddr) {
|
||||||
|
@ -68,6 +68,7 @@ public:
|
|||||||
|
|
||||||
QVulkanInfoVector<QVulkanLayer> supportedLayers() const override;
|
QVulkanInfoVector<QVulkanLayer> supportedLayers() const override;
|
||||||
QVulkanInfoVector<QVulkanExtension> supportedExtensions() const override;
|
QVulkanInfoVector<QVulkanExtension> supportedExtensions() const override;
|
||||||
|
QVersionNumber supportedApiVersion() const override;
|
||||||
bool isValid() const override;
|
bool isValid() const override;
|
||||||
VkResult errorCode() const override;
|
VkResult errorCode() const override;
|
||||||
VkInstance vkInstance() const override;
|
VkInstance vkInstance() const override;
|
||||||
@ -99,6 +100,7 @@ private:
|
|||||||
VkResult m_errorCode;
|
VkResult m_errorCode;
|
||||||
QVulkanInfoVector<QVulkanLayer> m_supportedLayers;
|
QVulkanInfoVector<QVulkanLayer> m_supportedLayers;
|
||||||
QVulkanInfoVector<QVulkanExtension> m_supportedExtensions;
|
QVulkanInfoVector<QVulkanExtension> m_supportedExtensions;
|
||||||
|
QVersionNumber m_supportedApiVersion;
|
||||||
QByteArrayList m_enabledLayers;
|
QByteArrayList m_enabledLayers;
|
||||||
QByteArrayList m_enabledExtensions;
|
QByteArrayList m_enabledExtensions;
|
||||||
|
|
||||||
|
@ -69,6 +69,7 @@ public:
|
|||||||
|
|
||||||
virtual QVulkanInfoVector<QVulkanLayer> supportedLayers() const = 0;
|
virtual QVulkanInfoVector<QVulkanLayer> supportedLayers() const = 0;
|
||||||
virtual QVulkanInfoVector<QVulkanExtension> supportedExtensions() const = 0;
|
virtual QVulkanInfoVector<QVulkanExtension> supportedExtensions() const = 0;
|
||||||
|
virtual QVersionNumber supportedApiVersion() const = 0;
|
||||||
virtual void createOrAdoptInstance() = 0;
|
virtual void createOrAdoptInstance() = 0;
|
||||||
virtual bool isValid() const = 0;
|
virtual bool isValid() const = 0;
|
||||||
virtual VkResult errorCode() const = 0;
|
virtual VkResult errorCode() const = 0;
|
||||||
|
@ -447,6 +447,28 @@ QVulkanInfoVector<QVulkanExtension> QVulkanInstance::supportedExtensions()
|
|||||||
return d_ptr->ensureVulkan() ? d_ptr->platformInst->supportedExtensions() : QVulkanInfoVector<QVulkanExtension>();
|
return d_ptr->ensureVulkan() ? d_ptr->platformInst->supportedExtensions() : QVulkanInfoVector<QVulkanExtension>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\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
|
Makes QVulkanInstance adopt an existing VkInstance handle instead of
|
||||||
creating a new one.
|
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
|
By default \a vulkanVersion is 0, which maps to Vulkan 1.0.
|
||||||
during Vulkan instance creation.
|
|
||||||
|
|
||||||
\note This function can only be called before create() and has no effect if
|
\note This function can only be called before create() and has no effect if
|
||||||
called afterwards.
|
called afterwards.
|
||||||
@ -538,6 +559,13 @@ void QVulkanInstance::setExtensions(const QByteArrayList &extensions)
|
|||||||
as was mandated by the specification. Starting with Vulkan 1.1, the
|
as was mandated by the specification. Starting with Vulkan 1.1, the
|
||||||
specification disallows this, the driver must accept any version without
|
specification disallows this, the driver must accept any version without
|
||||||
failing the instance creation.
|
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)
|
void QVulkanInstance::setApiVersion(const QVersionNumber &vulkanVersion)
|
||||||
{
|
{
|
||||||
|
@ -176,6 +176,7 @@ public:
|
|||||||
|
|
||||||
QVulkanInfoVector<QVulkanLayer> supportedLayers();
|
QVulkanInfoVector<QVulkanLayer> supportedLayers();
|
||||||
QVulkanInfoVector<QVulkanExtension> supportedExtensions();
|
QVulkanInfoVector<QVulkanExtension> supportedExtensions();
|
||||||
|
QVersionNumber supportedApiVersion();
|
||||||
|
|
||||||
void setVkInstance(VkInstance existingVkInstance);
|
void setVkInstance(VkInstance existingVkInstance);
|
||||||
|
|
||||||
|
@ -86,8 +86,8 @@ void tst_QVulkan::vulkanInstance()
|
|||||||
|
|
||||||
void tst_QVulkan::vulkanCheckSupported()
|
void tst_QVulkan::vulkanCheckSupported()
|
||||||
{
|
{
|
||||||
// Test the early calls to supportedLayers/extensions that need the library
|
// Test the early calls to supportedLayers/extensions/apiVersion that need
|
||||||
// and some basics, but do not initialize the instance.
|
// the library and some basics, but do not initialize the instance.
|
||||||
QVulkanInstance inst;
|
QVulkanInstance inst;
|
||||||
QVERIFY(!inst.isValid());
|
QVERIFY(!inst.isValid());
|
||||||
|
|
||||||
@ -103,6 +103,9 @@ void tst_QVulkan::vulkanCheckSupported()
|
|||||||
QVERIFY(!ve.isEmpty());
|
QVERIFY(!ve.isEmpty());
|
||||||
QVERIFY(ve == inst.supportedExtensions());
|
QVERIFY(ve == inst.supportedExtensions());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qDebug() << inst.supportedApiVersion();
|
||||||
|
QVERIFY(inst.supportedApiVersion().majorVersion() >= 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_QVulkan::vulkanPlainWindow()
|
void tst_QVulkan::vulkanPlainWindow()
|
||||||
@ -162,6 +165,15 @@ void tst_QVulkan::vulkanVersionRequest()
|
|||||||
// succeed for any bogus api version).
|
// succeed for any bogus api version).
|
||||||
if (!result)
|
if (!result)
|
||||||
QCOMPARE(inst.errorCode(), VK_ERROR_INCOMPATIBLE_DRIVER);
|
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)
|
static void waitForUnexposed(QWindow *w)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user