diff options
author | Lynne <[email protected]> | 2025-04-16 13:03:28 +0000 |
---|---|---|
committer | Lynne <[email protected]> | 2025-04-16 23:38:16 +0200 |
commit | bb3ce284d7cc99ddef9b2ceb00ec2db8b2c51338 (patch) | |
tree | c34dc9d0978d6d10cc0cb81b569d008da9a92c66 /libavutil/vulkan.c | |
parent | 36c6c66deb56dcad0ca50778069cd7ef4ded5f08 (diff) |
vulkan: use a single command buffer per command buffer pool
We violated the spec, which, despite the actual command buffer pool
*not* being involved in any functions which require external synchronization
of the pool, *require* external synchronization even if only the
command buffers are used.
This also has the effect of *significantly* speeding up execution
in case command buffers are contended.
Diffstat (limited to 'libavutil/vulkan.c')
-rw-r--r-- | libavutil/vulkan.c | 78 |
1 files changed, 46 insertions, 32 deletions
diff --git a/libavutil/vulkan.c b/libavutil/vulkan.c index d880d52272..8f444b2dfe 100644 --- a/libavutil/vulkan.c +++ b/libavutil/vulkan.c @@ -280,15 +280,19 @@ void ff_vk_exec_pool_free(FFVulkanContext *s, FFVkExecPool *pool) av_freep(&sd->desc_sets); } - if (pool->cmd_bufs) - vk->FreeCommandBuffers(s->hwctx->act_dev, pool->cmd_buf_pool, - pool->pool_size, pool->cmd_bufs); - if (pool->cmd_buf_pool) - vk->DestroyCommandPool(s->hwctx->act_dev, pool->cmd_buf_pool, s->hwctx->alloc); + for (int i = 0; i < pool->pool_size; i++) { + if (pool->cmd_buf_pools[i]) + vk->FreeCommandBuffers(s->hwctx->act_dev, pool->cmd_buf_pools[i], + 1, &pool->cmd_bufs[i]); + + if (pool->cmd_buf_pools[i]) + vk->DestroyCommandPool(s->hwctx->act_dev, pool->cmd_buf_pools[i], s->hwctx->alloc); + } if (pool->query_pool) vk->DestroyQueryPool(s->hwctx->act_dev, pool->query_pool, s->hwctx->alloc); av_free(pool->query_data); + av_free(pool->cmd_buf_pools); av_free(pool->cmd_bufs); av_free(pool->contexts); } @@ -316,19 +320,10 @@ int ff_vk_exec_pool_init(FFVulkanContext *s, AVVulkanDeviceQueueFamily *qf, return AVERROR(EINVAL); } - /* Create command pool */ - cqueue_create = (VkCommandPoolCreateInfo) { - .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, - .flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT | - VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, - .queueFamilyIndex = qf->idx, - }; - ret = vk->CreateCommandPool(s->hwctx->act_dev, &cqueue_create, - s->hwctx->alloc, &pool->cmd_buf_pool); - if (ret != VK_SUCCESS) { - av_log(s, AV_LOG_ERROR, "Command pool creation failure: %s\n", - ff_vk_ret2str(ret)); - err = AVERROR_EXTERNAL; + /* Allocate space for command buffer pools */ + pool->cmd_buf_pools = av_malloc(nb_contexts*sizeof(*pool->cmd_buf_pools)); + if (!pool->cmd_buf_pools) { + err = AVERROR(ENOMEM); goto fail; } @@ -339,20 +334,39 @@ int ff_vk_exec_pool_init(FFVulkanContext *s, AVVulkanDeviceQueueFamily *qf, goto fail; } - /* Allocate command buffer */ - cbuf_create = (VkCommandBufferAllocateInfo) { - .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, - .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY, - .commandPool = pool->cmd_buf_pool, - .commandBufferCount = nb_contexts, - }; - ret = vk->AllocateCommandBuffers(s->hwctx->act_dev, &cbuf_create, - pool->cmd_bufs); - if (ret != VK_SUCCESS) { - av_log(s, AV_LOG_ERROR, "Command buffer alloc failure: %s\n", - ff_vk_ret2str(ret)); - err = AVERROR_EXTERNAL; - goto fail; + for (int i = 0; i < nb_contexts; i++) { + /* Create command pool */ + cqueue_create = (VkCommandPoolCreateInfo) { + .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, + .flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT | + VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, + .queueFamilyIndex = qf->idx, + }; + + ret = vk->CreateCommandPool(s->hwctx->act_dev, &cqueue_create, + s->hwctx->alloc, &pool->cmd_buf_pools[i]); + if (ret != VK_SUCCESS) { + av_log(s, AV_LOG_ERROR, "Command pool creation failure: %s\n", + ff_vk_ret2str(ret)); + err = AVERROR_EXTERNAL; + goto fail; + } + + /* Allocate command buffer */ + cbuf_create = (VkCommandBufferAllocateInfo) { + .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, + .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY, + .commandPool = pool->cmd_buf_pools[i], + .commandBufferCount = 1, + }; + ret = vk->AllocateCommandBuffers(s->hwctx->act_dev, &cbuf_create, + &pool->cmd_bufs[i]); + if (ret != VK_SUCCESS) { + av_log(s, AV_LOG_ERROR, "Command buffer alloc failure: %s\n", + ff_vk_ret2str(ret)); + err = AVERROR_EXTERNAL; + goto fail; + } } /* Query pool */ |