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
673 case 0xfd92477a: /* BestPractices-vkAllocateMemory-small-allocation */673 case 0xfd92477a: /* BestPractices-vkAllocateMemory-small-allocation */
674 case 0x618ab1e7: /* VUID-VkImageViewCreateInfo-usage-02275 */674 case 0x618ab1e7: /* VUID-VkImageViewCreateInfo-usage-02275 */
675 case 0x30f4ac70: /* VUID-VkImageCreateInfo-pNext-06811 */675 case 0x30f4ac70: /* VUID-VkImageCreateInfo-pNext-06811 */
676 case 0xa05b236e: /* UNASSIGNED-Threading-MultipleThreads-Write */
677 return VK_FALSE;676 return VK_FALSE;
678 default:677 default:
679 break;678 break;
libavutil/vulkan.c+46−32
@@ -280,15 +280,19 @@ void ff_vk_exec_pool_free(FFVulkanContext *s, FFVkExecPool *pool) · 279 unmodified lines
280 av_freep(&sd->desc_sets);280 av_freep(&sd->desc_sets);
281 }281 }
282 282
283 if (pool->cmd_bufs)283 for (int i = 0; i < pool->pool_size; i++) {
284 vk->FreeCommandBuffers(s->hwctx->act_dev, pool->cmd_buf_pool,284 if (pool->cmd_buf_pools[i])
285 pool->pool_size, pool->cmd_bufs);285 vk->FreeCommandBuffers(s->hwctx->act_dev, pool->cmd_buf_pools[i],
286 if (pool->cmd_buf_pool)286 1, &pool->cmd_bufs[i]);
287 vk->DestroyCommandPool(s->hwctx->act_dev, pool->cmd_buf_pool, s->hwctx->alloc);287
288 if (pool->cmd_buf_pools[i])
289 vk->DestroyCommandPool(s->hwctx->act_dev, pool->cmd_buf_pools[i], s->hwctx->alloc);
290 }
288 if (pool->query_pool)291 if (pool->query_pool)
289 vk->DestroyQueryPool(s->hwctx->act_dev, pool->query_pool, s->hwctx->alloc);292 vk->DestroyQueryPool(s->hwctx->act_dev, pool->query_pool, s->hwctx->alloc);
290 293
291 av_free(pool->query_data);294 av_free(pool->query_data);
295 av_free(pool->cmd_buf_pools);
292 av_free(pool->cmd_bufs);296 av_free(pool->cmd_bufs);
293 av_free(pool->contexts);297 av_free(pool->contexts);
294}298}
@@ -316,19 +320,10 @@ int ff_vk_exec_pool_init(FFVulkanContext *s, AVVulkanDeviceQueueFamily *qf, · 21 unmodified lines
316 return AVERROR(EINVAL);320 return AVERROR(EINVAL);
317 }321 }
318 322
319 /* Create command pool */323 /* Allocate space for command buffer pools */
320 cqueue_create = (VkCommandPoolCreateInfo) {324 pool->cmd_buf_pools = av_malloc(nb_contexts*sizeof(*pool->cmd_buf_pools));
321 .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,325 if (!pool->cmd_buf_pools) {
322 .flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT |326 err = AVERROR(ENOMEM);
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;
332 goto fail;327 goto fail;
333 }328 }
334 329
@@ -339,20 +334,39 @@ int ff_vk_exec_pool_init(FFVulkanContext *s, AVVulkanDeviceQueueFamily *qf, · 4 unmodified lines
339 goto fail;334 goto fail;
340 }335 }
341 336
342 /* Allocate command buffer */337 for (int i = 0; i < nb_contexts; i++) {
343 cbuf_create = (VkCommandBufferAllocateInfo) {338 /* Create command pool */
344 .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,339 cqueue_create = (VkCommandPoolCreateInfo) {
345 .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,340 .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
346 .commandPool = pool->cmd_buf_pool,341 .flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT |
347 .commandBufferCount = nb_contexts,342 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
348 };343 .queueFamilyIndex = qf->idx,
349 ret = vk->AllocateCommandBuffers(s->hwctx->act_dev, &cbuf_create,344 };
350 pool->cmd_bufs);345
351 if (ret != VK_SUCCESS) {346 ret = vk->CreateCommandPool(s->hwctx->act_dev, &cqueue_create,
352 av_log(s, AV_LOG_ERROR, "Command buffer alloc failure: %s\n",347 s->hwctx->alloc, &pool->cmd_buf_pools[i]);
353 ff_vk_ret2str(ret));348 if (ret != VK_SUCCESS) {
354 err = AVERROR_EXTERNAL;349 av_log(s, AV_LOG_ERROR, "Command pool creation failure: %s\n",
355 goto fail;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 }
356 }370 }
357 371
358 /* Query pool */372 /* Query pool */
libavutil/vulkan.h+1−1
@@ -253,7 +253,7 @@ typedef struct FFVkExecPool { · 252 unmodified lines
253 FFVkExecContext *contexts;253 FFVkExecContext *contexts;
254 atomic_uint_least64_t idx;254 atomic_uint_least64_t idx;
255 255
256 VkCommandPool cmd_buf_pool;256 VkCommandPool *cmd_buf_pools;
257 VkCommandBuffer *cmd_bufs;257 VkCommandBuffer *cmd_bufs;
258 int pool_size;258 int pool_size;
259 259

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