From 37f3da90dd3d9817aca17d83ddffbf449f023013 Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Mon, 7 Feb 2022 13:11:19 -0600 Subject: [PATCH] vulkan: Implement of a bunch of VkCommandPool functions Reviewed-by: Lionel Landwerlin Reviewed-by: Boris Brezillon Part-of: --- src/vulkan/runtime/vk_command_buffer.c | 3 + src/vulkan/runtime/vk_command_buffer.h | 11 +++ src/vulkan/runtime/vk_command_pool.c | 105 +++++++++++++++++++++++++ src/vulkan/runtime/vk_command_pool.h | 4 + 4 files changed, 123 insertions(+) diff --git a/src/vulkan/runtime/vk_command_buffer.c b/src/vulkan/runtime/vk_command_buffer.c index 6195d0a7a0b..160d9440c27 100644 --- a/src/vulkan/runtime/vk_command_buffer.c +++ b/src/vulkan/runtime/vk_command_buffer.c @@ -39,6 +39,8 @@ vk_command_buffer_init(struct vk_command_buffer *command_buffer, util_dynarray_init(&command_buffer->labels, NULL); command_buffer->region_begin = true; + list_add(&command_buffer->pool_link, &pool->command_buffers); + return VK_SUCCESS; } @@ -52,6 +54,7 @@ vk_command_buffer_reset(struct vk_command_buffer *command_buffer) void vk_command_buffer_finish(struct vk_command_buffer *command_buffer) { + list_del(&command_buffer->pool_link); util_dynarray_fini(&command_buffer->labels); vk_object_base_finish(&command_buffer->base); } diff --git a/src/vulkan/runtime/vk_command_buffer.h b/src/vulkan/runtime/vk_command_buffer.h index 5d3dc5d850a..6ad5c71baa2 100644 --- a/src/vulkan/runtime/vk_command_buffer.h +++ b/src/vulkan/runtime/vk_command_buffer.h @@ -25,6 +25,7 @@ #define VK_COMMAND_BUFFER_H #include "vk_object.h" +#include "util/list.h" #include "util/u_dynarray.h" #ifdef __cplusplus @@ -41,6 +42,16 @@ struct vk_command_buffer { /** VkCommandBufferAllocateInfo::level */ VkCommandBufferLevel level; + /** Link in vk_command_pool::command_buffers if pool != NULL */ + struct list_head pool_link; + + /** Destroys the command buffer + * + * Used by the common command pool implementation. This function MUST + * call vk_command_buffer_finish(). + */ + void (*destroy)(struct vk_command_buffer *); + /** * VK_EXT_debug_utils * diff --git a/src/vulkan/runtime/vk_command_pool.c b/src/vulkan/runtime/vk_command_pool.c index cfb18bb8150..f4f5ff4decb 100644 --- a/src/vulkan/runtime/vk_command_pool.c +++ b/src/vulkan/runtime/vk_command_pool.c @@ -24,8 +24,11 @@ #include "vk_command_pool.h" +#include "vk_alloc.h" +#include "vk_command_buffer.h" #include "vk_common_entrypoints.h" #include "vk_device.h" +#include "vk_log.h" VkResult MUST_CHECK vk_command_pool_init(struct vk_command_pool *pool, @@ -40,6 +43,7 @@ vk_command_pool_init(struct vk_command_pool *pool, pool->flags = pCreateInfo->flags; pool->queue_family_index = pCreateInfo->queueFamilyIndex; pool->alloc = pAllocator ? *pAllocator : device->alloc; + list_inithead(&pool->command_buffers); return VK_SUCCESS; } @@ -47,5 +51,106 @@ vk_command_pool_init(struct vk_command_pool *pool, void vk_command_pool_finish(struct vk_command_pool *pool) { + list_for_each_entry_safe(struct vk_command_buffer, cmd_buffer, + &pool->command_buffers, pool_link) { + cmd_buffer->destroy(cmd_buffer); + } + assert(list_is_empty(&pool->command_buffers)); + vk_object_base_finish(&pool->base); } + +VKAPI_ATTR VkResult VKAPI_CALL +vk_common_CreateCommandPool(VkDevice _device, + const VkCommandPoolCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkCommandPool *pCommandPool) +{ + VK_FROM_HANDLE(vk_device, device, _device); + struct vk_command_pool *pool; + VkResult result; + + pool = vk_alloc2(&device->alloc, pAllocator, sizeof(*pool), 8, + VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + if (pool == NULL) + return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); + + result = vk_command_pool_init(pool, device, pCreateInfo, pAllocator); + if (unlikely(result != VK_SUCCESS)) { + vk_free2(&device->alloc, pAllocator, pool); + return result; + } + + *pCommandPool = vk_command_pool_to_handle(pool); + + return VK_SUCCESS; +} + +VKAPI_ATTR void VKAPI_CALL +vk_common_DestroyCommandPool(VkDevice _device, + VkCommandPool commandPool, + const VkAllocationCallbacks *pAllocator) +{ + VK_FROM_HANDLE(vk_device, device, _device); + VK_FROM_HANDLE(vk_command_pool, pool, commandPool); + + if (pool == NULL) + return; + + vk_command_pool_finish(pool); + vk_free2(&device->alloc, pAllocator, pool); +} + +VKAPI_ATTR VkResult VKAPI_CALL +vk_common_ResetCommandPool(VkDevice device, + VkCommandPool commandPool, + VkCommandPoolResetFlags flags) +{ + VK_FROM_HANDLE(vk_command_pool, pool, commandPool); + const struct vk_device_dispatch_table *disp = + &pool->base.device->dispatch_table; + +#define COPY_FLAG(flag) \ + if (flags & VK_COMMAND_POOL_RESET_##flag) \ + cb_flags |= VK_COMMAND_BUFFER_RESET_##flag + + VkCommandBufferResetFlags cb_flags = 0; + COPY_FLAG(RELEASE_RESOURCES_BIT); + +#undef COPY_FLAG + + list_for_each_entry_safe(struct vk_command_buffer, cmd_buffer, + &pool->command_buffers, pool_link) { + VkResult result = + disp->ResetCommandBuffer(vk_command_buffer_to_handle(cmd_buffer), + cb_flags); + if (result != VK_SUCCESS) + return result; + } + + return VK_SUCCESS; +} + +VKAPI_ATTR void VKAPI_CALL +vk_common_FreeCommandBuffers(VkDevice device, + VkCommandPool commandPool, + uint32_t commandBufferCount, + const VkCommandBuffer *pCommandBuffers) +{ + for (uint32_t i = 0; i < commandBufferCount; i++) { + VK_FROM_HANDLE(vk_command_buffer, cmd_buffer, pCommandBuffers[i]); + + if (cmd_buffer == NULL) + continue; + + cmd_buffer->destroy(cmd_buffer); + } +} + +VKAPI_ATTR void VKAPI_CALL +vk_common_TrimCommandPool(VkDevice device, + VkCommandPool commandPool, + VkCommandPoolTrimFlags flags) +{ + /* No-op is a valid implementation but may not be optimal */ +} diff --git a/src/vulkan/runtime/vk_command_pool.h b/src/vulkan/runtime/vk_command_pool.h index 0eb43be45cd..9ee4154309b 100644 --- a/src/vulkan/runtime/vk_command_pool.h +++ b/src/vulkan/runtime/vk_command_pool.h @@ -25,6 +25,7 @@ #define VK_COMMAND_POOL_H #include "vk_object.h" +#include "util/list.h" #ifdef __cplusplus extern "C" { @@ -41,6 +42,9 @@ struct vk_command_pool { /** Allocator passed to vkCreateCommandPool() */ VkAllocationCallbacks alloc; + + /** List of all command buffers */ + struct list_head command_buffers; }; VK_DEFINE_NONDISP_HANDLE_CASTS(vk_command_pool, base, VkCommandPool,