From 11f33234927356c33e157a67aa6118f94c04976b Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Tue, 30 Aug 2022 13:08:40 -0500 Subject: [PATCH] vulkan: Add a common vkAllocateCommandBuffers() implementation Reviewed-by: Dave Airlie Reviewed-by: Samuel Pitoiset Part-of: --- src/vulkan/runtime/vk_command_buffer.h | 11 ++++++++ src/vulkan/runtime/vk_command_pool.c | 36 ++++++++++++++++++++++++++ src/vulkan/runtime/vk_command_pool.h | 3 +++ src/vulkan/runtime/vk_device.h | 4 +++ 4 files changed, 54 insertions(+) diff --git a/src/vulkan/runtime/vk_command_buffer.h b/src/vulkan/runtime/vk_command_buffer.h index 95c02593a42..63864600628 100644 --- a/src/vulkan/runtime/vk_command_buffer.h +++ b/src/vulkan/runtime/vk_command_buffer.h @@ -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 diff --git a/src/vulkan/runtime/vk_command_pool.c b/src/vulkan/runtime/vk_command_pool.c index f9dec529f92..d4ff898f9b3 100644 --- a/src/vulkan/runtime/vk_command_pool.c +++ b/src/vulkan/runtime/vk_command_pool.c @@ -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, diff --git a/src/vulkan/runtime/vk_command_pool.h b/src/vulkan/runtime/vk_command_pool.h index 08c0785179f..ca5e6b92fc8 100644 --- a/src/vulkan/runtime/vk_command_pool.h +++ b/src/vulkan/runtime/vk_command_pool.h @@ -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; }; diff --git a/src/vulkan/runtime/vk_device.h b/src/vulkan/runtime/vk_device.h index 52afa783090..a4083656b2d 100644 --- a/src/vulkan/runtime/vk_device.h +++ b/src/vulkan/runtime/vk_device.h @@ -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;