Georg Lehmann : winevulkan: Fix queue creation with mixed queue flags.
Alexandre Julliard
julliard at winehq.org
Wed Apr 14 16:01:20 CDT 2021
Module: wine
Branch: master
Commit: 62cb6ace2cfe46358e6526868145a5bd8a7f990b
URL: https://source.winehq.org/git/wine.git/?a=commit;h=62cb6ace2cfe46358e6526868145a5bd8a7f990b
Author: Georg Lehmann <dadschoorse at gmail.com>
Date: Wed Apr 14 00:31:25 2021 +0200
winevulkan: Fix queue creation with mixed queue flags.
The Vulkan spec says:
The queueFamilyIndex member of each element of pQueueCreateInfos must be unique
within pQueueCreateInfos, except that two members can share the same
queueFamilyIndex if one is a protected-capable queue and one is not a
protected-capable queue.
Signed-off-by: Georg Lehmann <dadschoorse at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/winevulkan/vulkan.c | 84 +++++++++++++++++++++++-----------------
dlls/winevulkan/vulkan_private.h | 6 ++-
2 files changed, 52 insertions(+), 38 deletions(-)
diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c
index b186e425edb..9c322d75c76 100644
--- a/dlls/winevulkan/vulkan.c
+++ b/dlls/winevulkan/vulkan.c
@@ -310,25 +310,21 @@ static void wine_vk_free_command_buffers(struct VkDevice_T *device,
}
}
-static struct VkQueue_T *wine_vk_device_alloc_queues(struct VkDevice_T *device,
- uint32_t family_index, uint32_t queue_count, VkDeviceQueueCreateFlags flags)
+static void wine_vk_device_get_queues(struct VkDevice_T *device,
+ uint32_t family_index, uint32_t queue_count, VkDeviceQueueCreateFlags flags,
+ struct VkQueue_T* queues)
{
VkDeviceQueueInfo2 queue_info;
- struct VkQueue_T *queues;
unsigned int i;
- if (!(queues = calloc(queue_count, sizeof(*queues))))
- {
- ERR("Failed to allocate memory for queues\n");
- return NULL;
- }
-
for (i = 0; i < queue_count; i++)
{
struct VkQueue_T *queue = &queues[i];
queue->base.loader_magic = VULKAN_ICD_MAGIC_VALUE;
queue->device = device;
+ queue->family_index = family_index;
+ queue->queue_index = i;
queue->flags = flags;
/* The Vulkan spec says:
@@ -352,8 +348,6 @@ static struct VkQueue_T *wine_vk_device_alloc_queues(struct VkDevice_T *device,
WINE_VK_ADD_DISPATCHABLE_MAPPING(device->phys_dev->instance, queue, queue->queue);
}
-
- return queues;
}
static void wine_vk_device_free_create_info(VkDeviceCreateInfo *create_info)
@@ -425,17 +419,19 @@ static VkResult wine_vk_device_convert_create_info(const VkDeviceCreateInfo *src
*/
static void wine_vk_device_free(struct VkDevice_T *device)
{
+ struct VkQueue_T *queue;
+
if (!device)
return;
if (device->queues)
{
unsigned int i;
- for (i = 0; i < device->max_queue_families; i++)
+ for (i = 0; i < device->queue_count; i++)
{
- if (device->queues[i] && device->queues[i]->queue)
- WINE_VK_REMOVE_HANDLE_MAPPING(device->phys_dev->instance, device->queues[i]);
- free(device->queues[i]);
+ queue = &device->queues[i];
+ if (queue && queue->queue)
+ WINE_VK_REMOVE_HANDLE_MAPPING(device->phys_dev->instance, queue);
}
free(device->queues);
device->queues = NULL;
@@ -736,7 +732,7 @@ VkResult WINAPI wine_vkCreateDevice(VkPhysicalDevice phys_dev,
const VkAllocationCallbacks *allocator, VkDevice *device)
{
VkDeviceCreateInfo create_info_host;
- uint32_t max_queue_families;
+ struct VkQueue_T *next_queue;
struct VkDevice_T *object;
unsigned int i;
VkResult res;
@@ -791,17 +787,18 @@ VkResult WINAPI wine_vkCreateDevice(VkPhysicalDevice phys_dev,
/* We need to cache all queues within the device as each requires wrapping since queues are
* dispatchable objects.
*/
- phys_dev->instance->funcs.p_vkGetPhysicalDeviceQueueFamilyProperties(phys_dev->phys_dev,
- &max_queue_families, NULL);
- object->max_queue_families = max_queue_families;
- TRACE("Max queue families: %u.\n", object->max_queue_families);
+ for (i = 0; i < create_info_host.queueCreateInfoCount; i++)
+ {
+ object->queue_count += create_info_host.pQueueCreateInfos[i].queueCount;
+ }
- if (!(object->queues = calloc(max_queue_families, sizeof(*object->queues))))
+ if (!(object->queues = calloc(object->queue_count, sizeof(*object->queues))))
{
res = VK_ERROR_OUT_OF_HOST_MEMORY;
goto fail;
}
+ next_queue = object->queues;
for (i = 0; i < create_info_host.queueCreateInfoCount; i++)
{
uint32_t flags = create_info_host.pQueueCreateInfos[i].flags;
@@ -810,12 +807,8 @@ VkResult WINAPI wine_vkCreateDevice(VkPhysicalDevice phys_dev,
TRACE("Queue family index %u, queue count %u.\n", family_index, queue_count);
- if (!(object->queues[family_index] = wine_vk_device_alloc_queues(object, family_index, queue_count, flags)))
- {
- ERR("Failed to allocate memory for queues.\n");
- res = VK_ERROR_OUT_OF_HOST_MEMORY;
- goto fail;
- }
+ wine_vk_device_get_queues(object, family_index, queue_count, flags, next_queue);
+ next_queue += queue_count;
}
object->quirks = phys_dev->instance->quirks;
@@ -1071,17 +1064,42 @@ void WINAPI wine_vkFreeCommandBuffers(VkDevice device, VkCommandPool pool_handle
wine_vk_free_command_buffers(device, pool, count, buffers);
}
+static VkQueue wine_vk_device_find_queue(VkDevice device, const VkDeviceQueueInfo2 *info)
+{
+ struct VkQueue_T* queue;
+ uint32_t i;
+
+ for (i = 0; i < device->queue_count; i++)
+ {
+ queue = &device->queues[i];
+ if (queue->family_index == info->queueFamilyIndex
+ && queue->queue_index == info->queueIndex
+ && queue->flags == info->flags)
+ {
+ return queue;
+ }
+ }
+
+ return VK_NULL_HANDLE;
+}
+
void WINAPI wine_vkGetDeviceQueue(VkDevice device, uint32_t family_index,
uint32_t queue_index, VkQueue *queue)
{
+ VkDeviceQueueInfo2 queue_info;
TRACE("%p, %u, %u, %p\n", device, family_index, queue_index, queue);
- *queue = &device->queues[family_index][queue_index];
+ queue_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2;
+ queue_info.pNext = NULL;
+ queue_info.flags = 0;
+ queue_info.queueFamilyIndex = family_index;
+ queue_info.queueIndex = queue_index;
+
+ *queue = wine_vk_device_find_queue(device, &queue_info);
}
void WINAPI wine_vkGetDeviceQueue2(VkDevice device, const VkDeviceQueueInfo2 *info, VkQueue *queue)
{
- struct VkQueue_T *matching_queue;
const VkBaseInStructure *chain;
TRACE("%p, %p, %p\n", device, info, queue);
@@ -1089,13 +1107,7 @@ void WINAPI wine_vkGetDeviceQueue2(VkDevice device, const VkDeviceQueueInfo2 *in
if ((chain = info->pNext))
FIXME("Ignoring a linked structure of type %u.\n", chain->sType);
- matching_queue = &device->queues[info->queueFamilyIndex][info->queueIndex];
- if (matching_queue->flags != info->flags)
- {
- WARN("No matching flags were specified %#x, %#x.\n", matching_queue->flags, info->flags);
- matching_queue = VK_NULL_HANDLE;
- }
- *queue = matching_queue;
+ *queue = wine_vk_device_find_queue(device, info);
}
VkResult WINAPI wine_vkQueueSubmit(VkQueue queue, uint32_t count,
diff --git a/dlls/winevulkan/vulkan_private.h b/dlls/winevulkan/vulkan_private.h
index 1a44edb3c26..3f710a16a7b 100644
--- a/dlls/winevulkan/vulkan_private.h
+++ b/dlls/winevulkan/vulkan_private.h
@@ -89,8 +89,8 @@ struct VkDevice_T
struct VkPhysicalDevice_T *phys_dev; /* parent */
VkDevice device; /* native device */
- struct VkQueue_T **queues;
- uint32_t max_queue_families;
+ struct VkQueue_T* queues;
+ uint32_t queue_count;
unsigned int quirks;
@@ -155,6 +155,8 @@ struct VkQueue_T
struct VkDevice_T *device; /* parent */
VkQueue queue; /* native queue */
+ uint32_t family_index;
+ uint32_t queue_index;
VkDeviceQueueCreateFlags flags;
struct wine_vk_mapping mapping;
More information about the wine-cvs
mailing list