From: Conor McCarthy Subject: [PATCH vkd3d 2/2] vkd3d: Use multiple command queues if available. Message-Id: <20191212123112.4142-2-cmccarthy@codeweavers.com> Date: Thu, 12 Dec 2019 22:31:12 +1000 In-Reply-To: <20191212123112.4142-1-cmccarthy@codeweavers.com> References: <20191212123112.4142-1-cmccarthy@codeweavers.com> Signed-off-by: Conor McCarthy --- libs/vkd3d/command.c | 24 +++++++---- libs/vkd3d/device.c | 84 ++++++++++++++++++++++++-------------- libs/vkd3d/vkd3d_private.h | 16 ++++++-- 3 files changed, 83 insertions(+), 41 deletions(-) diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c index 8a7ff66..6b0d9e0 100644 --- a/libs/vkd3d/command.c +++ b/libs/vkd3d/command.c @@ -22,7 +22,8 @@ static HRESULT d3d12_fence_signal(struct d3d12_fence *fence, uint64_t value, VkFence vk_fence); HRESULT vkd3d_queue_create(struct d3d12_device *device, - uint32_t family_index, const VkQueueFamilyProperties *properties, struct vkd3d_queue **queue) + uint32_t family_index, const VkQueueFamilyProperties *properties, + struct vkd3d_queue_array *queue_array, uint32_t queue_index) { const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; struct vkd3d_queue *object; @@ -51,11 +52,11 @@ HRESULT vkd3d_queue_create(struct d3d12_device *device, memset(object->old_vk_semaphores, 0, sizeof(object->old_vk_semaphores)); - VK_CALL(vkGetDeviceQueue(device->vk_device, family_index, 0, &object->vk_queue)); + VK_CALL(vkGetDeviceQueue(device->vk_device, family_index, queue_index, &object->vk_queue)); TRACE("Created queue %p for queue family index %u.\n", object, family_index); - *queue = object; + queue_array->queues[queue_index] = object; return S_OK; } @@ -1683,17 +1684,26 @@ static struct d3d12_command_allocator *unsafe_impl_from_ID3D12CommandAllocator(I return impl_from_ID3D12CommandAllocator(iface); } +static struct vkd3d_queue *d3d12_device_get_next_vkd3d_queue(struct vkd3d_queue_array *queue_array) +{ + LONG i = (InterlockedIncrement(queue_array->index_ptr) - 1) % VKD3D_MAX_QUEUE_CREATE_COUNT; + struct vkd3d_queue *queue = queue_array->queues[i]; + if (queue) + return queue; + return queue_array->queues[0]; +} + struct vkd3d_queue *d3d12_device_get_vkd3d_queue(struct d3d12_device *device, D3D12_COMMAND_LIST_TYPE type) { switch (type) { case D3D12_COMMAND_LIST_TYPE_DIRECT: - return device->direct_queue; + return d3d12_device_get_next_vkd3d_queue(&device->direct_queues); case D3D12_COMMAND_LIST_TYPE_COMPUTE: - return device->compute_queue; + return d3d12_device_get_next_vkd3d_queue(&device->compute_queues); case D3D12_COMMAND_LIST_TYPE_COPY: - return device->copy_queue; + return d3d12_device_get_next_vkd3d_queue(&device->copy_queues); default: FIXME("Unhandled command list type %#x.\n", type); return NULL; @@ -1713,7 +1723,7 @@ static HRESULT d3d12_command_allocator_init(struct d3d12_command_allocator *allo return hr; if (!(queue = d3d12_device_get_vkd3d_queue(device, type))) - queue = device->direct_queue; + queue = device->direct_queues.queues[0]; allocator->ID3D12CommandAllocator_iface.lpVtbl = &d3d12_command_allocator_vtbl; allocator->refcount = 1; diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c index ad32ff2..ff5dad1 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -1538,17 +1538,48 @@ struct vkd3d_device_queue_info static void d3d12_device_destroy_vkd3d_queues(struct d3d12_device *device) { - if (device->direct_queue) - vkd3d_queue_destroy(device->direct_queue, device); - if (device->compute_queue && device->compute_queue != device->direct_queue) - vkd3d_queue_destroy(device->compute_queue, device); - if (device->copy_queue && device->copy_queue != device->direct_queue - && device->copy_queue != device->compute_queue) - vkd3d_queue_destroy(device->copy_queue, device); + struct vkd3d_queue_array *direct_queues = &device->direct_queues; + struct vkd3d_queue_array *compute_queues = &device->compute_queues; + struct vkd3d_queue_array *copy_queues = &device->copy_queues; + size_t i; - device->direct_queue = NULL; - device->compute_queue = NULL; - device->copy_queue = NULL; + for (i = 0; i < ARRAY_SIZE(direct_queues->queues); ++i) + { + if (direct_queues->queues[i]) + vkd3d_queue_destroy(direct_queues->queues[i], device); + if (compute_queues->queues[i] && compute_queues->queues[i] != direct_queues->queues[i]) + vkd3d_queue_destroy(compute_queues->queues[i], device); + if (copy_queues->queues[i] && copy_queues->queues[i] != direct_queues->queues[i] + && copy_queues->queues[i] != compute_queues->queues[i]) + vkd3d_queue_destroy(copy_queues->queues[i], device); + direct_queues->queues[i] = NULL; + compute_queues->queues[i] = NULL; + copy_queues->queues[i] = NULL; + } +} + +static HRESULT d3d12_device_create_family_queues(struct d3d12_device *device, + const struct vkd3d_device_queue_info *queue_info, enum vkd3d_queue_family family, + struct vkd3d_queue_array *queue_array) +{ + uint32_t family_index = queue_info->family_index[family]; + uint32_t i, count; + HRESULT hr; + + queue_array->index_ptr = &queue_array->index; + + count = min(queue_info->vk_properties[family].queueCount, VKD3D_MAX_QUEUE_CREATE_COUNT); + + for (i = 0; i < count; ++i) + { + if (FAILED(hr = vkd3d_queue_create(device, family_index, + &queue_info->vk_properties[family], queue_array, i))) + return hr; + } + + device->queue_family_indices[device->queue_family_count++] = family_index; + + return S_OK; } static HRESULT d3d12_device_create_vkd3d_queues(struct d3d12_device *device, @@ -1559,35 +1590,27 @@ static HRESULT d3d12_device_create_vkd3d_queues(struct d3d12_device *device, uint32_t direct_family_index = queue_info->family_index[VKD3D_QUEUE_FAMILY_DIRECT]; HRESULT hr; - device->direct_queue = NULL; - device->compute_queue = NULL; - device->copy_queue = NULL; + memset(&device->direct_queues, 0, sizeof(device->direct_queues)); + memset(&device->compute_queues, 0, sizeof(device->compute_queues)); + memset(&device->copy_queues, 0, sizeof(device->copy_queues)); device->queue_family_count = 0; memset(device->queue_family_indices, 0, sizeof(device->queue_family_indices)); - if (SUCCEEDED((hr = vkd3d_queue_create(device, direct_family_index, - &queue_info->vk_properties[VKD3D_QUEUE_FAMILY_DIRECT], &device->direct_queue)))) - device->queue_family_indices[device->queue_family_count++] = direct_family_index; - else + if (FAILED(hr = d3d12_device_create_family_queues(device, queue_info, VKD3D_QUEUE_FAMILY_DIRECT, &device->direct_queues))) goto out_destroy_queues; + /* A binary copy points index_ptr to the index in the source object, which is the desired behaviour. */ if (compute_family_index == direct_family_index) - device->compute_queue = device->direct_queue; - else if (SUCCEEDED(hr = vkd3d_queue_create(device, compute_family_index, - &queue_info->vk_properties[VKD3D_QUEUE_FAMILY_COMPUTE], &device->compute_queue))) - device->queue_family_indices[device->queue_family_count++] = compute_family_index; - else + memcpy(&device->compute_queues, &device->direct_queues, sizeof(device->compute_queues)); + else if (FAILED(hr = d3d12_device_create_family_queues(device, queue_info, VKD3D_QUEUE_FAMILY_COMPUTE, &device->compute_queues))) goto out_destroy_queues; if (transfer_family_index == direct_family_index) - device->copy_queue = device->direct_queue; + memcpy(&device->copy_queues, &device->direct_queues, sizeof(device->copy_queues)); else if (transfer_family_index == compute_family_index) - device->copy_queue = device->compute_queue; - else if (SUCCEEDED(hr = vkd3d_queue_create(device, transfer_family_index, - &queue_info->vk_properties[VKD3D_QUEUE_FAMILY_TRANSFER], &device->copy_queue))) - device->queue_family_indices[device->queue_family_count++] = transfer_family_index; - else + memcpy(&device->copy_queues, &device->compute_queues, sizeof(device->copy_queues)); + else if (FAILED(hr = d3d12_device_create_family_queues(device, queue_info, VKD3D_QUEUE_FAMILY_TRANSFER, &device->copy_queues))) goto out_destroy_queues; return S_OK; @@ -1597,7 +1620,8 @@ out_destroy_queues: return hr; } -static float queue_priorities[] = {1.0f}; +static float queue_priorities[] = {1.0f, 1.0f, 1.0f, 1.0f}; +STATIC_ASSERT(ARRAY_SIZE(queue_priorities) == VKD3D_MAX_QUEUE_CREATE_COUNT); static HRESULT vkd3d_select_queues(const struct vkd3d_instance *vkd3d_instance, VkPhysicalDevice physical_device, struct vkd3d_device_queue_info *info) @@ -1647,7 +1671,7 @@ static HRESULT vkd3d_select_queues(const struct vkd3d_instance *vkd3d_instance, queue_info->pNext = NULL; queue_info->flags = 0; queue_info->queueFamilyIndex = i; - queue_info->queueCount = 1; /* FIXME: Use multiple queues. */ + queue_info->queueCount = min(queue_properties[i].queueCount, VKD3D_MAX_QUEUE_CREATE_COUNT); queue_info->pQueuePriorities = queue_priorities; } diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index 0c031d2..382b5ca 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -50,6 +50,7 @@ #define VKD3D_MAX_COMPATIBLE_FORMAT_COUNT 6u #define VKD3D_MAX_QUEUE_FAMILY_COUNT 3u +#define VKD3D_MAX_QUEUE_CREATE_COUNT 4u #define VKD3D_MAX_SHADER_EXTENSIONS 1u #define VKD3D_MAX_SHADER_STAGES 5u #define VKD3D_MAX_VK_SYNC_OBJECTS 4u @@ -1003,10 +1004,17 @@ struct vkd3d_queue VkSemaphore old_vk_semaphores[VKD3D_MAX_VK_SYNC_OBJECTS]; }; +struct vkd3d_queue_array +{ + struct vkd3d_queue *queues[VKD3D_MAX_QUEUE_CREATE_COUNT]; + LONG *index_ptr; + LONG index; +}; + VkQueue vkd3d_queue_acquire(struct vkd3d_queue *queue) DECLSPEC_HIDDEN; HRESULT vkd3d_queue_create(struct d3d12_device *device, uint32_t family_index, const VkQueueFamilyProperties *properties, - struct vkd3d_queue **queue) DECLSPEC_HIDDEN; + struct vkd3d_queue_array *queue_array, uint32_t queue_index) DECLSPEC_HIDDEN; void vkd3d_queue_destroy(struct vkd3d_queue *queue, struct d3d12_device *device) DECLSPEC_HIDDEN; void vkd3d_queue_release(struct vkd3d_queue *queue) DECLSPEC_HIDDEN; @@ -1134,9 +1142,9 @@ struct d3d12_device struct vkd3d_vulkan_info vk_info; - struct vkd3d_queue *direct_queue; - struct vkd3d_queue *compute_queue; - struct vkd3d_queue *copy_queue; + struct vkd3d_queue_array direct_queues; + struct vkd3d_queue_array compute_queues; + struct vkd3d_queue_array copy_queues; uint32_t queue_family_indices[VKD3D_MAX_QUEUE_FAMILY_COUNT]; unsigned int queue_family_count; -- 2.24.0