Module: Mesa
Branch: main
Commit: 3b535d28d2f31455682c09886ebe49ccb99a2ed6
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=3b535d28d2f31455682c09886ebe49ccb99a2ed6

Author: Jason Ekstrand <[email protected]>
Date:   Thu Sep 23 12:18:08 2021 -0500

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 <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13003>

---

 src/vulkan/util/vk_device.c | 35 +++++++++++++++++++++++++++++++++++
 src/vulkan/util/vk_device.h |  4 ++++
 src/vulkan/util/vk_queue.c  |  5 +++++
 src/vulkan/util/vk_queue.h  | 11 +++++++++++
 4 files changed, 55 insertions(+)

diff --git a/src/vulkan/util/vk_device.c b/src/vulkan/util/vk_device.c
index c00a952c3b8..d3ac4df0e18 100644
--- a/src/vulkan/util/vk_device.c
+++ b/src/vulkan/util/vk_device.c
@@ -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,
diff --git a/src/vulkan/util/vk_device.h b/src/vulkan/util/vk_device.h
index dbf261ed4b4..3bb0347e018 100644
--- a/src/vulkan/util/vk_device.h
+++ b/src/vulkan/util/vk_device.h
@@ -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;
diff --git a/src/vulkan/util/vk_queue.c b/src/vulkan/util/vk_queue.c
index aa4eb3f838f..d1c0351ce35 100644
--- a/src/vulkan/util/vk_queue.c
+++ b/src/vulkan/util/vk_queue.c
@@ -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);
 }
diff --git a/src/vulkan/util/vk_queue.h b/src/vulkan/util/vk_queue.h
index 2f808024c8f..1a63b1f9d80 100644
--- a/src/vulkan/util/vk_queue.h
+++ b/src/vulkan/util/vk_queue.h
@@ -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

Reply via email to