* [FFmpeg-devel] [PATCH] vulkan: use a single command buffer per command buffer pool
@ 2025-04-16 13:26 Lynne
2025-04-17 8:11 ` Jerome Martinez
0 siblings, 1 reply; 2+ messages in thread
From: Lynne @ 2025-04-16 13:26 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Lynne
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.
---
libavutil/hwcontext_vulkan.c | 1 -
libavutil/vulkan.c | 78 +++++++++++++++++++++---------------
libavutil/vulkan.h | 2 +-
3 files changed, 47 insertions(+), 34 deletions(-)
diff --git a/libavutil/hwcontext_vulkan.c b/libavutil/hwcontext_vulkan.c
index 32203b2f06..d7822d4629 100644
--- a/libavutil/hwcontext_vulkan.c
+++ b/libavutil/hwcontext_vulkan.c
@@ -673,7 +673,6 @@ static VkBool32 VKAPI_CALL vk_dbg_callback(VkDebugUtilsMessageSeverityFlagBitsEX
case 0xfd92477a: /* BestPractices-vkAllocateMemory-small-allocation */
case 0x618ab1e7: /* VUID-VkImageViewCreateInfo-usage-02275 */
case 0x30f4ac70: /* VUID-VkImageCreateInfo-pNext-06811 */
- case 0xa05b236e: /* UNASSIGNED-Threading-MultipleThreads-Write */
return VK_FALSE;
default:
break;
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 */
diff --git a/libavutil/vulkan.h b/libavutil/vulkan.h
index 4ea68e3ecc..2fb7f7c2de 100644
--- a/libavutil/vulkan.h
+++ b/libavutil/vulkan.h
@@ -253,7 +253,7 @@ typedef struct FFVkExecPool {
FFVkExecContext *contexts;
atomic_uint_least64_t idx;
- VkCommandPool cmd_buf_pool;
+ VkCommandPool *cmd_buf_pools;
VkCommandBuffer *cmd_bufs;
int pool_size;
--
2.47.2
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [FFmpeg-devel] [PATCH] vulkan: use a single command buffer per command buffer pool
2025-04-16 13:26 [FFmpeg-devel] [PATCH] vulkan: use a single command buffer per command buffer pool Lynne
@ 2025-04-17 8:11 ` Jerome Martinez
0 siblings, 0 replies; 2+ messages in thread
From: Jerome Martinez @ 2025-04-17 8:11 UTC (permalink / raw)
To: ffmpeg-devel
Le 16/04/2025 à 15:26, Lynne a écrit :
> 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.
I can confirm a +6% on 16-bit content on a RTX 4070 Ti.
With a 2K 16-slice content:
- It was freezing after ~300 frames on a RTX 4070 Ti, now it runs slowly
but smoothly,
- The UI was frozen on a RTX 3050, still some kind of freeze with this
patch but it is better (especially with -thread 1)
no regression found.
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2025-04-17 8:11 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-04-16 13:26 [FFmpeg-devel] [PATCH] vulkan: use a single command buffer per command buffer pool Lynne
2025-04-17 8:11 ` Jerome Martinez
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
This inbox may be cloned and mirrored by anyone:
git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git
# If you have public-inbox 1.1+ installed, you may
# initialize and index your mirror using the following commands:
public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
ffmpegdev@gitmailbox.com
public-inbox-index ffmpegdev
Example config snippet for mirrors.
AGPL code for this site: git clone https://public-inbox.org/public-inbox.git