=?UTF-8?Q?J=C3=B3zef=20Kucia=20?=: libs/vkd3d: Add thread-safe API for accessing Vulkan command queues.
Alexandre Julliard
julliard at winehq.org
Mon Jan 15 10:54:12 CST 2018
Module: vkd3d
Branch: master
Commit: 12ca2bbcf62166f6ddda19419dc1cb8e9e094946
URL: https://source.winehq.org/git/vkd3d.git/?a=commit;h=12ca2bbcf62166f6ddda19419dc1cb8e9e094946
Author: Józef Kucia <jkucia at codeweavers.com>
Date: Mon Jan 15 13:49:07 2018 +0100
libs/vkd3d: Add thread-safe API for accessing Vulkan command queues.
Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
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 3cc2c54..a683dca 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 8a04dbd..322675b 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 85dcf6f..7aa1386 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 db638f6..57b8606 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 79d51cc..146467a 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);
}
More information about the wine-cvs
mailing list