libs/vkd3d: Add thread-safe API for accessing Vulkan command queues.

Signed-off-by: Józef Kucia <jkucia@codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Józef Kucia 2018-01-15 13:49:07 +01:00 committed by Alexandre Julliard
parent 8357908bc2
commit 12ca2bbcf6
5 changed files with 99 additions and 8 deletions

View File

@ -61,7 +61,7 @@ struct demo_swapchain
VkInstance vk_instance; VkInstance vk_instance;
VkDevice vk_device; VkDevice vk_device;
VkQueue vk_queue; ID3D12CommandQueue *command_queue;
uint32_t current_buffer; uint32_t current_buffer;
unsigned int buffer_count; 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_fence = vk_fence;
swapchain->vk_instance = vk_instance; swapchain->vk_instance = vk_instance;
swapchain->vk_device = vk_device; swapchain->vk_device = vk_device;
swapchain->vk_queue = vkd3d_get_vk_queue(command_queue);
vkAcquireNextImageKHR(vk_device, vk_swapchain, UINT64_MAX, vkAcquireNextImageKHR(vk_device, vk_swapchain, UINT64_MAX,
VK_NULL_HANDLE, vk_fence, &swapchain->current_buffer); 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); free(vk_images);
ID3D12Device_Release(d3d12_device); ID3D12Device_Release(d3d12_device);
ID3D12CommandQueue_AddRef(swapchain->command_queue = command_queue);
return swapchain; return swapchain;
fail: 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) static inline void demo_swapchain_present(struct demo_swapchain *swapchain)
{ {
VkPresentInfoKHR present_desc; VkPresentInfoKHR present_desc;
VkQueue vk_queue;
present_desc.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; present_desc.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
present_desc.pNext = NULL; 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.pImageIndices = &swapchain->current_buffer;
present_desc.pResults = NULL; 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, vkAcquireNextImageKHR(swapchain->vk_device, swapchain->vk_swapchain, UINT64_MAX,
VK_NULL_HANDLE, swapchain->vk_fence, &swapchain->current_buffer); 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; unsigned int i;
ID3D12CommandQueue_Release(swapchain->command_queue);
for (i = 0; i < swapchain->buffer_count; ++i) for (i = 0; i < swapchain->buffer_count; ++i)
{ {
ID3D12Resource_Release(swapchain->buffers[i]); ID3D12Resource_Release(swapchain->buffers[i]);

View File

@ -73,8 +73,10 @@ VkDevice vkd3d_get_vk_device(ID3D12Device *device);
VkInstance vkd3d_get_vk_instance(ID3D12Device *device); VkInstance vkd3d_get_vk_instance(ID3D12Device *device);
VkPhysicalDevice vkd3d_get_vk_physical_device(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); 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, HRESULT vkd3d_serialize_root_signature(const D3D12_ROOT_SIGNATURE_DESC *root_signature_desc,
D3D_ROOT_SIGNATURE_VERSION version, ID3DBlob **blob, ID3DBlob **error_blob); D3D_ROOT_SIGNATURE_VERSION version, ID3DBlob **blob, ID3DBlob **error_blob);

View File

@ -4394,6 +4394,20 @@ uint32_t vkd3d_get_vk_queue_family_index(ID3D12CommandQueue *queue)
return d3d12_queue->vkd3d_queue->vk_family_index; 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 */ /* ID3D12CommandSignature */
static inline struct d3d12_command_signature *impl_from_ID3D12CommandSignature(ID3D12CommandSignature *iface) static inline struct d3d12_command_signature *impl_from_ID3D12CommandSignature(ID3D12CommandSignature *iface)
{ {

View File

@ -1,5 +1,6 @@
{ {
global: global:
vkd3d_acquire_vk_queue;
vkd3d_create_device; vkd3d_create_device;
vkd3d_create_image_resource; vkd3d_create_image_resource;
vkd3d_create_instance; vkd3d_create_instance;
@ -12,6 +13,7 @@ global:
vkd3d_get_vk_queue_family_index; vkd3d_get_vk_queue_family_index;
vkd3d_instance_decref; vkd3d_instance_decref;
vkd3d_instance_incref; vkd3d_instance_incref;
vkd3d_release_vk_queue;
vkd3d_serialize_root_signature; vkd3d_serialize_root_signature;
local: *; local: *;

View File

@ -40,6 +40,33 @@ static const struct vkd3d_device_create_info device_default_create_info =
.instance_create_info = &instance_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) static void test_create_instance(void)
{ {
struct vkd3d_instance_create_info create_info; 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); 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) static bool have_d3d12_device(void)
{ {
ID3D12Device *device; ID3D12Device *device;
HRESULT hr;
if (SUCCEEDED(hr = vkd3d_create_device(&device_default_create_info, if ((device = create_device()))
&IID_ID3D12Device, (void **)&device)))
ID3D12Device_Release(device); ID3D12Device_Release(device);
return hr == S_OK; return device;
} }
START_TEST(vkd3d_api) START_TEST(vkd3d_api)
@ -131,4 +198,5 @@ START_TEST(vkd3d_api)
run_test(test_create_instance); run_test(test_create_instance);
run_test(test_create_device); run_test(test_create_device);
run_test(test_vkd3d_queue);
} }