[PATCH vkd3d 7/7] libs/vkd3d: Add thread-safe API for accessing Vulkan command queues.

Józef Kucia joseph.kucia at gmail.com
Mon Jan 15 06:49:07 CST 2018


From: Józef Kucia <jkucia at codeweavers.com>

Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
---

I'll remove vkd3d_get_vk_queue() after converting vkmodelviewer to the
new API.

---
 demos/demo_xcb.h     | 11 +++++---
 include/vkd3d.h      |  4 ++-
 libs/vkd3d/command.c | 14 ++++++++++
 libs/vkd3d/vkd3d.map |  2 ++
 tests/vkd3d_api.c    | 76 +++++++++++++++++++++++++++++++++++++++++++++++++---
 5 files changed, 99 insertions(+), 8 deletions(-)

diff --git a/demos/demo_xcb.h b/demos/demo_xcb.h
index 3cc2c54d7ff4..a683dcae1951 100644
--- a/demos/demo_xcb.h
+++ b/demos/demo_xcb.h
@@ -61,7 +61,7 @@ struct demo_swapchain
 
     VkInstance vk_instance;
     VkDevice vk_device;
-    VkQueue vk_queue;
+    ID3D12CommandQueue *command_queue;
 
     uint32_t current_buffer;
     unsigned int buffer_count;
@@ -451,7 +451,6 @@ static inline struct demo_swapchain *demo_swapchain_create(ID3D12CommandQueue *c
     swapchain->vk_fence = vk_fence;
     swapchain->vk_instance = vk_instance;
     swapchain->vk_device = vk_device;
-    swapchain->vk_queue = vkd3d_get_vk_queue(command_queue);
 
     vkAcquireNextImageKHR(vk_device, vk_swapchain, UINT64_MAX,
             VK_NULL_HANDLE, vk_fence, &swapchain->current_buffer);
@@ -488,6 +487,8 @@ static inline struct demo_swapchain *demo_swapchain_create(ID3D12CommandQueue *c
     free(vk_images);
     ID3D12Device_Release(d3d12_device);
 
+    ID3D12CommandQueue_AddRef(swapchain->command_queue = command_queue);
+
     return swapchain;
 
 fail:
@@ -518,6 +519,7 @@ static inline ID3D12Resource *demo_swapchain_get_back_buffer(struct demo_swapcha
 static inline void demo_swapchain_present(struct demo_swapchain *swapchain)
 {
     VkPresentInfoKHR present_desc;
+    VkQueue vk_queue;
 
     present_desc.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
     present_desc.pNext = NULL;
@@ -528,7 +530,9 @@ static inline void demo_swapchain_present(struct demo_swapchain *swapchain)
     present_desc.pImageIndices = &swapchain->current_buffer;
     present_desc.pResults = NULL;
 
-    vkQueuePresentKHR(swapchain->vk_queue, &present_desc);
+    vk_queue = vkd3d_acquire_vk_queue(swapchain->command_queue);
+    vkQueuePresentKHR(vk_queue, &present_desc);
+    vkd3d_release_vk_queue(swapchain->command_queue);
 
     vkAcquireNextImageKHR(swapchain->vk_device, swapchain->vk_swapchain, UINT64_MAX,
             VK_NULL_HANDLE, swapchain->vk_fence, &swapchain->current_buffer);
@@ -540,6 +544,7 @@ static inline void demo_swapchain_destroy(struct demo_swapchain *swapchain)
 {
     unsigned int i;
 
+    ID3D12CommandQueue_Release(swapchain->command_queue);
     for (i = 0; i < swapchain->buffer_count; ++i)
     {
         ID3D12Resource_Release(swapchain->buffers[i]);
diff --git a/include/vkd3d.h b/include/vkd3d.h
index 8a04dbd97cfa..322675b9e992 100644
--- a/include/vkd3d.h
+++ b/include/vkd3d.h
@@ -73,8 +73,10 @@ VkDevice vkd3d_get_vk_device(ID3D12Device *device);
 VkInstance vkd3d_get_vk_instance(ID3D12Device *device);
 VkPhysicalDevice vkd3d_get_vk_physical_device(ID3D12Device *device);
 
-VkQueue vkd3d_get_vk_queue(ID3D12CommandQueue *queue);
 uint32_t vkd3d_get_vk_queue_family_index(ID3D12CommandQueue *queue);
+VkQueue vkd3d_acquire_vk_queue(ID3D12CommandQueue *queue);
+VkQueue vkd3d_get_vk_queue(ID3D12CommandQueue *queue);
+void vkd3d_release_vk_queue(ID3D12CommandQueue *queue);
 
 HRESULT vkd3d_serialize_root_signature(const D3D12_ROOT_SIGNATURE_DESC *root_signature_desc,
         D3D_ROOT_SIGNATURE_VERSION version, ID3DBlob **blob, ID3DBlob **error_blob);
diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c
index 85dcf6fcabbf..7aa138672315 100644
--- a/libs/vkd3d/command.c
+++ b/libs/vkd3d/command.c
@@ -4394,6 +4394,20 @@ uint32_t vkd3d_get_vk_queue_family_index(ID3D12CommandQueue *queue)
     return d3d12_queue->vkd3d_queue->vk_family_index;
 }
 
+VkQueue vkd3d_acquire_vk_queue(ID3D12CommandQueue *queue)
+{
+    struct d3d12_command_queue *d3d12_queue = impl_from_ID3D12CommandQueue(queue);
+
+    return vkd3d_queue_acquire(d3d12_queue->vkd3d_queue);
+}
+
+void vkd3d_release_vk_queue(ID3D12CommandQueue *queue)
+{
+    struct d3d12_command_queue *d3d12_queue = impl_from_ID3D12CommandQueue(queue);
+
+    return vkd3d_queue_release(d3d12_queue->vkd3d_queue);
+}
+
 /* ID3D12CommandSignature */
 static inline struct d3d12_command_signature *impl_from_ID3D12CommandSignature(ID3D12CommandSignature *iface)
 {
diff --git a/libs/vkd3d/vkd3d.map b/libs/vkd3d/vkd3d.map
index db638f6dd35c..57b8606e3f6f 100644
--- a/libs/vkd3d/vkd3d.map
+++ b/libs/vkd3d/vkd3d.map
@@ -1,5 +1,6 @@
 {
 global:
+    vkd3d_acquire_vk_queue;
     vkd3d_create_device;
     vkd3d_create_image_resource;
     vkd3d_create_instance;
@@ -12,6 +13,7 @@ global:
     vkd3d_get_vk_queue_family_index;
     vkd3d_instance_decref;
     vkd3d_instance_incref;
+    vkd3d_release_vk_queue;
     vkd3d_serialize_root_signature;
 
 local: *;
diff --git a/tests/vkd3d_api.c b/tests/vkd3d_api.c
index 79d51ccd36aa..146467a4f8f6 100644
--- a/tests/vkd3d_api.c
+++ b/tests/vkd3d_api.c
@@ -40,6 +40,33 @@ static const struct vkd3d_device_create_info device_default_create_info =
     .instance_create_info = &instance_default_create_info,
 };
 
+static ID3D12Device *create_device(void)
+{
+    ID3D12Device *device;
+    HRESULT hr;
+
+    hr = vkd3d_create_device(&device_default_create_info,
+            &IID_ID3D12Device, (void **)&device);
+    return SUCCEEDED(hr) ? device : NULL;
+}
+
+static ID3D12CommandQueue *create_command_queue(ID3D12Device *device,
+        D3D12_COMMAND_LIST_TYPE type)
+{
+    D3D12_COMMAND_QUEUE_DESC desc;
+    ID3D12CommandQueue *queue;
+    HRESULT hr;
+
+    desc.Type = type;
+    desc.Priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL;
+    desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
+    desc.NodeMask = 0;
+    hr = ID3D12Device_CreateCommandQueue(device, &desc,
+            &IID_ID3D12CommandQueue, (void **)&queue);
+    ok(hr == S_OK, "Failed to create command queue, hr %#x.\n", hr);
+    return queue;
+}
+
 static void test_create_instance(void)
 {
     struct vkd3d_instance_create_info create_info;
@@ -110,15 +137,55 @@ static void test_create_device(void)
     ok(!refcount, "Instance has %u references left.\n", refcount);
 }
 
+static void test_vkd3d_queue(void)
+{
+    ID3D12CommandQueue *direct_queue, *compute_queue, *copy_queue;
+    uint32_t vk_queue_family;
+    ID3D12Device *device;
+    VkQueue vk_queue;
+    ULONG refcount;
+
+    device = create_device();
+    ok(device, "Failed to create device.\n");
+
+    direct_queue = create_command_queue(device, D3D12_COMMAND_LIST_TYPE_DIRECT);
+    ok(direct_queue, "Failed to create direct command queue.\n");
+    compute_queue = create_command_queue(device, D3D12_COMMAND_LIST_TYPE_COMPUTE);
+    ok(compute_queue, "Failed to create direct command queue.\n");
+    copy_queue = create_command_queue(device, D3D12_COMMAND_LIST_TYPE_COPY);
+    ok(copy_queue, "Failed to create direct command queue.\n");
+
+    vk_queue_family = vkd3d_get_vk_queue_family_index(direct_queue);
+    trace("Direct queue family index %u.\n", vk_queue_family);
+    vk_queue_family = vkd3d_get_vk_queue_family_index(compute_queue);
+    trace("Compute queue family index %u.\n", vk_queue_family);
+    vk_queue_family = vkd3d_get_vk_queue_family_index(copy_queue);
+    trace("Copy queue family index %u.\n", vk_queue_family);
+
+    vk_queue = vkd3d_acquire_vk_queue(direct_queue);
+    ok(vk_queue != VK_NULL_HANDLE, "Failed to acquire Vulkan queue.\n");
+    vkd3d_release_vk_queue(direct_queue);
+    vk_queue = vkd3d_acquire_vk_queue(compute_queue);
+    ok(vk_queue != VK_NULL_HANDLE, "Failed to acquire Vulkan queue.\n");
+    vkd3d_release_vk_queue(compute_queue);
+    vk_queue = vkd3d_acquire_vk_queue(copy_queue);
+    ok(vk_queue != VK_NULL_HANDLE, "Failed to acquire Vulkan queue.\n");
+    vkd3d_release_vk_queue(copy_queue);
+
+    ID3D12CommandQueue_Release(direct_queue);
+    ID3D12CommandQueue_Release(compute_queue);
+    ID3D12CommandQueue_Release(copy_queue);
+    refcount = ID3D12Device_Release(device);
+    ok(!refcount, "Device has %u references left.\n", refcount);
+}
+
 static bool have_d3d12_device(void)
 {
     ID3D12Device *device;
-    HRESULT hr;
 
-    if (SUCCEEDED(hr = vkd3d_create_device(&device_default_create_info,
-            &IID_ID3D12Device, (void **)&device)))
+    if ((device = create_device()))
         ID3D12Device_Release(device);
-    return hr == S_OK;
+    return device;
 }
 
 START_TEST(vkd3d_api)
@@ -131,4 +198,5 @@ START_TEST(vkd3d_api)
 
     run_test(test_create_instance);
     run_test(test_create_device);
+    run_test(test_vkd3d_queue);
 }
-- 
2.13.6




More information about the wine-devel mailing list