vulkan: Add a common vkAllocateCommandBuffers() implementation
authorJason Ekstrand <jason.ekstrand@collabora.com>
Tue, 30 Aug 2022 18:08:40 +0000 (13:08 -0500)
committerMarge Bot <emma+marge@anholt.net>
Thu, 1 Sep 2022 20:17:25 +0000 (20:17 +0000)
Reviewed-by: Dave Airlie <airlied@redhat.com>
Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18324>

src/vulkan/runtime/vk_command_buffer.h
src/vulkan/runtime/vk_command_pool.c
src/vulkan/runtime/vk_command_pool.h
src/vulkan/runtime/vk_device.h

index 95c0259..6386460 100644 (file)
@@ -60,6 +60,17 @@ struct vk_attachment_state {
 };
 
 struct vk_command_buffer_ops {
+   /** Creates a command buffer
+    *
+    * Used by the common command pool implementation.  This function MUST
+    * call `vk_command_buffer_finish()`.  Notably, this function does not
+    * receive any additional parameters such as the level.  The level will be
+    * set by `vk_common_AllocateCommandBuffers()` and the driver must not rely
+    * on it until `vkBeginCommandBuffer()` time.
+    */
+   VkResult (*create)(struct vk_command_pool *,
+                      struct vk_command_buffer **);
+
    /** Resets the command buffer
     *
     * Used by the common command pool implementation.  This function MUST
index f9dec52..d4ff898 100644 (file)
@@ -43,6 +43,7 @@ vk_command_pool_init(struct vk_device *device,
    pool->flags = pCreateInfo->flags;
    pool->queue_family_index = pCreateInfo->queueFamilyIndex;
    pool->alloc = pAllocator ? *pAllocator : device->alloc;
+   pool->command_buffer_ops = device->command_buffer_ops;
    list_inithead(&pool->command_buffers);
 
    return VK_SUCCESS;
@@ -131,6 +132,41 @@ vk_common_ResetCommandPool(VkDevice device,
    return VK_SUCCESS;
 }
 
+VKAPI_ATTR VkResult VKAPI_CALL
+vk_common_AllocateCommandBuffers(VkDevice device,
+                                 const VkCommandBufferAllocateInfo *pAllocateInfo,
+                                 VkCommandBuffer *pCommandBuffers)
+{
+   VK_FROM_HANDLE(vk_command_pool, pool, pAllocateInfo->commandPool);
+   VkResult result;
+   uint32_t i;
+
+   assert(device == vk_device_to_handle(pool->base.device));
+
+   for (i = 0; i < pAllocateInfo->commandBufferCount; i++) {
+      struct vk_command_buffer *cmd_buffer;
+      result = pool->command_buffer_ops->create(pool, &cmd_buffer);
+      if (unlikely(result != VK_SUCCESS))
+         goto fail;
+
+      cmd_buffer->level = pAllocateInfo->level;
+
+      pCommandBuffers[i] = vk_command_buffer_to_handle(cmd_buffer);
+   }
+
+   return VK_SUCCESS;
+
+fail:
+   while (i--) {
+      VK_FROM_HANDLE(vk_command_buffer, cmd_buffer, pCommandBuffers[i]);
+      cmd_buffer->ops->destroy(cmd_buffer);
+   }
+   for (i = 0; i < pAllocateInfo->commandBufferCount; i++)
+      pCommandBuffers[i] = VK_NULL_HANDLE;
+
+   return result;
+}
+
 VKAPI_ATTR void VKAPI_CALL
 vk_common_FreeCommandBuffers(VkDevice device,
                              VkCommandPool commandPool,
index 08c0785..ca5e6b9 100644 (file)
@@ -43,6 +43,9 @@ struct vk_command_pool {
    /** Allocator passed to vkCreateCommandPool() */
    VkAllocationCallbacks alloc;
 
+   /** Command buffer vtable for command buffers allocated from this pool */
+   const struct vk_command_buffer_ops *command_buffer_ops;
+
    /** List of all command buffers */
    struct list_head command_buffers;
 };
index 52afa78..a408365 100644 (file)
@@ -34,6 +34,7 @@
 extern "C" {
 #endif
 
+struct vk_command_buffer_ops;
 struct vk_sync;
 
 enum vk_queue_submit_mode {
@@ -124,6 +125,9 @@ struct vk_device {
     */
    const struct vk_device_dispatch_table *command_dispatch_table;
 
+   /** Command buffer vtable when using the common command pool */
+   const struct vk_command_buffer_ops *command_buffer_ops;
+
    /* For VK_EXT_private_data */
    uint32_t private_data_next_index;