summaryrefslogtreecommitdiffstats
path: root/tests/auto/gui/qvulkan
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2021-01-14 16:40:14 +0100
committerLaszlo Agocs <laszlo.agocs@qt.io>2021-01-19 14:17:55 +0100
commitc6d602990901bb44b9268b1603b25d3c76c97683 (patch)
tree23a5cc95fa7e3bb9f0a8b22dd722da1a252b2c2b /tests/auto/gui/qvulkan
parent12d8bb0709bf7982061cb0c3e608e4a581892e35 (diff)
Update QVulkan(Device)Functions to Vulkan 1.2
This also needs improvements to qvkgen. What we get with this patch are the Vulkan 1.1 and 1.2 core API's additional 11 instance-level and 30 device-level commands present in QVulkanFunctions and QVulkanDeviceFunctions. All of these are attempted to be resolved upon construction. When the implementation does not return a valid function pointer for some of them (e.g. because it is a Vulkan 1.0 instance or physical device), calling the corresponding wrapper functions will lead to unspecified behavior. This is in line with how QOpenGLExtraFunctions works. The simple autotest added to exercise some Vulkan 1.1 APIs demonstrates this in action. The member functions in the generated qvulkan(device)functions header and source files are ifdefed by VK_VERSION_1_{0,1,2}. This is essential because otherwise a Qt build made on a system with Vulkan 1.2 headers would cause compilation breaks in application build environments with Vulkan 1.0/1.1 headers when including qvulkanfunctions.h (due to missing the 1.1/1.2 types and constants, some of which are used in the function prototypes). In practice this should be alright - the only caveat to keep in mind is that the Qt builds meant to be distributed to a wide variety of systems need to be made with a sufficiently new version of the Vulkan headers installed, just to ensure that the 1.1 and 1.2 wrapper functions are compiled into the Qt libraries. Task-number: QTBUG-90219 Change-Id: I48360a8a2e915d2709fe82993f65e99b2ccd5d53 Reviewed-by: Andy Nichols <andy.nichols@qt.io>
Diffstat (limited to 'tests/auto/gui/qvulkan')
-rw-r--r--tests/auto/gui/qvulkan/tst_qvulkan.cpp73
1 files changed, 73 insertions, 0 deletions
diff --git a/tests/auto/gui/qvulkan/tst_qvulkan.cpp b/tests/auto/gui/qvulkan/tst_qvulkan.cpp
index 82183c395c..5b425158f9 100644
--- a/tests/auto/gui/qvulkan/tst_qvulkan.cpp
+++ b/tests/auto/gui/qvulkan/tst_qvulkan.cpp
@@ -43,6 +43,7 @@ private slots:
void vulkanCheckSupported();
void vulkanPlainWindow();
void vulkanVersionRequest();
+ void vulkan11();
void vulkanWindow();
void vulkanWindowRenderer();
void vulkanWindowGrab();
@@ -108,6 +109,78 @@ void tst_QVulkan::vulkanCheckSupported()
QVERIFY(inst.supportedApiVersion().majorVersion() >= 1);
}
+void tst_QVulkan::vulkan11()
+{
+#if VK_VERSION_1_1
+ QVulkanInstance inst;
+ if (inst.supportedApiVersion() < QVersionNumber(1, 1))
+ QSKIP("Vulkan 1.1 is not supported by the VkInstance; skip");
+
+ inst.setApiVersion(QVersionNumber(1, 1));
+ if (!inst.create())
+ QSKIP("Vulkan 1.1 instance creation failed; skip");
+
+ QCOMPARE(inst.errorCode(), VK_SUCCESS);
+
+ // exercise some 1.1 commands
+ QVulkanFunctions *f = inst.functions();
+ QVERIFY(f);
+ uint32_t count = 0;
+ VkResult err = f->vkEnumeratePhysicalDeviceGroups(inst.vkInstance(), &count, nullptr);
+ if (err != VK_SUCCESS)
+ QSKIP("No physical devices; skip");
+
+ if (count) {
+ QVarLengthArray<VkPhysicalDeviceGroupProperties, 4> groupProperties;
+ groupProperties.resize(count);
+ err = f->vkEnumeratePhysicalDeviceGroups(inst.vkInstance(), &count, groupProperties.data()); // 1.1 API
+ QCOMPARE(err, VK_SUCCESS);
+ for (const VkPhysicalDeviceGroupProperties &gp : groupProperties) {
+ QCOMPARE(gp.sType, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES);
+ for (uint32_t i = 0; i != gp.physicalDeviceCount; ++i) {
+ VkPhysicalDevice physDev = gp.physicalDevices[i];
+
+ // Instance and physical device apiVersion are two different things.
+ VkPhysicalDeviceProperties props;
+ f->vkGetPhysicalDeviceProperties(physDev, &props);
+ QVersionNumber physDevVer(VK_VERSION_MAJOR(props.apiVersion),
+ VK_VERSION_MINOR(props.apiVersion),
+ VK_VERSION_PATCH(props.apiVersion));
+ qDebug() << "Physical device" << physDev << "apiVersion" << physDevVer;
+
+ if (physDevVer >= QVersionNumber(1, 1)) {
+ // Now that we ensured that we have an 1.1 capable instance and physical device,
+ // query something that was not in 1.0.
+ VkPhysicalDeviceIDProperties deviceIdProps = {}; // new in 1.1
+ deviceIdProps.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES;
+ VkPhysicalDeviceProperties2 props2 = {};
+ props2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
+ props2.pNext = &deviceIdProps;
+ f->vkGetPhysicalDeviceProperties2(physDev, &props2); // 1.1 API
+ QByteArray deviceUuid = QByteArray::fromRawData((const char *) deviceIdProps.deviceUUID, VK_UUID_SIZE).toHex();
+ QByteArray driverUuid = QByteArray::fromRawData((const char *) deviceIdProps.driverUUID, VK_UUID_SIZE).toHex();
+ qDebug() << "deviceUUID" << deviceUuid << "driverUUID" << driverUuid;
+ // deviceUUID cannot be all zero as per spec
+ bool seenNonZero = false;
+ for (int i = 0; i < VK_UUID_SIZE; ++i) {
+ if (deviceIdProps.deviceUUID[i]) {
+ seenNonZero = true;
+ break;
+ }
+ }
+ QVERIFY(seenNonZero);
+ } else {
+ qDebug("Physical device is not Vulkan 1.1 capable");
+ }
+ }
+ }
+ }
+
+#else
+ QSKIP("Vulkan header is not 1.1 capable; skip");
+#endif
+}
+
void tst_QVulkan::vulkanPlainWindow()
{
QVulkanInstance inst;