vkd3d-shader/hlsl: Use a block in hlsl_normalize_binary_exprs().
[vkd3d.git] / tests / vkd3d_api.c
blob756fbce77d0e4e35b78ae2a4d0b2f419521b81a7
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 /* Hack for MinGW-w64 headers.
21 * We want to use WIDL C inline wrappers because some methods
22 * in D3D12 interfaces return aggregate objects. Unfortunately,
23 * WIDL C inline wrappers are broken when used with MinGW-w64
24 * headers because FORCEINLINE expands to extern inline
25 * which leads to the "multiple storage classes in declaration
26 * specifiers" compiler error.
28 #ifdef __MINGW32__
29 # include <_mingw.h>
30 # ifdef __MINGW64_VERSION_MAJOR
31 # undef __forceinline
32 # define __forceinline __inline__ __attribute__((__always_inline__,__gnu_inline__))
33 # endif
34 #endif
36 #define VK_NO_PROTOTYPES
37 #define COBJMACROS
38 #define INITGUID
39 #define WIDL_C_INLINE_WRAPPERS
40 #include "vkd3d_test.h"
41 #include <vkd3d.h>
43 #include "d3d12_test_utils.h"
45 #define DECLARE_VK_PFN(name) static PFN_##name name;
46 DECLARE_VK_PFN(vkEnumerateInstanceExtensionProperties)
47 DECLARE_VK_PFN(vkGetInstanceProcAddr)
48 #define VK_INSTANCE_PFN DECLARE_VK_PFN
49 #define VK_DEVICE_PFN DECLARE_VK_PFN
50 #include "vulkan_procs.h"
52 HRESULT WINAPI D3D12SerializeRootSignature(const D3D12_ROOT_SIGNATURE_DESC *root_signature_desc,
53 D3D_ROOT_SIGNATURE_VERSION version, ID3DBlob **blob, ID3DBlob **error_blob)
55 return vkd3d_serialize_root_signature(root_signature_desc, version, blob, error_blob);
58 static void wait_queue_idle_(const char *file, unsigned int line, ID3D12Device *device, ID3D12CommandQueue *queue)
60 VkQueue vk_queue;
62 vk_queue = vkd3d_acquire_vk_queue(queue);
63 vkQueueWaitIdle(vk_queue);
64 vkd3d_release_vk_queue(queue);
67 static ULONG get_refcount(void *iface)
69 IUnknown *unk = iface;
70 IUnknown_AddRef(unk);
71 return IUnknown_Release(unk);
74 static ULONG resource_get_internal_refcount(ID3D12Resource *resource)
76 vkd3d_resource_incref(resource);
77 return vkd3d_resource_decref(resource);
80 static HRESULT signal_event(HANDLE event)
82 trace("Signal event %p.\n", event);
83 return S_OK;
86 static const struct vkd3d_application_info instance_default_application_info =
88 .type = VKD3D_STRUCTURE_TYPE_APPLICATION_INFO,
89 .api_version = VKD3D_API_VERSION_1_2,
92 static const struct vkd3d_instance_create_info instance_default_create_info =
94 .type = VKD3D_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
95 .next = &instance_default_application_info,
96 .wchar_size = sizeof(WCHAR),
97 .pfn_signal_event = signal_event,
100 static const struct vkd3d_device_create_info device_default_create_info =
102 .type = VKD3D_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
103 .minimum_feature_level = D3D_FEATURE_LEVEL_11_0,
104 .instance_create_info = &instance_default_create_info,
107 static ID3D12Device *create_device(void)
109 ID3D12Device *device;
110 HRESULT hr;
112 hr = vkd3d_create_device(&device_default_create_info,
113 &IID_ID3D12Device, (void **)&device);
114 return SUCCEEDED(hr) ? device : NULL;
117 static void test_create_instance(void)
119 struct vkd3d_instance_create_info create_info;
120 struct vkd3d_instance *instance;
121 ULONG refcount;
122 HRESULT hr;
124 create_info = instance_default_create_info;
125 hr = vkd3d_create_instance(&create_info, &instance);
126 ok(hr == S_OK, "Failed to create instance, hr %#x.\n", hr);
127 refcount = vkd3d_instance_incref(instance);
128 ok(refcount == 2, "Got unexpected refcount %u.\n", refcount);
129 vkd3d_instance_decref(instance);
130 refcount = vkd3d_instance_decref(instance);
131 ok(!refcount, "Instance has %u references left.\n", refcount);
133 create_info = instance_default_create_info;
134 create_info.wchar_size = 1;
135 hr = vkd3d_create_instance(&create_info, &instance);
136 ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
138 create_info = instance_default_create_info;
139 create_info.pfn_signal_event = NULL;
140 hr = vkd3d_create_instance(&create_info, &instance);
141 ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
143 create_info = instance_default_create_info;
144 create_info.pfn_vkGetInstanceProcAddr = vkGetInstanceProcAddr;
145 hr = vkd3d_create_instance(&create_info, &instance);
146 ok(hr == S_OK, "Failed to create instance, hr %#x.\n", hr);
147 refcount = vkd3d_instance_decref(instance);
148 ok(!refcount, "Instance has %u references left.\n", refcount);
151 struct vulkan_extension
153 const char *name;
154 bool is_supported;
157 static uint32_t check_extensions(const char **enabled_extensions,
158 struct vulkan_extension *extensions, unsigned int extension_count,
159 const VkExtensionProperties *properties, unsigned int count)
161 uint32_t enabled_extension_count = 0;
162 unsigned int i, j;
164 for (i = 0; i < count; ++i)
166 for (j = 0; j < extension_count; ++j)
168 if (!strcmp(properties[i].extensionName, extensions[j].name))
170 extensions[j].is_supported = true;
171 enabled_extensions[enabled_extension_count++] = extensions[j].name;
176 return enabled_extension_count;
179 static uint32_t check_instance_extensions(const char **enabled_extensions,
180 struct vulkan_extension *extensions, unsigned int extension_count)
182 VkExtensionProperties *properties;
183 uint32_t enabled_extension_count;
184 uint32_t count;
185 VkResult vr;
187 vr = vkEnumerateInstanceExtensionProperties(NULL, &count, NULL);
188 ok(vr == VK_SUCCESS, "Got unexpected VkResult %d.\n", vr);
189 if (!count)
190 return 0;
192 properties = calloc(count, sizeof(*properties));
193 ok(properties, "Failed to allocate memory.\n");
194 vr = vkEnumerateInstanceExtensionProperties(NULL, &count, properties);
195 ok(vr == VK_SUCCESS, "Got unexpected VkResult %d.\n", vr);
196 enabled_extension_count = check_extensions(enabled_extensions,
197 extensions, extension_count, properties, count);
198 free(properties);
199 return enabled_extension_count;
202 static uint32_t check_device_extensions(VkPhysicalDevice vk_physical_device,
203 const char **enabled_extensions, struct vulkan_extension *extensions,
204 unsigned int extension_count)
206 VkExtensionProperties *properties;
207 uint32_t enabled_extension_count;
208 uint32_t count;
209 VkResult vr;
211 vr = vkEnumerateDeviceExtensionProperties(vk_physical_device, NULL, &count, NULL);
212 ok(vr == VK_SUCCESS, "Got unexpected VkResult %d.\n", vr);
213 if (!count)
214 return 0;
216 properties = calloc(count, sizeof(*properties));
217 ok(properties, "Failed to allocate memory.\n");
218 vr = vkEnumerateDeviceExtensionProperties(vk_physical_device, NULL, &count, properties);
219 ok(vr == VK_SUCCESS, "Got unexpected VkResult %d.\n", vr);
220 enabled_extension_count = check_extensions(enabled_extensions,
221 extensions, extension_count, properties, count);
222 free(properties);
223 return enabled_extension_count;
226 static void test_additional_instance_extensions(void)
228 struct vulkan_extension extensions[] =
230 {VK_KHR_SURFACE_EXTENSION_NAME},
231 {"VK_KHR_xcb_surface"},
232 {"VK_KHR_xlib_surface"},
235 const char *enabled_extensions[ARRAY_SIZE(extensions)];
236 struct vkd3d_instance_create_info create_info;
237 struct vkd3d_instance *instance;
238 uint32_t extension_count;
239 PFN_vkVoidFunction pfn;
240 VkInstance vk_instance;
241 unsigned int i;
242 ULONG refcount;
243 HRESULT hr;
245 if (!(extension_count = check_instance_extensions(enabled_extensions,
246 extensions, ARRAY_SIZE(extensions))))
248 skip("Found 0 extensions.\n");
249 return;
252 create_info = instance_default_create_info;
253 create_info.instance_extensions = enabled_extensions;
254 create_info.instance_extension_count = extension_count;
255 hr = vkd3d_create_instance(&create_info, &instance);
256 ok(hr == S_OK, "Failed to create instance, hr %#x.\n", hr);
257 vk_instance = vkd3d_instance_get_vk_instance(instance);
258 ok(vk_instance != VK_NULL_HANDLE, "Failed to get Vulkan instance.\n");
260 for (i = 0; i < ARRAY_SIZE(extensions); ++i)
262 if (!extensions[i].is_supported)
263 continue;
265 if (!strcmp(extensions[i].name, "VK_KHR_xcb_surface"))
267 pfn = vkGetInstanceProcAddr(vk_instance, "vkCreateXcbSurfaceKHR");
268 ok(pfn, "Failed to get proc addr for vkCreateXcbSurfaceKHR.\n");
270 else if (!strcmp(extensions[i].name, "VK_KHR_xlib_surface"))
272 pfn = vkGetInstanceProcAddr(vk_instance, "vkCreateXlibSurfaceKHR");
273 ok(pfn, "Failed to get proc addr for vkCreateXlibSurfaceKHR.\n");
277 refcount = vkd3d_instance_decref(instance);
278 ok(!refcount, "Instance has %u references left.\n", refcount);
281 static void test_create_device(void)
283 struct vkd3d_instance *instance, *tmp_instance;
284 struct vkd3d_device_create_info create_info;
285 ID3D12Device *device;
286 ULONG refcount;
287 HRESULT hr;
289 hr = vkd3d_create_device(NULL, &IID_ID3D12Device, (void **)&device);
290 ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
292 create_info = device_default_create_info;
293 create_info.instance = NULL;
294 create_info.instance_create_info = NULL;
295 hr = vkd3d_create_device(&create_info, &IID_ID3D12Device, (void **)&device);
296 ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
298 create_info.instance_create_info = &instance_default_create_info;
299 hr = vkd3d_create_device(&create_info, &IID_ID3D12Device, (void **)&device);
300 ok(hr == S_OK, "Failed to create device, hr %#x.\n", hr);
301 refcount = ID3D12Device_Release(device);
302 ok(!refcount, "Device has %u references left.\n", refcount);
304 hr = vkd3d_create_instance(&instance_default_create_info, &instance);
305 ok(hr == S_OK, "Failed to create instance, hr %#x.\n", hr);
307 create_info.instance = instance;
308 create_info.instance_create_info = NULL;
309 hr = vkd3d_create_device(&create_info, &IID_ID3D12Device, (void **)&device);
310 ok(hr == S_OK, "Failed to create device, hr %#x.\n", hr);
311 refcount = vkd3d_instance_incref(instance);
312 ok(refcount >= 3, "Got unexpected refcount %u.\n", refcount);
313 vkd3d_instance_decref(instance);
314 tmp_instance = vkd3d_instance_from_device(device);
315 ok(tmp_instance == instance, "Got instance %p, expected %p.\n", tmp_instance, instance);
316 refcount = ID3D12Device_Release(device);
317 ok(!refcount, "Device has %u references left.\n", refcount);
319 create_info.instance = instance;
320 create_info.instance_create_info = &instance_default_create_info;
321 hr = vkd3d_create_device(&create_info, &IID_ID3D12Device, (void **)&device);
322 ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
324 refcount = vkd3d_instance_decref(instance);
325 ok(!refcount, "Instance has %u references left.\n", refcount);
328 static VkResult VKAPI_CALL fake_vkEnumerateDeviceExtensionProperties(
329 VkPhysicalDevice physical_device, const char *layer_name,
330 uint32_t *out_count, VkExtensionProperties *out_properties)
332 VkExtensionProperties *properties;
333 uint32_t count, i, j;
334 VkResult vr;
336 vr = vkEnumerateDeviceExtensionProperties(physical_device, layer_name, &count, NULL);
337 ok(vr == VK_SUCCESS, "Got unexpected VkResult %d.\n", vr);
338 if (!count)
340 *out_count = count;
341 return vr;
344 properties = calloc(count, sizeof(*properties));
345 ok(properties, "Failed to allocate memory.\n");
347 vr = vkEnumerateDeviceExtensionProperties(physical_device, layer_name, &count, properties);
348 ok(vr == VK_SUCCESS, "Got unexpected VkResult %d.\n", vr);
350 vr = VK_SUCCESS;
351 for (i = 0, j = 0; i < count; ++i)
353 /* Filter out VK_KHR_maintenance1. */
354 if (!strcmp(properties[i].extensionName, VK_KHR_MAINTENANCE1_EXTENSION_NAME))
355 continue;
357 if (out_properties)
359 if (j < *out_count)
360 out_properties[j] = properties[i];
361 else
362 vr = VK_INCOMPLETE;
365 ++j;
368 free(properties);
370 *out_count = j;
371 return vr;
374 static VkResult VKAPI_CALL fake_vkCreateDevice(VkPhysicalDevice physical_device,
375 const VkDeviceCreateInfo *create_info, const VkAllocationCallbacks *allocator,
376 VkDevice *device)
378 uint32_t i;
380 for (i = 0; i < create_info->enabledExtensionCount; ++i)
382 if (!strcmp(create_info->ppEnabledExtensionNames[i], VK_KHR_MAINTENANCE1_EXTENSION_NAME))
383 return VK_ERROR_EXTENSION_NOT_PRESENT;
386 return vkCreateDevice(physical_device, create_info, allocator, device);
389 static PFN_vkVoidFunction VKAPI_CALL fake_vkGetInstanceProcAddr(VkInstance instance,
390 const char *name)
392 if (!strcmp(name, "vkCreateDevice"))
393 return (PFN_vkVoidFunction)fake_vkCreateDevice;
394 if (!strcmp(name, "vkEnumerateDeviceExtensionProperties"))
395 return (PFN_vkVoidFunction)fake_vkEnumerateDeviceExtensionProperties;
397 return vkGetInstanceProcAddr(instance, name);
400 static void test_required_device_extensions(void)
402 struct vkd3d_instance_create_info instance_create_info;
403 struct vkd3d_device_create_info device_create_info;
404 struct vkd3d_instance *instance;
405 ID3D12Device *device;
406 ULONG refcount;
407 HRESULT hr;
409 instance_create_info = instance_default_create_info;
410 instance_create_info.pfn_vkGetInstanceProcAddr = fake_vkGetInstanceProcAddr;
411 hr = vkd3d_create_instance(&instance_create_info, &instance);
412 ok(hr == S_OK, "Failed to create instance, hr %#x.\n", hr);
414 device_create_info = device_default_create_info;
415 device_create_info.instance = instance;
416 device_create_info.instance_create_info = NULL;
417 hr = vkd3d_create_device(&device_create_info, &IID_ID3D12Device, (void **)&device);
418 ok(hr == E_FAIL, "Failed to create device, hr %#x.\n", hr);
420 refcount = vkd3d_instance_decref(instance);
421 ok(!refcount, "Instance has %u references left.\n", refcount);
424 static void test_additional_device_extensions(void)
426 struct vulkan_extension extensions[] =
428 {VK_KHR_SWAPCHAIN_EXTENSION_NAME},
431 struct vkd3d_instance_create_info instance_create_info;
432 const char *enabled_extensions[ARRAY_SIZE(extensions)];
433 struct vkd3d_device_create_info device_create_info;
434 VkPhysicalDevice vk_physical_device;
435 struct vkd3d_instance *instance;
436 uint32_t extension_count;
437 PFN_vkVoidFunction pfn;
438 VkInstance vk_instance;
439 ID3D12Device *device;
440 VkDevice vk_device;
441 uint32_t count;
442 ULONG refcount;
443 VkResult vr;
444 HRESULT hr;
446 /* Required by VK_KHR_swapchain. */
447 enabled_extensions[0] = VK_KHR_SURFACE_EXTENSION_NAME;
448 extension_count = 1;
450 instance_create_info = instance_default_create_info;
451 instance_create_info.instance_extensions = enabled_extensions;
452 instance_create_info.instance_extension_count = extension_count;
453 if (FAILED(hr = vkd3d_create_instance(&instance_create_info, &instance)))
455 skip("Failed to create instance, hr %#x.\n", hr);
456 return;
458 ok(hr == S_OK, "Failed to create instance, hr %#x.\n", hr);
459 vk_instance = vkd3d_instance_get_vk_instance(instance);
460 ok(vk_instance != VK_NULL_HANDLE, "Failed to get Vulkan instance.\n");
462 vr = vkEnumeratePhysicalDevices(vk_instance, &count, NULL);
463 ok(vr == VK_SUCCESS, "Got unexpected VkResult %d.\n", vr);
464 count = 1;
465 vr = vkEnumeratePhysicalDevices(vk_instance, &count, &vk_physical_device);
466 ok(vr == VK_SUCCESS || vr == VK_INCOMPLETE, "Got unexpected VkResult %d.\n", vr);
468 if (!(extension_count = check_device_extensions(vk_physical_device,
469 enabled_extensions, extensions, ARRAY_SIZE(extensions))))
471 skip("%s is not available.\n", VK_KHR_SWAPCHAIN_EXTENSION_NAME);
472 vkd3d_instance_decref(instance);
473 return;
476 device_create_info = device_default_create_info;
477 device_create_info.instance = instance;
478 device_create_info.instance_create_info = NULL;
479 device_create_info.vk_physical_device = vk_physical_device;
480 device_create_info.device_extensions = enabled_extensions;
481 device_create_info.device_extension_count = extension_count;
482 hr = vkd3d_create_device(&device_create_info, &IID_ID3D12Device, (void **)&device);
483 ok(hr == S_OK, "Failed to create device, hr %#x.\n", hr);
485 vk_device = vkd3d_get_vk_device(device);
487 pfn = vkGetDeviceProcAddr(vk_device, "vkCreateSwapchainKHR");
488 ok(pfn, "Failed to get proc addr for vkCreateSwapchainKHR.\n");
490 refcount = ID3D12Device_Release(device);
491 ok(!refcount, "Device has %u references left.\n", refcount);
492 refcount = vkd3d_instance_decref(instance);
493 ok(!refcount, "Instance has %u references left.\n", refcount);
496 static void test_optional_device_extensions(void)
498 static const char * const extensions[] =
500 "VK_VKD3D_invalid_extension",
501 VK_KHR_BIND_MEMORY_2_EXTENSION_NAME,
504 struct vkd3d_optional_device_extensions_info optional_extensions;
505 struct vkd3d_instance_create_info instance_create_info;
506 struct vkd3d_device_create_info device_create_info;
507 struct vkd3d_instance *instance;
508 ID3D12Device *device;
509 ULONG refcount;
510 HRESULT hr;
512 instance_create_info = instance_default_create_info;
513 hr = vkd3d_create_instance(&instance_create_info, &instance);
514 ok(hr == S_OK, "Failed to create instance, hr %#x.\n", hr);
516 device_create_info = device_default_create_info;
517 device_create_info.instance = instance;
518 device_create_info.instance_create_info = NULL;
519 device_create_info.device_extensions = extensions;
520 device_create_info.device_extension_count = ARRAY_SIZE(extensions);
521 hr = vkd3d_create_device(&device_create_info, &IID_ID3D12Device, (void **)&device);
522 ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr);
524 optional_extensions.type = VKD3D_STRUCTURE_TYPE_OPTIONAL_DEVICE_EXTENSIONS_INFO;
525 optional_extensions.next = NULL;
526 optional_extensions.extensions = extensions;
527 optional_extensions.extension_count = ARRAY_SIZE(extensions);
529 device_create_info.next = &optional_extensions;
530 device_create_info.device_extensions = NULL;
531 device_create_info.device_extension_count = 0;
532 hr = vkd3d_create_device(&device_create_info, &IID_ID3D12Device, (void **)&device);
533 ok(hr == S_OK, "Failed to create device, hr %#x.\n", hr);
535 refcount = ID3D12Device_Release(device);
536 ok(!refcount, "Device has %u references left.\n", refcount);
537 refcount = vkd3d_instance_decref(instance);
538 ok(!refcount, "Instance has %u references left.\n", refcount);
541 static void test_physical_device(void)
543 struct vkd3d_device_create_info create_info;
544 VkPhysicalDevice *vk_physical_devices;
545 VkPhysicalDevice vk_physical_device;
546 struct vkd3d_instance *instance;
547 VkInstance vk_instance;
548 ID3D12Device *device;
549 uint32_t i, count;
550 ULONG refcount;
551 VkResult vr;
552 HRESULT hr;
554 hr = vkd3d_create_instance(&instance_default_create_info, &instance);
555 ok(hr == S_OK, "Failed to create instance, hr %#x.\n", hr);
556 vk_instance = vkd3d_instance_get_vk_instance(instance);
557 ok(vk_instance != VK_NULL_HANDLE, "Failed to get Vulkan instance.\n");
559 create_info = device_default_create_info;
560 create_info.instance = instance;
561 create_info.instance_create_info = NULL;
562 create_info.vk_physical_device = VK_NULL_HANDLE;
563 hr = vkd3d_create_device(&create_info, &IID_ID3D12Device, (void **)&device);
564 ok(hr == S_OK, "Failed to create device, hr %#x.\n", hr);
565 vk_physical_device = vkd3d_get_vk_physical_device(device);
566 trace("Default Vulkan physical device %p.\n", vk_physical_device);
567 refcount = ID3D12Device_Release(device);
568 ok(!refcount, "Device has %u references left.\n", refcount);
570 vr = vkEnumeratePhysicalDevices(vk_instance, &count, NULL);
571 ok(vr == VK_SUCCESS, "Got unexpected VkResult %d.\n", vr);
572 vk_physical_devices = calloc(count, sizeof(*vk_physical_devices));
573 ok(vk_physical_devices, "Failed to allocate memory.\n");
574 vr = vkEnumeratePhysicalDevices(vk_instance, &count, vk_physical_devices);
575 ok(vr == VK_SUCCESS, "Got unexpected VkResult %d.\n", vr);
577 if (!getenv("VKD3D_VULKAN_DEVICE"))
579 for (i = 0; i < count; ++i)
581 trace("Creating device for Vulkan physical device %p.\n", vk_physical_devices[i]);
583 create_info.vk_physical_device = vk_physical_devices[i];
584 hr = vkd3d_create_device(&create_info, &IID_ID3D12Device, (void **)&device);
585 ok(hr == S_OK, "Failed to create device, hr %#x.\n", hr);
586 vk_physical_device = vkd3d_get_vk_physical_device(device);
587 ok(vk_physical_device == vk_physical_devices[i],
588 "Got unexpected Vulkan physical device %p.\n", vk_physical_device);
589 refcount = ID3D12Device_Release(device);
590 ok(!refcount, "Device has %u references left.\n", refcount);
593 else
595 skip("VKD3D_VULKAN_DEVICE is set.\n");
598 free(vk_physical_devices);
599 refcount = vkd3d_instance_decref(instance);
600 ok(!refcount, "Instance has %u references left.\n", refcount);
603 static void test_adapter_luid(void)
605 struct vkd3d_device_create_info create_info;
606 ID3D12Device *device;
607 ULONG refcount;
608 HRESULT hr;
609 LUID luid;
611 create_info = device_default_create_info;
612 create_info.adapter_luid.HighPart = 0xdeadc0de;
613 create_info.adapter_luid.LowPart = 0xdeadbeef;
614 hr = vkd3d_create_device(&create_info, &IID_ID3D12Device, (void **)&device);
615 ok(hr == S_OK, "Failed to create device, hr %#x.\n", hr);
617 luid = ID3D12Device_GetAdapterLuid(device);
618 ok(luid.HighPart == 0xdeadc0de && luid.LowPart == 0xdeadbeef,
619 "Got unexpected LUID %08x:%08x.\n", luid.HighPart, luid.LowPart);
621 refcount = ID3D12Device_Release(device);
622 ok(!refcount, "Device has %u references left.\n", refcount);
625 struct parent
627 IUnknown IUnknown_iface;
628 unsigned int refcount;
631 static struct parent *parent_from_IUnknown(IUnknown *iface)
633 return CONTAINING_RECORD(iface, struct parent, IUnknown_iface);
636 static HRESULT STDMETHODCALLTYPE parent_QueryInterface(IUnknown *iface,
637 REFIID iid, void **object)
639 if (IsEqualGUID(iid, &IID_IUnknown))
641 IUnknown_AddRef(iface);
642 *object = iface;
643 return S_OK;
646 ok(false, "Unexpected QueryInterface() call.\n");
647 return E_NOINTERFACE;
650 static ULONG STDMETHODCALLTYPE parent_AddRef(IUnknown *iface)
652 struct parent *parent = parent_from_IUnknown(iface);
654 return vkd3d_atomic_increment_u32(&parent->refcount);
657 static ULONG STDMETHODCALLTYPE parent_Release(IUnknown *iface)
659 struct parent *parent = parent_from_IUnknown(iface);
661 return vkd3d_atomic_decrement_u32(&parent->refcount);
664 static const struct IUnknownVtbl parent_vtbl =
666 parent_QueryInterface,
667 parent_AddRef,
668 parent_Release,
671 static void test_device_parent(void)
673 struct vkd3d_device_create_info create_info;
674 struct parent parent_impl;
675 ID3D12Device *device;
676 IUnknown *unknown;
677 IUnknown *parent;
678 ULONG refcount;
679 HRESULT hr;
681 parent_impl.IUnknown_iface.lpVtbl = &parent_vtbl;
682 parent_impl.refcount = 1;
683 parent = &parent_impl.IUnknown_iface;
685 refcount = get_refcount(parent);
686 ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
688 create_info = device_default_create_info;
689 create_info.parent = parent;
690 hr = vkd3d_create_device(&create_info, &IID_ID3D12Device, (void **)&device);
691 ok(hr == S_OK, "Failed to create device, hr %#x.\n", hr);
693 refcount = get_refcount(parent);
694 ok(refcount == 2, "Got unexpected refcount %u.\n", refcount);
696 unknown = vkd3d_get_device_parent(device);
697 ok(unknown == parent, "Got device parent %p, expected %p.\n", unknown, parent);
699 refcount = ID3D12Device_Release(device);
700 ok(!refcount, "Device has %u references left.\n", refcount);
702 refcount = get_refcount(parent);
703 ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
706 static void test_vkd3d_queue(void)
708 ID3D12CommandQueue *direct_queue, *compute_queue, *copy_queue;
709 uint32_t vk_queue_family;
710 ID3D12Device *device;
711 VkQueue vk_queue;
712 ULONG refcount;
714 device = create_device();
715 ok(device, "Failed to create device.\n");
717 direct_queue = create_command_queue(device, D3D12_COMMAND_LIST_TYPE_DIRECT, D3D12_COMMAND_QUEUE_PRIORITY_NORMAL);
718 ok(direct_queue, "Failed to create direct command queue.\n");
719 compute_queue = create_command_queue(device, D3D12_COMMAND_LIST_TYPE_COMPUTE, D3D12_COMMAND_QUEUE_PRIORITY_NORMAL);
720 ok(compute_queue, "Failed to create compute command queue.\n");
721 copy_queue = create_command_queue(device, D3D12_COMMAND_LIST_TYPE_COPY, D3D12_COMMAND_QUEUE_PRIORITY_NORMAL);
722 ok(copy_queue, "Failed to create copy command queue.\n");
724 vk_queue_family = vkd3d_get_vk_queue_family_index(direct_queue);
725 trace("Direct queue family index %u.\n", vk_queue_family);
726 vk_queue_family = vkd3d_get_vk_queue_family_index(compute_queue);
727 trace("Compute queue family index %u.\n", vk_queue_family);
728 vk_queue_family = vkd3d_get_vk_queue_family_index(copy_queue);
729 trace("Copy queue family index %u.\n", vk_queue_family);
731 vk_queue = vkd3d_acquire_vk_queue(direct_queue);
732 ok(vk_queue != VK_NULL_HANDLE, "Failed to acquire Vulkan queue.\n");
733 vkd3d_release_vk_queue(direct_queue);
734 vk_queue = vkd3d_acquire_vk_queue(compute_queue);
735 ok(vk_queue != VK_NULL_HANDLE, "Failed to acquire Vulkan queue.\n");
736 vkd3d_release_vk_queue(compute_queue);
737 vk_queue = vkd3d_acquire_vk_queue(copy_queue);
738 ok(vk_queue != VK_NULL_HANDLE, "Failed to acquire Vulkan queue.\n");
739 vkd3d_release_vk_queue(copy_queue);
741 ID3D12CommandQueue_Release(direct_queue);
742 ID3D12CommandQueue_Release(compute_queue);
743 ID3D12CommandQueue_Release(copy_queue);
744 refcount = ID3D12Device_Release(device);
745 ok(!refcount, "Device has %u references left.\n", refcount);
748 static void test_resource_internal_refcount(void)
750 ID3D12Resource *resource;
751 ID3D12Device *device;
752 ULONG refcount;
754 device = create_device();
755 ok(device, "Failed to create device.\n");
757 resource = create_buffer(device, D3D12_HEAP_TYPE_UPLOAD, 1024,
758 D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_GENERIC_READ);
759 refcount = vkd3d_resource_incref(resource);
760 ok(refcount == 2, "Got refcount %u.\n", refcount);
761 refcount = ID3D12Resource_Release(resource);
762 ok(!refcount, "Got refcount %u.\n", refcount);
763 refcount = resource_get_internal_refcount(resource);
764 ok(refcount == 1, "Got refcount %u.\n", refcount);
765 refcount = vkd3d_resource_decref(resource);
766 ok(!refcount, "Got refcount %u.\n", refcount);
768 resource = create_buffer(device, D3D12_HEAP_TYPE_UPLOAD, 1024,
769 D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_GENERIC_READ);
770 refcount = vkd3d_resource_incref(resource);
771 ok(refcount == 2, "Got refcount %u.\n", refcount);
772 refcount = ID3D12Resource_Release(resource);
773 ok(!refcount, "Got refcount %u.\n", refcount);
774 refcount = resource_get_internal_refcount(resource);
775 ok(refcount == 1, "Got refcount %u.\n", refcount);
776 refcount = ID3D12Resource_AddRef(resource);
777 ok(refcount == 1, "Got refcount %u.\n", refcount);
778 refcount = vkd3d_resource_decref(resource);
779 ok(refcount == 1, "Got refcount %u.\n", refcount);
780 refcount = ID3D12Resource_Release(resource);
781 ok(!refcount, "Got refcount %u.\n", refcount);
783 refcount = ID3D12Device_Release(device);
784 ok(!refcount, "Device has %u references left.\n", refcount);
787 static VkImage create_vulkan_image(ID3D12Device *device,
788 unsigned int width, unsigned int height, VkFormat vk_format, VkImageUsageFlags usage)
790 VkImageCreateInfo image_info;
791 VkDevice vk_device;
792 VkImage vk_image;
793 VkResult vr;
795 vk_device = vkd3d_get_vk_device(device);
797 image_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
798 image_info.pNext = NULL;
799 image_info.imageType = VK_IMAGE_TYPE_2D;
800 image_info.format = vk_format;
801 image_info.extent.width = width;
802 image_info.extent.height = height;
803 image_info.extent.depth = 1;
804 image_info.arrayLayers = 1;
805 image_info.mipLevels = 1;
806 image_info.samples = VK_SAMPLE_COUNT_1_BIT;
807 image_info.tiling = VK_IMAGE_TILING_OPTIMAL;
808 image_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
809 image_info.usage |= usage;
810 image_info.flags = 0;
811 image_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
812 image_info.queueFamilyIndexCount = 0;
813 image_info.pQueueFamilyIndices = NULL;
814 image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
816 vr = vkCreateImage(vk_device, &image_info, NULL, &vk_image);
817 ok(vr == VK_SUCCESS, "Failed to create image, vr %d.\n", vr);
819 return vk_image;
822 static unsigned int select_vulkan_memory_type(ID3D12Device *device,
823 uint32_t memory_type_mask, VkMemoryPropertyFlags required_flags)
825 VkPhysicalDeviceMemoryProperties memory_info;
826 VkPhysicalDevice vk_physical_device;
827 unsigned int i;
829 vk_physical_device = vkd3d_get_vk_physical_device(device);
831 vkGetPhysicalDeviceMemoryProperties(vk_physical_device, &memory_info);
833 for (i = 0; i < memory_info.memoryTypeCount; ++i)
835 if (!(memory_type_mask & (1u << i)))
836 continue;
837 if ((memory_info.memoryTypes[i].propertyFlags & required_flags) == required_flags)
838 return i;
841 return ~0u;
844 static VkDeviceMemory allocate_vulkan_device_memory(ID3D12Device *device,
845 VkMemoryPropertyFlags required_flags, const VkMemoryRequirements *memory_requirements)
847 VkMemoryAllocateInfo allocate_info;
848 VkDeviceMemory vk_memory;
849 VkDevice vk_device;
850 VkResult vr;
852 vk_device = vkd3d_get_vk_device(device);
854 allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
855 allocate_info.pNext = NULL;
856 allocate_info.allocationSize = memory_requirements->size;
857 allocate_info.memoryTypeIndex = select_vulkan_memory_type(device,
858 memory_requirements->memoryTypeBits, required_flags);
859 ok(allocate_info.memoryTypeIndex != ~0u, "Failed to find memory type.\n");
861 vr = vkAllocateMemory(vk_device, &allocate_info, NULL, &vk_memory);
862 ok(vr == VK_SUCCESS, "Got unexpected VkResult %d.\n", vr);
864 return vk_memory;
867 static VkDeviceMemory allocate_vulkan_image_memory(ID3D12Device *device,
868 VkMemoryPropertyFlags required_flags, VkImage vk_image)
870 VkMemoryRequirements memory_requirements;
871 VkDeviceMemory vk_memory;
872 VkDevice vk_device;
873 VkResult vr;
875 vk_device = vkd3d_get_vk_device(device);
877 vkGetImageMemoryRequirements(vk_device, vk_image, &memory_requirements);
878 vk_memory = allocate_vulkan_device_memory(device, required_flags, &memory_requirements);
880 vr = vkBindImageMemory(vk_device, vk_image, vk_memory, 0);
881 ok(vr == VK_SUCCESS, "Got unexpected VkResult %d.\n", vr);
883 return vk_memory;
886 static void test_external_resource_map(void)
888 struct vkd3d_image_resource_create_info resource_create_info;
889 D3D12_HEAP_PROPERTIES heap_properties;
890 D3D12_GPU_VIRTUAL_ADDRESS gpu_address;
891 D3D12_HEAP_FLAGS heap_flags;
892 ID3D12Resource *vk_resource;
893 VkDeviceMemory vk_memory;
894 ID3D12Device *device;
895 VkDevice vk_device;
896 VkImage vk_image;
897 ULONG refcount;
898 HRESULT hr;
899 void *ptr;
901 device = create_device();
902 ok(device, "Failed to create device.\n");
904 vk_image = create_vulkan_image(device, 32, 32,
905 VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
906 vk_memory = allocate_vulkan_image_memory(device,
907 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, vk_image);
909 resource_create_info.type = VKD3D_STRUCTURE_TYPE_IMAGE_RESOURCE_CREATE_INFO;
910 resource_create_info.next = NULL;
911 resource_create_info.vk_image = vk_image;
912 resource_create_info.desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
913 resource_create_info.desc.Alignment = 0;
914 resource_create_info.desc.Width = 32;
915 resource_create_info.desc.Height = 32;
916 resource_create_info.desc.DepthOrArraySize = 1;
917 resource_create_info.desc.MipLevels = 1;
918 resource_create_info.desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
919 resource_create_info.desc.SampleDesc.Count = 1;
920 resource_create_info.desc.SampleDesc.Quality = 0;
921 resource_create_info.desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
922 resource_create_info.desc.Flags = 0;
923 resource_create_info.flags = VKD3D_RESOURCE_INITIAL_STATE_TRANSITION;
924 hr = vkd3d_create_image_resource(device, &resource_create_info, &vk_resource);
925 ok(hr == S_OK, "Failed to create D3D12 resource for Vulkan image, hr %#x.\n", hr);
927 ptr = (void *)0xdeadbeef;
928 hr = ID3D12Resource_Map(vk_resource, 0, NULL, &ptr);
929 ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
930 ok(ptr == (void *)0xdeadbeef, "Pointer was modified %p.\n", ptr);
932 gpu_address = ID3D12Resource_GetGPUVirtualAddress(vk_resource);
933 ok(!gpu_address, "Got unexpected GPU virtual address %#"PRIx64".\n", gpu_address);
935 hr = ID3D12Resource_GetHeapProperties(vk_resource, &heap_properties, &heap_flags);
936 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
937 ok(heap_properties.Type == D3D12_HEAP_TYPE_DEFAULT, "Got unexpected heap type %#x.\n", heap_properties.Type);
938 ok(heap_properties.CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_UNKNOWN,
939 "Got unexpected CPU page property %#x.\n", heap_properties.CPUPageProperty);
940 ok(heap_properties.MemoryPoolPreference == D3D12_MEMORY_POOL_UNKNOWN,
941 "Got unexpected memory pool preference %#x.\n", heap_properties.MemoryPoolPreference);
942 ok(!!heap_properties.CreationNodeMask, "Got unexpected node mask %#x.\n", heap_properties.CreationNodeMask);
943 ok(!!heap_properties.VisibleNodeMask, "Got unexpected node mask %#x.\n", heap_properties.VisibleNodeMask);
945 ID3D12Resource_Release(vk_resource);
946 vk_device = vkd3d_get_vk_device(device);
947 vkDestroyImage(vk_device, vk_image, NULL);
948 vkFreeMemory(vk_device, vk_memory, NULL);
949 refcount = ID3D12Device_Release(device);
950 ok(!refcount, "Device has %u references left.\n", refcount);
953 static void test_external_resource_present_state(void)
955 static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
957 struct vkd3d_image_resource_create_info resource_create_info;
958 ID3D12GraphicsCommandList *command_list;
959 ID3D12Resource *vk_resource, *resource;
960 D3D12_CPU_DESCRIPTOR_HANDLE rtv;
961 struct test_context_desc desc;
962 struct test_context context;
963 ID3D12CommandQueue *queue;
964 VkDeviceMemory vk_memory;
965 ID3D12Device *device;
966 VkDevice vk_device;
967 VkImage vk_image;
968 HRESULT hr;
970 memset(&desc, 0, sizeof(desc));
971 desc.rt_width = desc.rt_height = 32;
972 if (!init_test_context(&context, &desc))
973 return;
974 device = context.device;
975 command_list = context.list;
976 queue = context.queue;
978 resource = create_default_texture(device, 32, 32, DXGI_FORMAT_R8G8B8A8_UNORM,
979 D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_COPY_DEST);
981 vk_image = create_vulkan_image(device, 32, 32,
982 VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
983 vk_memory = allocate_vulkan_image_memory(device,
984 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, vk_image);
986 resource_create_info.type = VKD3D_STRUCTURE_TYPE_IMAGE_RESOURCE_CREATE_INFO;
987 resource_create_info.next = NULL;
988 resource_create_info.vk_image = vk_image;
989 resource_create_info.desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
990 resource_create_info.desc.Alignment = 0;
991 resource_create_info.desc.Width = 32;
992 resource_create_info.desc.Height = 32;
993 resource_create_info.desc.DepthOrArraySize = 1;
994 resource_create_info.desc.MipLevels = 1;
995 resource_create_info.desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
996 resource_create_info.desc.SampleDesc.Count = 1;
997 resource_create_info.desc.SampleDesc.Quality = 0;
998 resource_create_info.desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
999 resource_create_info.desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
1000 resource_create_info.flags = VKD3D_RESOURCE_INITIAL_STATE_TRANSITION | VKD3D_RESOURCE_PRESENT_STATE_TRANSITION;
1001 resource_create_info.present_state = D3D12_RESOURCE_STATE_COPY_SOURCE;
1002 hr = vkd3d_create_image_resource(device, &resource_create_info, &vk_resource);
1003 ok(hr == S_OK, "Failed to create D3D12 resource for Vulkan image, hr %#x.\n", hr);
1005 rtv = get_cpu_descriptor_handle(&context, context.rtv_heap, 0);
1006 ID3D12Device_CreateRenderTargetView(device, vk_resource, NULL, rtv);
1008 transition_resource_state(command_list, vk_resource,
1009 D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET);
1011 ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, rtv, white, 0, NULL);
1012 ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &rtv, false, NULL);
1013 ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
1014 ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
1015 ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
1016 ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
1017 ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
1018 ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
1020 transition_resource_state(command_list, vk_resource,
1021 D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT);
1022 ID3D12GraphicsCommandList_CopyResource(command_list, resource, vk_resource);
1023 transition_resource_state(command_list, resource,
1024 D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_COPY_SOURCE);
1026 check_sub_resource_uint(resource, 0, queue, command_list, 0xff00ff00, 0);
1028 ID3D12Resource_Release(vk_resource);
1029 vk_device = vkd3d_get_vk_device(device);
1030 vkDestroyImage(vk_device, vk_image, NULL);
1031 vkFreeMemory(vk_device, vk_memory, NULL);
1032 ID3D12Resource_Release(resource);
1033 destroy_test_context(&context);
1036 static void test_formats(void)
1038 DXGI_FORMAT dxgi_format, format;
1039 VkFormat vk_format;
1040 unsigned int i;
1042 static const DXGI_FORMAT formats[] =
1044 DXGI_FORMAT_R32G32B32A32_FLOAT,
1045 DXGI_FORMAT_R32G32B32A32_UINT,
1046 DXGI_FORMAT_R32G32B32A32_SINT,
1047 DXGI_FORMAT_R32G32B32_FLOAT,
1048 DXGI_FORMAT_R32G32B32_UINT,
1049 DXGI_FORMAT_R32G32B32_SINT,
1050 DXGI_FORMAT_R16G16B16A16_FLOAT,
1051 DXGI_FORMAT_R16G16B16A16_UNORM,
1052 DXGI_FORMAT_R16G16B16A16_UINT,
1053 DXGI_FORMAT_R16G16B16A16_SNORM,
1054 DXGI_FORMAT_R16G16B16A16_SINT,
1055 DXGI_FORMAT_R32G32_FLOAT,
1056 DXGI_FORMAT_R32G32_UINT,
1057 DXGI_FORMAT_R32G32_SINT,
1058 DXGI_FORMAT_R10G10B10A2_UNORM,
1059 DXGI_FORMAT_R11G11B10_FLOAT,
1060 DXGI_FORMAT_R8G8B8A8_UNORM,
1061 DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
1062 DXGI_FORMAT_R8G8B8A8_UINT,
1063 DXGI_FORMAT_R8G8B8A8_SNORM,
1064 DXGI_FORMAT_R8G8B8A8_SINT,
1065 DXGI_FORMAT_R16G16_FLOAT,
1066 DXGI_FORMAT_R16G16_UNORM,
1067 DXGI_FORMAT_R16G16_UINT,
1068 DXGI_FORMAT_R16G16_SNORM,
1069 DXGI_FORMAT_R16G16_SINT,
1070 DXGI_FORMAT_D32_FLOAT,
1071 DXGI_FORMAT_R32_FLOAT,
1072 DXGI_FORMAT_R32_UINT,
1073 DXGI_FORMAT_R32_SINT,
1074 DXGI_FORMAT_R8G8_UNORM,
1075 DXGI_FORMAT_R8G8_UINT,
1076 DXGI_FORMAT_R8G8_SNORM,
1077 DXGI_FORMAT_R8G8_SINT,
1078 DXGI_FORMAT_R16_FLOAT,
1079 DXGI_FORMAT_D16_UNORM,
1080 DXGI_FORMAT_R16_UNORM,
1081 DXGI_FORMAT_R16_UINT,
1082 DXGI_FORMAT_R16_SNORM,
1083 DXGI_FORMAT_R16_SINT,
1084 DXGI_FORMAT_R8_UNORM,
1085 DXGI_FORMAT_R8_UINT,
1086 DXGI_FORMAT_R8_SNORM,
1087 DXGI_FORMAT_R8_SINT,
1090 for (i = 0; i < ARRAY_SIZE(formats); ++i)
1092 format = formats[i];
1093 vk_format = vkd3d_get_vk_format(format);
1094 dxgi_format = vkd3d_get_dxgi_format(vk_format);
1095 ok(dxgi_format == format, "Got format %#x, expected %#x.\n", dxgi_format, format);
1099 static void test_application_info(void)
1101 D3D12_FEATURE_DATA_ROOT_SIGNATURE root_signature;
1102 struct vkd3d_instance_create_info create_info;
1103 struct vkd3d_device_create_info device_info;
1104 struct vkd3d_application_info app_info;
1105 struct vkd3d_instance *instance;
1106 ID3D12Device *device;
1107 unsigned int i;
1108 ULONG refcount;
1109 HRESULT hr;
1111 static const struct
1113 enum vkd3d_api_version api_version;
1114 D3D_ROOT_SIGNATURE_VERSION rs_version;
1116 root_signature_versions[] =
1118 {VKD3D_API_VERSION_1_0, D3D_ROOT_SIGNATURE_VERSION_1_0},
1119 {VKD3D_API_VERSION_1_1, D3D_ROOT_SIGNATURE_VERSION_1_0},
1120 {VKD3D_API_VERSION_1_2, D3D_ROOT_SIGNATURE_VERSION_1_1},
1123 app_info.type = VKD3D_STRUCTURE_TYPE_APPLICATION_INFO;
1124 app_info.next = NULL;
1125 app_info.engine_name = NULL;
1126 app_info.engine_version = 0;
1127 app_info.application_name = NULL;
1128 app_info.application_version = 0;
1129 app_info.api_version = VKD3D_API_VERSION_1_0;
1131 create_info = instance_default_create_info;
1132 create_info.next = &app_info;
1133 hr = vkd3d_create_instance(&create_info, &instance);
1134 ok(hr == S_OK, "Failed to create instance, hr %#x.\n", hr);
1135 refcount = vkd3d_instance_decref(instance);
1136 ok(!refcount, "Instance has %u references left.\n", refcount);
1138 app_info.application_name = "vkd3d_api_tests";
1139 app_info.application_version = 0xdeadbeef;
1140 hr = vkd3d_create_instance(&create_info, &instance);
1141 ok(hr == S_OK, "Failed to create instance, hr %#x.\n", hr);
1142 refcount = vkd3d_instance_decref(instance);
1143 ok(!refcount, "Instance has %u references left.\n", refcount);
1145 app_info.engine_name = "engine_name";
1146 hr = vkd3d_create_instance(&create_info, &instance);
1147 ok(hr == S_OK, "Failed to create instance, hr %#x.\n", hr);
1148 refcount = vkd3d_instance_decref(instance);
1149 ok(!refcount, "Instance has %u references left.\n", refcount);
1151 app_info.engine_name = "engine_name";
1152 app_info.engine_version = 2;
1153 hr = vkd3d_create_instance(&create_info, &instance);
1154 ok(hr == S_OK, "Failed to create instance, hr %#x.\n", hr);
1155 refcount = vkd3d_instance_decref(instance);
1156 ok(!refcount, "Instance has %u references left.\n", refcount);
1158 device_info = device_default_create_info;
1159 device_info.instance_create_info = &create_info;
1160 for (i = 0; i < ARRAY_SIZE(root_signature_versions); ++i)
1162 app_info.api_version = root_signature_versions[i].api_version;
1163 hr = vkd3d_create_device(&device_info, &IID_ID3D12Device, (void **)&device);
1164 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
1166 root_signature.HighestVersion = D3D_ROOT_SIGNATURE_VERSION_1_0;
1167 hr = ID3D12Device_CheckFeatureSupport(device, D3D12_FEATURE_ROOT_SIGNATURE,
1168 &root_signature, sizeof(root_signature));
1169 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
1170 ok(root_signature.HighestVersion == D3D_ROOT_SIGNATURE_VERSION_1_0,
1171 "Got unexpected root signature feature version %#x.\n", root_signature.HighestVersion);
1173 root_signature.HighestVersion = D3D_ROOT_SIGNATURE_VERSION_1_1;
1174 hr = ID3D12Device_CheckFeatureSupport(device, D3D12_FEATURE_ROOT_SIGNATURE,
1175 &root_signature, sizeof(root_signature));
1176 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
1177 ok(root_signature.HighestVersion == root_signature_versions[i].rs_version,
1178 "Got unexpected root signature feature version %#x.\n", root_signature.HighestVersion);
1180 ID3D12Device_Release(device);
1183 create_info.next = NULL;
1184 hr = vkd3d_create_device(&device_info, &IID_ID3D12Device, (void **)&device);
1185 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
1187 root_signature.HighestVersion = D3D_ROOT_SIGNATURE_VERSION_1_1;
1188 hr = ID3D12Device_CheckFeatureSupport(device, D3D12_FEATURE_ROOT_SIGNATURE,
1189 &root_signature, sizeof(root_signature));
1190 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
1191 ok(root_signature.HighestVersion == D3D_ROOT_SIGNATURE_VERSION_1_0,
1192 "Got unexpected root signature feature version %#x.\n", root_signature.HighestVersion);
1194 ID3D12Device_Release(device);
1197 static void test_queue_signal_on_cpu(void)
1199 PFN_vkd3d_queue_signal_on_cpu pfn_vkd3d_queue_signal_on_cpu = vkd3d_queue_signal_on_cpu;
1200 D3D12_COMMAND_QUEUE_DESC queue_desc = {0};
1201 ID3D12CommandQueue *queue, *queue2;
1202 struct test_context context = {0};
1203 struct test_context_desc desc;
1204 ID3D12Fence *fence, *fence2;
1205 unsigned int refcount;
1206 enum vkd3d_result ret;
1207 ID3D12Device *device;
1208 HRESULT hr;
1210 desc.no_render_target = true;
1211 if (!init_test_context(&context, &desc))
1212 return;
1213 device = context.device;
1214 queue = context.queue;
1216 queue_desc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
1217 hr = ID3D12Device_CreateCommandQueue(device, &queue_desc, &IID_ID3D12CommandQueue, (void **)&queue2);
1218 ok(hr == S_OK, "Couldn't create command queue, hr %#x.\n", hr);
1220 hr = ID3D12Device_CreateFence(device, 0, 0, &IID_ID3D12Fence, (void **)&fence);
1221 ok(hr == S_OK, "Couldn't create fence, hr %#x.\n", hr);
1222 hr = ID3D12Device_CreateFence(device, 0, 0, &IID_ID3D12Fence, (void **)&fence2);
1223 ok(hr == S_OK, "Couldn't create fence, hr %#x.\n", hr);
1225 /* Queue signal on CPU immediately. */
1226 ret = pfn_vkd3d_queue_signal_on_cpu(queue, fence, 1);
1227 ok(ret == VKD3D_OK, "Couldn't queue signal on CPU, ret %#x.\n", ret);
1228 hr = ID3D12Fence_SetEventOnCompletion(fence, 1, NULL);
1229 ok(hr == S_OK, "Couldn't wait for fence, hr %#x.\n", hr);
1231 /* Queue signal on CPU depending on a CPU-side signal. */
1232 hr = ID3D12CommandQueue_Wait(queue, fence2, 2);
1233 ok(hr == S_OK, "Couldn't queue wait, hr %#x.\n", hr);
1234 ret = pfn_vkd3d_queue_signal_on_cpu(queue, fence, 2);
1235 ok(ret == VKD3D_OK, "Couldn't queue signal on CPU, ret %#x.\n", ret);
1236 hr = ID3D12Fence_Signal(fence2, 2);
1237 ok(hr == S_OK, "Couldn't signal, hr %#x.\n", hr);
1238 hr = ID3D12Fence_SetEventOnCompletion(fence, 2, NULL);
1239 ok(hr == S_OK, "Couldn't wait for fence, hr %#x.\n", hr);
1241 /* Queue signal on CPU depending on a GPU-side signal which is already satisfied. */
1242 hr = ID3D12CommandQueue_Signal(queue, fence2, 3);
1243 ok(hr == S_OK, "Couldn't queue signal, hr %#x.\n", hr);
1244 hr = ID3D12CommandQueue_Wait(queue, fence2, 3);
1245 ok(hr == S_OK, "Couldn't queue wait, hr %#x.\n", hr);
1246 ret = pfn_vkd3d_queue_signal_on_cpu(queue, fence, 3);
1247 ok(ret == VKD3D_OK, "Couldn't queue signal on CPU, ret %#x.\n", ret);
1248 hr = ID3D12Fence_SetEventOnCompletion(fence, 3, NULL);
1249 ok(hr == S_OK, "Couldn't wait for fence, hr %#x.\n", hr);
1251 /* Queue signal on CPU depending on a GPU-side signal queued on another queue. */
1252 hr = ID3D12CommandQueue_Wait(queue, fence2, 4);
1253 ok(hr == S_OK, "Couldn't queue wait, hr %#x.\n", hr);
1254 ret = pfn_vkd3d_queue_signal_on_cpu(queue, fence, 4);
1255 ok(ret == VKD3D_OK, "Couldn't queue signal on CPU, ret %#x.\n", ret);
1256 hr = ID3D12CommandQueue_Signal(queue2, fence2, 4);
1257 ok(hr == S_OK, "Couldn't queue signal, hr %#x.\n", hr);
1258 hr = ID3D12Fence_SetEventOnCompletion(fence, 4, NULL);
1259 ok(hr == S_OK, "Couldn't wait for fence, hr %#x.\n", hr);
1261 refcount = ID3D12CommandQueue_Release(queue2);
1262 ok(refcount == 0, "%u references to command queue leaked.\n", refcount);
1263 refcount = ID3D12Fence_Release(fence2);
1264 ok(refcount == 0, "%u references to fence leaked.\n", refcount);
1265 refcount = ID3D12Fence_Release(fence);
1266 ok(refcount == 0, "%u references to fence leaked.\n", refcount);
1267 destroy_test_context(&context);
1270 static bool have_d3d12_device(void)
1272 ID3D12Device *device;
1274 if ((device = create_device()))
1275 ID3D12Device_Release(device);
1276 return device;
1279 START_TEST(vkd3d_api)
1281 void *libvulkan;
1283 if (!(libvulkan = vkd3d_dlopen(SONAME_LIBVULKAN)))
1285 skip("Failed to load %s: %s.\n", SONAME_LIBVULKAN, vkd3d_dlerror());
1286 return;
1289 #define LOAD_VK_PFN(name) name = vkd3d_dlsym(libvulkan, #name);
1290 LOAD_VK_PFN(vkEnumerateInstanceExtensionProperties)
1291 LOAD_VK_PFN(vkGetInstanceProcAddr)
1292 #define VK_DEVICE_PFN LOAD_VK_PFN
1293 #define VK_INSTANCE_PFN LOAD_VK_PFN
1294 #include "vulkan_procs.h"
1296 if (!have_d3d12_device())
1298 skip("D3D12 device cannot be created.\n");
1299 return;
1302 run_test(test_create_instance);
1303 run_test(test_additional_instance_extensions);
1304 run_test(test_create_device);
1305 run_test(test_required_device_extensions);
1306 run_test(test_additional_device_extensions);
1307 run_test(test_optional_device_extensions);
1308 run_test(test_physical_device);
1309 run_test(test_adapter_luid);
1310 run_test(test_device_parent);
1311 run_test(test_vkd3d_queue);
1312 run_test(test_resource_internal_refcount);
1313 run_test(test_external_resource_map);
1314 run_test(test_external_resource_present_state);
1315 run_test(test_formats);
1316 run_test(test_application_info);
1317 run_test(test_queue_signal_on_cpu);