History

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.

Lynne committed 1 year ago

Commit bb3ce281 parent 36c6c663 files · +47 −34Browse files

Unified · Split

3 files
  1. libavutil/hwcontext_vulkan.c +0 −1
  2. libavutil/vulkan.c +46 −32
  3. libavutil/vulkan.h +1 −1
libavutil/hwcontext_vulkan.c+0−1
@@ -673,7 +673,6 @@ static VkBool32 VKAPI_CALL vk_dbg_callback(VkDebugUtilsMessageSeverityFlagBitsEX · 672 unmodified lines
673673 case 0xfd92477a: /* BestPractices-vkAllocateMemory-small-allocation */
674674 case 0x618ab1e7: /* VUID-VkImageViewCreateInfo-usage-02275 */
675675 case 0x30f4ac70: /* VUID-VkImageCreateInfo-pNext-06811 */
676− case 0xa05b236e: /* UNASSIGNED-Threading-MultipleThreads-Write */
677676 return VK_FALSE;
678677 default:
679678 break;
libavutil/vulkan.c+46−32
@@ -280,15 +280,19 @@ void ff_vk_exec_pool_free(FFVulkanContext *s, FFVkExecPool *pool) · 279 unmodified lines
280280 av_freep(&sd->desc_sets);
281281 }
282282
283− if (pool->cmd_bufs)
284− vk->FreeCommandBuffers(s->hwctx->act_dev, pool->cmd_buf_pool,
285− pool->pool_size, pool->cmd_bufs);
286− if (pool->cmd_buf_pool)
287− vk->DestroyCommandPool(s->hwctx->act_dev, pool->cmd_buf_pool, s->hwctx->alloc);
283+ for (int i = 0; i < pool->pool_size; i++) {
284+ if (pool->cmd_buf_pools[i])
285+ vk->FreeCommandBuffers(s->hwctx->act_dev, pool->cmd_buf_pools[i],
286+ 1, &pool->cmd_bufs[i]);
287+
288+ if (pool->cmd_buf_pools[i])
289+ vk->DestroyCommandPool(s->hwctx->act_dev, pool->cmd_buf_pools[i], s->hwctx->alloc);
290+ }
288291 if (pool->query_pool)
289292 vk->DestroyQueryPool(s->hwctx->act_dev, pool->query_pool, s->hwctx->alloc);
290293
291294 av_free(pool->query_data);
295+ av_free(pool->cmd_buf_pools);
292296 av_free(pool->cmd_bufs);
293297 av_free(pool->contexts);
294298 }
@@ -316,19 +320,10 @@ int ff_vk_exec_pool_init(FFVulkanContext *s, AVVulkanDeviceQueueFamily *qf, · 21 unmodified lines
316320 return AVERROR(EINVAL);
317321 }
318322
319− /* Create command pool */
320− cqueue_create = (VkCommandPoolCreateInfo) {
321− .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
322− .flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT |
323− VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
324− .queueFamilyIndex = qf->idx,
325− };
326− ret = vk->CreateCommandPool(s->hwctx->act_dev, &cqueue_create,
327− s->hwctx->alloc, &pool->cmd_buf_pool);
328− if (ret != VK_SUCCESS) {
329− av_log(s, AV_LOG_ERROR, "Command pool creation failure: %s\n",
330− ff_vk_ret2str(ret));
331− err = AVERROR_EXTERNAL;
323+ /* Allocate space for command buffer pools */
324+ pool->cmd_buf_pools = av_malloc(nb_contexts*sizeof(*pool->cmd_buf_pools));
325+ if (!pool->cmd_buf_pools) {
326+ err = AVERROR(ENOMEM);
332327 goto fail;
333328 }
334329
@@ -339,20 +334,39 @@ int ff_vk_exec_pool_init(FFVulkanContext *s, AVVulkanDeviceQueueFamily *qf, · 4 unmodified lines
339334 goto fail;
340335 }
341336
342− /* Allocate command buffer */
343− cbuf_create = (VkCommandBufferAllocateInfo) {
344− .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
345− .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
346− .commandPool = pool->cmd_buf_pool,
347− .commandBufferCount = nb_contexts,
348− };
349− ret = vk->AllocateCommandBuffers(s->hwctx->act_dev, &cbuf_create,
350− pool->cmd_bufs);
351− if (ret != VK_SUCCESS) {
352− av_log(s, AV_LOG_ERROR, "Command buffer alloc failure: %s\n",
353− ff_vk_ret2str(ret));
354− err = AVERROR_EXTERNAL;
355− goto fail;
337+ for (int i = 0; i < nb_contexts; i++) {
338+ /* Create command pool */
339+ cqueue_create = (VkCommandPoolCreateInfo) {
340+ .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
341+ .flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT |
342+ VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
343+ .queueFamilyIndex = qf->idx,
344+ };
345+
346+ ret = vk->CreateCommandPool(s->hwctx->act_dev, &cqueue_create,
347+ s->hwctx->alloc, &pool->cmd_buf_pools[i]);
348+ if (ret != VK_SUCCESS) {
349+ av_log(s, AV_LOG_ERROR, "Command pool creation failure: %s\n",
350+ ff_vk_ret2str(ret));
351+ err = AVERROR_EXTERNAL;
352+ goto fail;
353+ }
354+
355+ /* Allocate command buffer */
356+ cbuf_create = (VkCommandBufferAllocateInfo) {
357+ .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
358+ .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
359+ .commandPool = pool->cmd_buf_pools[i],
360+ .commandBufferCount = 1,
361+ };
362+ ret = vk->AllocateCommandBuffers(s->hwctx->act_dev, &cbuf_create,
363+ &pool->cmd_bufs[i]);
364+ if (ret != VK_SUCCESS) {
365+ av_log(s, AV_LOG_ERROR, "Command buffer alloc failure: %s\n",
366+ ff_vk_ret2str(ret));
367+ err = AVERROR_EXTERNAL;
368+ goto fail;
369+ }
356370 }
357371
358372 /* Query pool */
libavutil/vulkan.h+1−1
@@ -253,7 +253,7 @@ typedef struct FFVkExecPool { · 252 unmodified lines
253253 FFVkExecContext *contexts;
254254 atomic_uint_least64_t idx;
255255
256− VkCommandPool cmd_buf_pool;
256+ VkCommandPool *cmd_buf_pools;
257257 VkCommandBuffer *cmd_bufs;
258258 int pool_size;
259259

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t