[PATCH vkd3d 2/2] vkd3d: Use multiple command queues if available.
Conor McCarthy
cmccarthy at codeweavers.com
Thu Dec 12 06:31:12 CST 2019
Signed-off-by: Conor McCarthy <cmccarthy at codeweavers.com>
---
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
More information about the wine-devel
mailing list