mfplat: Read queue subscriber within the critical section.
[wine/zf.git] / dlls / vulkan-1 / tests / vulkan.c
blob9061b2b6db8712776da786324d5e8683910d157d
1 /*
2 * Copyright 2018 Józef Kucia for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #include "windows.h"
20 #include "wine/heap.h"
21 #include "wine/vulkan.h"
22 #include "wine/test.h"
24 static VkResult create_instance(uint32_t extension_count,
25 const char * const *enabled_extensions, VkInstance *vk_instance)
27 VkInstanceCreateInfo create_info;
29 create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
30 create_info.pNext = NULL;
31 create_info.flags = 0;
32 create_info.pApplicationInfo = NULL;
33 create_info.enabledLayerCount = 0;
34 create_info.ppEnabledLayerNames = NULL;
35 create_info.enabledExtensionCount = extension_count;
36 create_info.ppEnabledExtensionNames = enabled_extensions;
38 return vkCreateInstance(&create_info, NULL, vk_instance);
41 #define create_instance_skip(a, b, c) create_instance_skip_(__LINE__, a, b, c)
42 static VkResult create_instance_skip_(unsigned int line, uint32_t extension_count,
43 const char * const *enabled_extensions, VkInstance *vk_instance)
45 VkResult vr;
47 if ((vr = create_instance(extension_count, enabled_extensions, vk_instance)) >= 0)
48 return vr;
50 switch (vr)
52 case VK_ERROR_EXTENSION_NOT_PRESENT:
53 if (extension_count == 1)
54 skip_(__FILE__, line)("Instance extension '%s' not supported.\n", enabled_extensions[0]);
55 else
56 skip_(__FILE__, line)("Instance extensions not supported.\n");
57 break;
59 default:
60 skip_(__FILE__, line)("Failed to create Vulkan instance, vr %d.\n", vr);
61 break;
64 return vr;
67 static VkBool32 find_queue_family(VkPhysicalDevice vk_physical_device,
68 VkQueueFlags flags, uint32_t *family_index)
70 VkQueueFamilyProperties *properties;
71 VkBool32 ret = VK_FALSE;
72 uint32_t i, count;
74 vkGetPhysicalDeviceQueueFamilyProperties(vk_physical_device, &count, NULL);
75 properties = heap_calloc(count, sizeof(*properties));
76 ok(!!properties, "Failed to allocate memory.\n");
77 vkGetPhysicalDeviceQueueFamilyProperties(vk_physical_device, &count, properties);
79 for (i = 0; i < count; ++i)
81 if ((properties[i].queueFlags & flags) == flags)
83 ret = VK_TRUE;
84 *family_index = i;
85 break;
89 heap_free(properties);
90 return ret;
93 static VkResult create_device(VkPhysicalDevice vk_physical_device,
94 uint32_t extension_count, const char * const *enabled_extensions,
95 const void *next, VkDevice *vk_device)
97 VkDeviceQueueCreateInfo queue_info;
98 VkDeviceCreateInfo create_info;
99 float priority = 0.0f;
101 queue_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
102 queue_info.pNext = NULL;
103 queue_info.flags = 0;
104 if (!find_queue_family(vk_physical_device, VK_QUEUE_GRAPHICS_BIT, &queue_info.queueFamilyIndex))
106 trace("Failed to find queue family.\n");
107 return VK_ERROR_INITIALIZATION_FAILED;
109 queue_info.queueCount = 1;
110 queue_info.pQueuePriorities = &priority;
112 create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
113 create_info.pNext = next;
114 create_info.flags = 0;
115 create_info.queueCreateInfoCount = 1;
116 create_info.pQueueCreateInfos = &queue_info;
117 create_info.enabledLayerCount = 0;
118 create_info.ppEnabledLayerNames = NULL;
119 create_info.enabledExtensionCount = extension_count;
120 create_info.ppEnabledExtensionNames = enabled_extensions;
121 create_info.pEnabledFeatures = NULL;
123 return vkCreateDevice(vk_physical_device, &create_info, NULL, vk_device);
126 static void test_instance_version(void)
128 PFN_vkEnumerateInstanceVersion pfn_vkEnumerateInstanceVersion;
129 uint32_t version;
130 VkResult vr;
132 pfn_vkEnumerateInstanceVersion = (PFN_vkEnumerateInstanceVersion)vkGetInstanceProcAddr(
133 NULL, "vkEnumerateInstanceVersion");
134 if (!pfn_vkEnumerateInstanceVersion)
136 skip("vkEnumerateInstanceVersion() is not available.\n");
137 return;
140 vr = pfn_vkEnumerateInstanceVersion(&version);
141 ok(vr == VK_SUCCESS, "Got unexpected VkResult %d.\n", vr);
142 ok(version >= VK_API_VERSION_1_0, "Invalid version %#x.\n", version);
143 trace("Vulkan version %u.%u.%u.\n",
144 VK_VERSION_MAJOR(version), VK_VERSION_MINOR(version), VK_VERSION_PATCH(version));
147 static void enumerate_physical_device(VkPhysicalDevice vk_physical_device)
149 VkPhysicalDeviceProperties properties;
151 vkGetPhysicalDeviceProperties(vk_physical_device, &properties);
153 trace("Device '%s', %#x:%#x, driver version %u.%u.%u (%#x), api version %u.%u.%u.\n",
154 properties.deviceName, properties.vendorID, properties.deviceID,
155 VK_VERSION_MAJOR(properties.driverVersion), VK_VERSION_MINOR(properties.driverVersion),
156 VK_VERSION_PATCH(properties.driverVersion), properties.driverVersion,
157 VK_VERSION_MAJOR(properties.apiVersion), VK_VERSION_MINOR(properties.apiVersion),
158 VK_VERSION_PATCH(properties.apiVersion));
161 static void test_enumerate_physical_device2(void)
163 static const char *procs[] = {"vkGetPhysicalDeviceProperties2", "vkGetPhysicalDeviceProperties2KHR"};
164 static const char *extensions[] = {VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME};
165 PFN_vkGetPhysicalDeviceProperties2 pfn_vkGetPhysicalDeviceProperties2;
166 VkPhysicalDeviceProperties2 properties2;
167 VkPhysicalDevice *vk_physical_devices;
168 VkPhysicalDeviceIDProperties id;
169 VkInstance vk_instance;
170 unsigned int i, j;
171 const LUID *luid;
172 uint32_t count;
173 VkResult vr;
175 if ((vr = create_instance_skip(ARRAY_SIZE(extensions), extensions, &vk_instance)) < 0)
176 return;
177 ok(vr == VK_SUCCESS, "Got unexpected VkResult %d.\n", vr);
179 vr = vkEnumeratePhysicalDevices(vk_instance, &count, NULL);
180 if (vr || !count)
182 skip("No physical devices. VkResult %d.\n", vr);
183 vkDestroyInstance(vk_instance, NULL);
184 return;
187 vk_physical_devices = heap_calloc(count, sizeof(*vk_physical_devices));
188 ok(!!vk_physical_devices, "Failed to allocate memory.\n");
189 vr = vkEnumeratePhysicalDevices(vk_instance, &count, vk_physical_devices);
190 ok(vr == VK_SUCCESS, "Got unexpected VkResult %d.\n", vr);
192 for (i = 0; i < ARRAY_SIZE(procs); ++i)
194 pfn_vkGetPhysicalDeviceProperties2
195 = (PFN_vkGetPhysicalDeviceProperties2)vkGetInstanceProcAddr(vk_instance, procs[i]);
196 if (!pfn_vkGetPhysicalDeviceProperties2)
198 skip("%s is not available.\n", procs[i]);
199 continue;
202 for (j = 0; j < count; ++j)
204 properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
205 properties2.pNext = &id;
207 memset(&id, 0, sizeof(id));
208 id.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES;
210 pfn_vkGetPhysicalDeviceProperties2(vk_physical_devices[j], &properties2);
211 luid = (const LUID *)id.deviceLUID;
212 trace("Device '%s', device UUID: %s, driver UUID: %s, device LUID: %08x:%08x.\n",
213 properties2.properties.deviceName, wine_dbgstr_guid((const GUID *)id.deviceUUID),
214 wine_dbgstr_guid((const GUID *)id.driverUUID), luid->HighPart, luid->LowPart);
215 ok(id.deviceLUIDValid == VK_TRUE, "Expected valid device LUID.\n");
216 /* If deviceLUIDValid is VK_TRUE, deviceNodeMask must contain exactly one bit according
217 * to the Vulkan specification */
218 ok(id.deviceNodeMask && !(id.deviceNodeMask & (id.deviceNodeMask - 1)),
219 "Expect deviceNodeMask to have only one bit set, got %#x.\n", id.deviceNodeMask);
223 heap_free(vk_physical_devices);
224 vkDestroyInstance(vk_instance, NULL);
227 static void enumerate_device_queues(VkPhysicalDevice vk_physical_device)
229 VkPhysicalDeviceProperties device_properties;
230 VkQueueFamilyProperties *properties;
231 uint32_t i, count;
233 vkGetPhysicalDeviceProperties(vk_physical_device, &device_properties);
235 vkGetPhysicalDeviceQueueFamilyProperties(vk_physical_device, &count, NULL);
236 properties = heap_calloc(count, sizeof(*properties));
237 ok(!!properties, "Failed to allocate memory.\n");
238 vkGetPhysicalDeviceQueueFamilyProperties(vk_physical_device, &count, properties);
240 for (i = 0; i < count; ++i)
242 trace("Device '%s', queue family %u: flags %#x count %u.\n",
243 device_properties.deviceName, i, properties[i].queueFlags, properties[i].queueCount);
246 heap_free(properties);
249 static void test_physical_device_groups(void)
251 PFN_vkEnumeratePhysicalDeviceGroupsKHR vkEnumeratePhysicalDeviceGroupsKHR;
252 VkPhysicalDeviceGroupProperties *properties;
253 VkDeviceGroupDeviceCreateInfo group_info;
254 VkInstance vk_instance;
255 uint32_t i, j, count;
256 VkDevice vk_device;
257 VkResult vr;
259 static const char *extensions[] =
261 VK_KHR_DEVICE_GROUP_CREATION_EXTENSION_NAME,
264 if ((vr = create_instance_skip(ARRAY_SIZE(extensions), extensions, &vk_instance)) < 0)
265 return;
266 ok(vr == VK_SUCCESS, "Got unexpected VkResult %d.\n", vr);
268 vkEnumeratePhysicalDeviceGroupsKHR
269 = (void *)vkGetInstanceProcAddr(vk_instance, "vkEnumeratePhysicalDeviceGroupsKHR");
270 ok(!!vkEnumeratePhysicalDeviceGroupsKHR, "Failed to get proc addr.\n");
272 vr = vkEnumeratePhysicalDeviceGroupsKHR(vk_instance, &count, NULL);
273 ok(vr == VK_SUCCESS, "Got unexpected VkResult %d.\n", vr);
274 ok(count > 0, "Unexpected device group count %u.\n", count);
276 properties = heap_calloc(count, sizeof(*properties));
277 ok(!!properties, "Failed to allocate memory.\n");
278 vr = vkEnumeratePhysicalDeviceGroupsKHR(vk_instance, &count, properties);
279 ok(vr == VK_SUCCESS, "Got unexpected VkResult %d.\n", vr);
281 for (i = 0; i < count; ++i)
283 trace("Group[%u] count %u, subset allocation %#x\n",
284 i, properties[i].physicalDeviceCount, properties[i].subsetAllocation);
285 for (j = 0; j < properties[i].physicalDeviceCount; ++j)
286 enumerate_physical_device(properties[i].physicalDevices[j]);
289 if ((vr = create_device(properties->physicalDevices[0], 0, NULL, NULL, &vk_device)) < 0)
291 skip("Failed to create device, vr %d.\n", vr);
292 return;
294 ok(vr == VK_SUCCESS, "Got unexpected VkResult %d.\n", vr);
295 vkDestroyDevice(vk_device, NULL);
297 group_info.sType = VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO;
298 group_info.pNext = NULL;
299 group_info.physicalDeviceCount = properties->physicalDeviceCount;
300 group_info.pPhysicalDevices = properties->physicalDevices;
301 vr = create_device(group_info.pPhysicalDevices[0], 0, NULL, &group_info, &vk_device);
302 ok(vr == VK_SUCCESS, "Failed to create device, VkResult %d.\n", vr);
303 vkDestroyDevice(vk_device, NULL);
305 heap_free(properties);
307 vkDestroyInstance(vk_instance, NULL);
310 static void test_destroy_command_pool(VkPhysicalDevice vk_physical_device)
312 VkCommandBufferAllocateInfo allocate_info;
313 VkCommandPoolCreateInfo pool_info;
314 VkCommandBuffer vk_cmd_buffers[4];
315 uint32_t queue_family_index;
316 VkCommandPool vk_cmd_pool;
317 VkDevice vk_device;
318 VkResult vr;
320 if ((vr = create_device(vk_physical_device, 0, NULL, NULL, &vk_device)) < 0)
322 skip("Failed to create device, vr %d.\n", vr);
323 return;
326 find_queue_family(vk_physical_device, VK_QUEUE_GRAPHICS_BIT, &queue_family_index);
328 pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
329 pool_info.pNext = NULL;
330 pool_info.flags = 0;
331 pool_info.queueFamilyIndex = queue_family_index;
332 vr = vkCreateCommandPool(vk_device, &pool_info, NULL, &vk_cmd_pool);
333 ok(vr == VK_SUCCESS, "Got unexpected VkResult %d.\n", vr);
335 allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
336 allocate_info.pNext = NULL;
337 allocate_info.commandPool = vk_cmd_pool;
338 allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
339 allocate_info.commandBufferCount = ARRAY_SIZE(vk_cmd_buffers);
340 vr = vkAllocateCommandBuffers(vk_device, &allocate_info, vk_cmd_buffers);
341 ok(vr == VK_SUCCESS, "Got unexpected VkResult %d.\n", vr);
343 vkDestroyCommandPool(vk_device, vk_cmd_pool, NULL);
344 vkDestroyCommandPool(vk_device, VK_NULL_HANDLE, NULL);
346 vkDestroyDevice(vk_device, NULL);
349 static void test_unsupported_instance_extensions(void)
351 VkInstance vk_instance;
352 unsigned int i;
353 VkResult vr;
355 static const char *extensions[] =
357 "VK_KHR_xcb_surface",
358 "VK_KHR_xlib_surface",
361 for (i = 0; i < ARRAY_SIZE(extensions); ++i)
363 vr = create_instance(1, &extensions[i], &vk_instance);
364 ok(vr == VK_ERROR_EXTENSION_NOT_PRESENT,
365 "Got VkResult %d for extension %s.\n", vr, extensions[i]);
369 static void test_unsupported_device_extensions(VkPhysicalDevice vk_physical_device)
371 VkDevice vk_device;
372 unsigned int i;
373 VkResult vr;
375 static const char *extensions[] =
377 "VK_KHR_external_fence_fd",
378 "VK_KHR_external_memory_fd",
379 "VK_KHR_external_semaphore_fd",
382 for (i = 0; i < ARRAY_SIZE(extensions); ++i)
384 vr = create_device(vk_physical_device, 1, &extensions[i], NULL, &vk_device);
385 ok(vr == VK_ERROR_EXTENSION_NOT_PRESENT,
386 "Got VkResult %d for extension %s.\n", vr, extensions[i]);
390 static void test_private_data(VkPhysicalDevice vk_physical_device)
392 PFN_vkDestroyPrivateDataSlotEXT pfn_vkDestroyPrivateDataSlotEXT;
393 PFN_vkCreatePrivateDataSlotEXT pfn_vkCreatePrivateDataSlotEXT;
394 VkPrivateDataSlotCreateInfoEXT data_create_info;
395 PFN_vkGetPrivateDataEXT pfn_vkGetPrivateDataEXT;
396 PFN_vkSetPrivateDataEXT pfn_vkSetPrivateDataEXT;
397 VkPrivateDataSlotEXT data_slot;
398 VkDevice vk_device;
399 uint64_t data;
400 VkResult vr;
402 static const uint64_t data_value = 0x70AD;
404 static const char *ext_name = "VK_EXT_private_data";
406 if ((vr = create_device(vk_physical_device, 1, &ext_name, NULL, &vk_device)) < 0)
408 skip("Failed to create device with VK_EXT_private_data, VkResult %d.\n", vr);
409 return;
412 pfn_vkDestroyPrivateDataSlotEXT =
413 (void*) vkGetDeviceProcAddr(vk_device, "vkDestroyPrivateDataSlotEXT");
414 pfn_vkCreatePrivateDataSlotEXT =
415 (void*) vkGetDeviceProcAddr(vk_device, "vkCreatePrivateDataSlotEXT");
416 pfn_vkGetPrivateDataEXT =
417 (void*) vkGetDeviceProcAddr(vk_device, "vkGetPrivateDataEXT");
418 pfn_vkSetPrivateDataEXT =
419 (void*) vkGetDeviceProcAddr(vk_device, "vkSetPrivateDataEXT");
421 data_create_info.sType = VK_STRUCTURE_TYPE_PRIVATE_DATA_SLOT_CREATE_INFO_EXT;
422 data_create_info.pNext = NULL;
423 data_create_info.flags = 0;
424 vr = pfn_vkCreatePrivateDataSlotEXT(vk_device, &data_create_info, NULL, &data_slot);
425 ok(vr == VK_SUCCESS, "Failed to create private data slot, VkResult %d.\n", vr);
427 vr = pfn_vkSetPrivateDataEXT(vk_device, VK_OBJECT_TYPE_DEVICE,
428 (uint64_t) (uintptr_t) vk_device, data_slot, data_value);
429 ok(vr == VK_SUCCESS, "Failed to set private data, VkResult %d.\n", vr);
431 pfn_vkGetPrivateDataEXT(vk_device, VK_OBJECT_TYPE_DEVICE,
432 (uint64_t) (uintptr_t) vk_device, data_slot, &data);
433 ok(data == data_value, "Got unexpected private data, %s.\n",
434 wine_dbgstr_longlong(data));
436 pfn_vkDestroyPrivateDataSlotEXT(vk_device, data_slot, NULL);
437 vkDestroyDevice(vk_device, NULL);
440 static void for_each_device(void (*test_func)(VkPhysicalDevice))
442 VkPhysicalDevice *vk_physical_devices;
443 VkInstance vk_instance;
444 unsigned int i;
445 uint32_t count;
446 VkResult vr;
448 if ((vr = create_instance_skip(0, NULL, &vk_instance)) < 0)
449 return;
450 ok(vr == VK_SUCCESS, "Got unexpected VkResult %d.\n", vr);
452 vr = vkEnumeratePhysicalDevices(vk_instance, &count, NULL);
453 if (vr || !count)
455 skip("No physical devices. VkResult %d.\n", vr);
456 vkDestroyInstance(vk_instance, NULL);
457 return;
460 vk_physical_devices = heap_calloc(count, sizeof(*vk_physical_devices));
461 ok(!!vk_physical_devices, "Failed to allocate memory.\n");
462 vr = vkEnumeratePhysicalDevices(vk_instance, &count, vk_physical_devices);
463 ok(vr == VK_SUCCESS, "Got unexpected VkResult %d.\n", vr);
465 for (i = 0; i < count; ++i)
466 test_func(vk_physical_devices[i]);
468 heap_free(vk_physical_devices);
470 vkDestroyInstance(vk_instance, NULL);
473 START_TEST(vulkan)
475 test_instance_version();
476 for_each_device(enumerate_physical_device);
477 test_enumerate_physical_device2();
478 for_each_device(enumerate_device_queues);
479 test_physical_device_groups();
480 for_each_device(test_destroy_command_pool);
481 test_unsupported_instance_extensions();
482 for_each_device(test_unsupported_device_extensions);
483 for_each_device(test_private_data);