History

vulkan_decode: use a single execution pool

Originally, the decoder had a single execution pool, with one execution context per thread. Execution pools were always intended to be thread-safe, as long as there were enough execution contexts in the pool to satisfy all threads. Due to synchronization issues, the threading part was removed at some point, and, for decoding, each thread had its own execution pool. Having a single execution pool per context is hacky, not to mention wasteful. Most importantly, we *cannot* associate single shaders across multiple execution pools for a single application. This means that we cannot use shaders to either apply film grain, or use this framework for software-defined decoders. The recent commits added threading capabilities back to the execution pool, and the number of contexts in each pool was increased. This was done with the assumption that the execution pool was singular, which it was not. This led to increased parallelism and number of frames in flight, which is taxing on memory. This commit finally restores proper threading behaviour. The validation layer has isses that are reported and addressed in the earlier commit.

Lynne committed 1 year ago

Commit 7239be01 parent 4ca2b862 files · +16 −33Browse files

Unified · Split

2 files
  1. libavcodec/vulkan_decode.c +15 −32
  2. libavcodec/vulkan_decode.h +1 −1
libavcodec/vulkan_decode.c+15−32
@@ -83,25 +83,6 @@ int ff_vk_update_thread_context(AVCodecContext *dst, const AVCodecContext *src) · 82 unmodified lines
8383 FFVulkanDecodeContext *src_ctx = src->internal->hwaccel_priv_data;
8484 FFVulkanDecodeContext *dst_ctx = dst->internal->hwaccel_priv_data;
8585
86− if (!dst_ctx->exec_pool.cmd_bufs) {
87− FFVulkanDecodeShared *ctx = src_ctx->shared_ctx;
88−
89− const VkVideoProfileInfoKHR *profile = get_video_profile(ctx, dst->codec_id);
90− if (!profile) {
91− av_log(dst, AV_LOG_ERROR, "Video profile missing from frames context!\n");
92− return AVERROR(EINVAL);
93− }
94−
95− err = ff_vk_exec_pool_init(&ctx->s, &ctx->qf,
96− &dst_ctx->exec_pool,
97− src_ctx->exec_pool.pool_size,
98− src_ctx->exec_pool.nb_queries,
99− VK_QUERY_TYPE_RESULT_STATUS_ONLY_KHR, 0,
100− profile);
101− if (err < 0)
102− return err;
103− }
104−
10586 av_refstruct_replace(&dst_ctx->shared_ctx, src_ctx->shared_ctx);
10687
10788 if (src_ctx->session_params) {
@@ -293,8 +274,11 @@ void ff_vk_decode_flush(AVCodecContext *avctx) · 185 unmodified lines
293274 };
294275
295276 VkCommandBuffer cmd_buf;
296− FFVkExecContext *exec = ff_vk_exec_get(&ctx->s, &dec->exec_pool);
297− int had_submission = exec->had_submission;
277+ FFVkExecContext *exec;
278+ int had_submission;
279+
280+ exec = ff_vk_exec_get(&ctx->s, &ctx->exec_pool);
281+ had_submission = exec->had_submission;
298282 ff_vk_exec_start(&ctx->s, exec);
299283 cmd_buf = exec->buf;
300284
@@ -345,7 +329,7 @@ int ff_vk_decode_frame(AVCodecContext *avctx, · 44 unmodified lines
345329 size_t data_size = FFALIGN(vp->slices_size,
346330 ctx->caps.minBitstreamBufferSizeAlignment);
347331
348− FFVkExecContext *exec = ff_vk_exec_get(&ctx->s, &dec->exec_pool);
332+ FFVkExecContext *exec = ff_vk_exec_get(&ctx->s, &ctx->exec_pool);
349333
350334 /* The current decoding reference has to be bound as an inactive reference */
351335 VkVideoReferenceSlotInfoKHR *cur_vk_ref;
@@ -354,7 +338,7 @@ int ff_vk_decode_frame(AVCodecContext *avctx, · 2 unmodified lines
354338 cur_vk_ref[0].slotIndex = -1;
355339 decode_start.referenceSlotCount++;
356340
357− if (dec->exec_pool.nb_queries && exec->had_submission) {
341+ if (ctx->exec_pool.nb_queries && exec->had_submission) {
358342 uint32_t *result;
359343 ret = ff_vk_exec_get_query(&ctx->s, exec, (void **)&result,
360344 VK_QUERY_RESULT_WAIT_BIT);
@@ -525,14 +509,14 @@ int ff_vk_decode_frame(AVCodecContext *avctx, · 164 unmodified lines
525509 vk->CmdBeginVideoCodingKHR(cmd_buf, &decode_start);
526510
527511 /* Start status query */
528− if (dec->exec_pool.nb_queries)
529− vk->CmdBeginQuery(cmd_buf, dec->exec_pool.query_pool, exec->query_idx + 0, 0);
512+ if (ctx->exec_pool.nb_queries)
513+ vk->CmdBeginQuery(cmd_buf, ctx->exec_pool.query_pool, exec->query_idx + 0, 0);
530514
531515 vk->CmdDecodeVideoKHR(cmd_buf, &vp->decode_info);
532516
533517 /* End status query */
534− if (dec->exec_pool.nb_queries)
535− vk->CmdEndQuery(cmd_buf, dec->exec_pool.query_pool, exec->query_idx + 0);
518+ if (ctx->exec_pool.nb_queries)
519+ vk->CmdEndQuery(cmd_buf, ctx->exec_pool.query_pool, exec->query_idx + 0);
536520
537521 vk->CmdEndVideoCodingKHR(cmd_buf, &decode_end);
538522
@@ -577,6 +561,9 @@ static void free_common(AVRefStructOpaque unused, void *obj) · 38 unmodified lines
577561 FFVulkanContext *s = &ctx->s;
578562 FFVulkanFunctions *vk = &ctx->s.vkfn;
579563
564+ /* Wait on and free execution pool */
565+ ff_vk_exec_pool_free(&ctx->s, &ctx->exec_pool);
566+
580567 /* This also frees all references from this pool */
581568 av_frame_free(&ctx->common.layered_frame);
582569
@@ -1066,10 +1053,6 @@ int ff_vk_decode_create_params(AVBufferRef **par_ref, void *logctx, FFVulkanDeco · 483 unmodified lines
10661053 int ff_vk_decode_uninit(AVCodecContext *avctx)
10671054 {
10681055 FFVulkanDecodeContext *dec = avctx->internal->hwaccel_priv_data;
1069− FFVulkanDecodeShared *ctx = dec->shared_ctx;
1070−
1071− /* Wait on and free execution pool */
1072− ff_vk_exec_pool_free(&ctx->s, &dec->exec_pool);
10731056
10741057 av_freep(&dec->hevc_headers);
10751058 av_buffer_unref(&dec->session_params);
@@ -1159,7 +1142,7 @@ int ff_vk_decode_init(AVCodecContext *avctx) · 83 unmodified lines
11591142 /* Create decode exec context for this specific main thread.
11601143 * 2 async contexts per thread was experimentally determined to be optimal
11611144 * for a majority of streams. */
1162− err = ff_vk_exec_pool_init(s, &ctx->qf, &dec->exec_pool,
1145+ err = ff_vk_exec_pool_init(s, &ctx->qf, &ctx->exec_pool,
11631146 FFMAX(2*ctx->qf.nb_queues, avctx->thread_count),
11641147 nb_q, VK_QUERY_TYPE_RESULT_STATUS_ONLY_KHR, 0,
11651148 profile);
libavcodec/vulkan_decode.h+1−1
@@ -47,6 +47,7 @@ typedef struct FFVulkanDecodeShared { · 46 unmodified lines
4747 FFVulkanContext s;
4848 FFVkVideoCommon common;
4949 FFVkQueueFamilyCtx qf;
50+ FFVkExecPool exec_pool;
5051
5152 AVBufferPool *buf_pool;
5253
@@ -59,7 +60,6 @@ typedef struct FFVulkanDecodeShared { · 6 unmodified lines
5960 typedef struct FFVulkanDecodeContext {
6061 FFVulkanDecodeShared *shared_ctx;
6162 AVBufferRef *session_params;
62− FFVkExecPool exec_pool;
6363
6464 int dedicated_dpb; /* Oddity #1 - separate DPB images */
6565 int external_fg; /* Oddity #2 - hardware can't apply film grain */

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