diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c index b95afda1..8e78756b 100644 --- a/libs/vkd3d/command.c +++ b/libs/vkd3d/command.c @@ -1765,7 +1765,7 @@ static HRESULT d3d12_command_allocator_init(struct d3d12_command_allocator *allo * Memory is owned by the pool and CommandBuffers become lightweight handles, * assuming a half-decent driver implementation. */ command_pool_info.flags = 0; - command_pool_info.queueFamilyIndex = queue->vk_family_index; + command_pool_info.queueFamilyIndex = queue_family->vk_family_index; if ((vr = VK_CALL(vkCreateCommandPool(device->vk_device, &command_pool_info, NULL, &allocator->vk_command_pool))) < 0) diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c index 85f60259..acd1c21d 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -1758,6 +1758,23 @@ static void d3d12_device_destroy_vkd3d_queues(struct d3d12_device *device) { unsigned int i, j; + for (i = 0; i < VKD3D_QUEUE_FAMILY_COUNT; i++) + { + struct vkd3d_queue_family_info *queue_family = device->queue_families[i]; + + if (!queue_family) + continue; + + /* Don't destroy the same queue family twice */ + for (j = i; j < VKD3D_QUEUE_FAMILY_COUNT; j++) + { + if (device->queue_families[j] == queue_family) + device->queue_families[j] = NULL; + } + + vkd3d_free(queue_family); + } + for (i = 0; i < VKD3D_QUEUE_FAMILY_COUNT; i++) { struct vkd3d_queue *queue = device->queues[i]; @@ -1785,6 +1802,7 @@ static HRESULT d3d12_device_create_vkd3d_queues(struct d3d12_device *device, device->unique_queue_mask = 0; device->queue_family_count = 0; memset(device->queues, 0, sizeof(device->queues)); + memset(device->queue_families, 0, sizeof(device->queue_families)); memset(device->queue_family_indices, 0, sizeof(device->queue_family_indices)); for (i = 0; i < VKD3D_QUEUE_FAMILY_COUNT; i++) @@ -1807,8 +1825,34 @@ static HRESULT d3d12_device_create_vkd3d_queues(struct d3d12_device *device, if (i != VKD3D_QUEUE_FAMILY_INTERNAL_COMPUTE) device->unique_queue_mask |= 1u << i; + } - device->queue_family_indices[device->queue_family_count++] = queue_info->family_index[i]; + for (i = 0; i < VKD3D_QUEUE_FAMILY_COUNT; i++) + { + struct vkd3d_queue_family_info *info; + + for (j = 0; j < i; j++) + { + if (queue_info->family_index[i] == queue_info->family_index[j]) + device->queue_families[i] = device->queue_families[j]; + } + + if (device->queue_families[i]) + continue; + + if (!(info = vkd3d_malloc(sizeof(*info)))) + { + hr = E_OUTOFMEMORY; + goto out_destroy_queues; + } + + info->queues = &device->queues[i]; + info->queue_count = 1; + info->vk_family_index = queue_info->family_index[i]; + info->vk_queue_flags = queue_info->vk_properties[i].queueFlags; + + device->queue_families[i] = info; + device->queue_family_indices[device->queue_family_count++] = info->vk_family_index; } return S_OK; diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index 63e61759..cadb2aca 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -2476,6 +2476,14 @@ enum vkd3d_queue_family VKD3D_QUEUE_FAMILY_COUNT }; +struct vkd3d_queue_family_info +{ + struct vkd3d_queue **queues; + uint32_t queue_count; + uint32_t vk_family_index; + VkQueueFlags vk_queue_flags; +}; + /* ID3D12Device */ typedef ID3D12Device6 d3d12_device_iface; @@ -2501,6 +2509,7 @@ struct d3d12_device struct vkd3d_physical_device_info device_info; struct vkd3d_queue *queues[VKD3D_QUEUE_FAMILY_COUNT]; + struct vkd3d_queue_family_info *queue_families[VKD3D_QUEUE_FAMILY_COUNT]; uint32_t queue_family_indices[VKD3D_QUEUE_FAMILY_COUNT]; unsigned int queue_family_count; uint32_t unique_queue_mask;