vulkan/device: Add a common GetDeviceQueue2 implementation

If we store the queues in a linked list in the device as vk_queue_init
is called then we can handle enumeration in common code.

Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13003>
This commit is contained in:
Jason Ekstrand 2021-09-23 12:18:08 -05:00 committed by Marge Bot
parent 0d80799ccd
commit 3b535d28d2
4 changed files with 55 additions and 0 deletions

View File

@ -26,6 +26,7 @@
#include "vk_common_entrypoints.h"
#include "vk_instance.h"
#include "vk_physical_device.h"
#include "vk_queue.h"
#include "vk_util.h"
#include "util/hash_table.h"
#include "util/ralloc.h"
@ -76,6 +77,8 @@ vk_device_init(struct vk_device *device,
p_atomic_set(&device->private_data_next_index, 0);
list_inithead(&device->queues);
#ifdef ANDROID
mtx_init(&device->swapchain_private_mtx, mtx_plain);
device->swapchain_private = NULL;
@ -87,6 +90,9 @@ vk_device_init(struct vk_device *device,
void
vk_device_finish(UNUSED struct vk_device *device)
{
/* Drivers should tear down their own queues */
assert(list_is_empty(&device->queues));
#ifdef ANDROID
if (device->swapchain_private) {
hash_table_foreach(device->swapchain_private, entry)
@ -147,6 +153,35 @@ vk_common_GetDeviceQueue(VkDevice _device,
device->dispatch_table.GetDeviceQueue2(_device, &info, pQueue);
}
VKAPI_ATTR void VKAPI_CALL
vk_common_GetDeviceQueue2(VkDevice _device,
const VkDeviceQueueInfo2 *pQueueInfo,
VkQueue *pQueue)
{
VK_FROM_HANDLE(vk_device, device, _device);
struct vk_queue *queue = NULL;
vk_foreach_queue(iter, device) {
if (iter->queue_family_index == pQueueInfo->queueFamilyIndex &&
iter->index_in_family == pQueueInfo->queueIndex) {
queue = iter;
break;
}
}
/* From the Vulkan 1.1.70 spec:
*
* "The queue returned by vkGetDeviceQueue2 must have the same flags
* value from this structure as that used at device creation time in a
* VkDeviceQueueCreateInfo instance. If no matching flags were specified
* at device creation time then pQueue will return VK_NULL_HANDLE."
*/
if (queue && queue->flags == pQueueInfo->flags)
*pQueue = vk_queue_to_handle(queue);
else
*pQueue = VK_NULL_HANDLE;
}
VKAPI_ATTR void VKAPI_CALL
vk_common_GetBufferMemoryRequirements(VkDevice _device,
VkBuffer buffer,

View File

@ -27,6 +27,8 @@
#include "vk_extensions.h"
#include "vk_object.h"
#include "util/list.h"
#ifdef __cplusplus
extern "C" {
#endif
@ -43,6 +45,8 @@ struct vk_device {
/* For VK_EXT_private_data */
uint32_t private_data_next_index;
struct list_head queues;
#ifdef ANDROID
mtx_t swapchain_private_mtx;
struct hash_table *swapchain_private;

View File

@ -23,6 +23,8 @@
#include "vk_queue.h"
#include "vk_device.h"
VkResult
vk_queue_init(struct vk_queue *queue, struct vk_device *device,
const VkDeviceQueueCreateInfo *pCreateInfo,
@ -31,6 +33,8 @@ vk_queue_init(struct vk_queue *queue, struct vk_device *device,
memset(queue, 0, sizeof(*queue));
vk_object_base_init(device, &queue->base, VK_OBJECT_TYPE_QUEUE);
list_addtail(&queue->link, &device->queues);
queue->flags = pCreateInfo->flags;
queue->queue_family_index = pCreateInfo->queueFamilyIndex;
@ -47,5 +51,6 @@ void
vk_queue_finish(struct vk_queue *queue)
{
util_dynarray_fini(&queue->labels);
list_del(&queue->link);
vk_object_base_finish(&queue->base);
}

View File

@ -25,6 +25,8 @@
#define VK_QUEUE_H
#include "vk_object.h"
#include "util/list.h"
#include "util/u_dynarray.h"
#ifdef __cplusplus
@ -34,6 +36,9 @@ extern "C" {
struct vk_queue {
struct vk_object_base base;
/* Link in vk_device::queues */
struct list_head link;
/* VkDeviceQueueCreateInfo::flags */
VkDeviceQueueCreateFlags flags;
@ -94,6 +99,12 @@ vk_queue_init(struct vk_queue *queue, struct vk_device *device,
void
vk_queue_finish(struct vk_queue *queue);
#define vk_foreach_queue(queue, device) \
list_for_each_entry(struct vk_queue, queue, &(device)->queues, link)
#define vk_foreach_queue_safe(queue, device) \
list_for_each_entry_safe(struct vk_queue, queue, &(device)->queues, link)
#ifdef __cplusplus
}
#endif