Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
* [FFmpeg-devel] [PATCH 1/3] lavc/vulkan_decode: use a single execution pool per thread
@ 2023-07-19  4:17 Lynne
       [not found] ` <N_gMYP2--3-9@lynne.ee-N_gMbDd----9>
  0 siblings, 1 reply; 4+ messages in thread
From: Lynne @ 2023-07-19  4:17 UTC (permalink / raw)
  To: Ffmpeg Devel

[-- Attachment #1: Type: text/plain, Size: 203 bytes --]

The spec says command buffer pools must be externally synchronized
objects, which caused us to fail validation when decoding.

This still lets us pool some resources, just not as much.

Patch attached.


[-- Attachment #2: 0001-lavc-vulkan_decode-use-a-single-execution-pool-per-t.patch --]
[-- Type: text/x-diff, Size: 9421 bytes --]

From ef7fc2ea266f04467cf8c37a76275ea167b4d5a1 Mon Sep 17 00:00:00 2001
From: Lynne <dev@lynne.ee>
Date: Wed, 19 Jul 2023 05:39:07 +0200
Subject: [PATCH 1/3] lavc/vulkan_decode: use a single execution pool per
 thread

The spec says command buffer pools must be externally synchronized
objects.

This still lets us pool some, just not as much.
---
 libavcodec/vulkan_decode.c | 86 ++++++++++++++++++++++++++++----------
 libavcodec/vulkan_decode.h |  3 +-
 2 files changed, 66 insertions(+), 23 deletions(-)

diff --git a/libavcodec/vulkan_decode.c b/libavcodec/vulkan_decode.c
index 973c7ca548..f20733fb39 100644
--- a/libavcodec/vulkan_decode.c
+++ b/libavcodec/vulkan_decode.c
@@ -42,12 +42,53 @@ static const VkExtensionProperties *dec_ext[] = {
 #endif
 };
 
+static const VkVideoProfileInfoKHR *get_video_profile(FFVulkanDecodeShared *ctx, enum AVCodecID codec_id)
+{
+    const VkVideoProfileListInfoKHR *profile_list;
+
+    VkStructureType profile_struct_type =
+        codec_id == AV_CODEC_ID_H264 ? VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PROFILE_INFO_KHR :
+        codec_id == AV_CODEC_ID_HEVC ? VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_PROFILE_INFO_KHR :
+        codec_id == AV_CODEC_ID_AV1  ? VK_STRUCTURE_TYPE_VIDEO_DECODE_AV1_PROFILE_INFO_MESA :
+        0;
+
+    profile_list = ff_vk_find_struct(ctx->s.hwfc->create_pnext,
+                                     VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR);
+    if (!profile_list)
+        return NULL;
+
+    for (int i = 0; i < profile_list->profileCount; i++)
+        if (ff_vk_find_struct(profile_list->pProfiles[i].pNext, profile_struct_type))
+            return &profile_list->pProfiles[i];
+
+    return NULL;
+}
+
 int ff_vk_update_thread_context(AVCodecContext *dst, const AVCodecContext *src)
 {
     int err;
     FFVulkanDecodeContext *src_ctx = src->internal->hwaccel_priv_data;
     FFVulkanDecodeContext *dst_ctx = dst->internal->hwaccel_priv_data;
 
+    if (!dst_ctx->exec_pool.cmd_bufs) {
+        FFVulkanDecodeShared *ctx = (FFVulkanDecodeShared *)src_ctx->shared_ref->data;
+
+        const VkVideoProfileInfoKHR *profile = get_video_profile(ctx, dst->codec_id);
+        if (!profile) {
+            av_log(dst, AV_LOG_ERROR, "Video profile missing from frames context!");
+            return AVERROR(EINVAL);
+        }
+
+        err = ff_vk_exec_pool_init(&ctx->s, &ctx->qf,
+                                   &dst_ctx->exec_pool,
+                                   src_ctx->exec_pool.pool_size,
+                                   src_ctx->exec_pool.nb_queries,
+                                   VK_QUERY_TYPE_RESULT_STATUS_ONLY_KHR, 0,
+                                   profile);
+        if (err < 0)
+            return err;
+    }
+
     err = av_buffer_replace(&dst_ctx->shared_ref, src_ctx->shared_ref);
     if (err < 0)
         return err;
@@ -271,7 +312,7 @@ void ff_vk_decode_flush(AVCodecContext *avctx)
     };
 
     VkCommandBuffer cmd_buf;
-    FFVkExecContext *exec = ff_vk_exec_get(&ctx->exec_pool);
+    FFVkExecContext *exec = ff_vk_exec_get(&dec->exec_pool);
     ff_vk_exec_start(&ctx->s, exec);
     cmd_buf = exec->buf;
 
@@ -317,7 +358,7 @@ int ff_vk_decode_frame(AVCodecContext *avctx,
     size_t data_size = FFALIGN(vp->slices_size,
                                ctx->caps.minBitstreamBufferSizeAlignment);
 
-    FFVkExecContext *exec = ff_vk_exec_get(&ctx->exec_pool);
+    FFVkExecContext *exec = ff_vk_exec_get(&dec->exec_pool);
 
     /* The current decoding reference has to be bound as an inactive reference */
     VkVideoReferenceSlotInfoKHR *cur_vk_ref;
@@ -326,7 +367,7 @@ int ff_vk_decode_frame(AVCodecContext *avctx,
     cur_vk_ref[0].slotIndex = -1;
     decode_start.referenceSlotCount++;
 
-    if (ctx->exec_pool.nb_queries) {
+    if (dec->exec_pool.nb_queries) {
         int64_t prev_sub_res = 0;
         ff_vk_exec_wait(&ctx->s, exec);
         ret = ff_vk_exec_get_query(&ctx->s, exec, NULL, &prev_sub_res);
@@ -495,14 +536,14 @@ int ff_vk_decode_frame(AVCodecContext *avctx,
     vk->CmdBeginVideoCodingKHR(cmd_buf, &decode_start);
 
     /* Start status query */
-    if (ctx->exec_pool.nb_queries)
-        vk->CmdBeginQuery(cmd_buf, ctx->exec_pool.query_pool, exec->query_idx + 0, 0);
+    if (dec->exec_pool.nb_queries)
+        vk->CmdBeginQuery(cmd_buf, dec->exec_pool.query_pool, exec->query_idx + 0, 0);
 
     vk->CmdDecodeVideoKHR(cmd_buf, &vp->decode_info);
 
     /* End status query */
-    if (ctx->exec_pool.nb_queries)
-        vk->CmdEndQuery(cmd_buf, ctx->exec_pool.query_pool, exec->query_idx + 0);
+    if (dec->exec_pool.nb_queries)
+        vk->CmdEndQuery(cmd_buf, dec->exec_pool.query_pool, exec->query_idx + 0);
 
     vk->CmdEndVideoCodingKHR(cmd_buf, &decode_end);
 
@@ -555,9 +596,6 @@ static void free_common(void *opaque, uint8_t *data)
     FFVulkanContext *s = &ctx->s;
     FFVulkanFunctions *vk = &ctx->s.vkfn;
 
-    /* Wait on and free execution pool */
-    ff_vk_exec_pool_free(s, &ctx->exec_pool);
-
     /* Destroy layered view */
     if (ctx->layered_view)
         vk->DestroyImageView(s->hwctx->act_dev, ctx->layered_view, s->hwctx->alloc);
@@ -1029,6 +1067,11 @@ void ff_vk_decode_free_params(void *opaque, uint8_t *data)
 int ff_vk_decode_uninit(AVCodecContext *avctx)
 {
     FFVulkanDecodeContext *dec = avctx->internal->hwaccel_priv_data;
+    FFVulkanDecodeShared *ctx = (FFVulkanDecodeShared *)dec->shared_ref->data;
+
+    /* Wait on and free execution pool */
+    ff_vk_exec_pool_free(&ctx->s, &dec->exec_pool);
+
     av_buffer_pool_uninit(&dec->tmp_pool);
     av_buffer_unref(&dec->session_params);
     av_buffer_unref(&dec->shared_ref);
@@ -1044,8 +1087,7 @@ int ff_vk_decode_init(AVCodecContext *avctx)
     FFVulkanDecodeShared *ctx;
     FFVulkanContext *s;
     FFVulkanFunctions *vk;
-    FFVkQueueFamilyCtx qf_dec;
-    const VkVideoProfileListInfoKHR *profile_list;
+    const VkVideoProfileInfoKHR *profile;
 
     VkVideoDecodeH264SessionParametersCreateInfoKHR h264_params = {
         .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_SESSION_PARAMETERS_CREATE_INFO_KHR,
@@ -1089,10 +1131,9 @@ int ff_vk_decode_init(AVCodecContext *avctx)
     s->device = (AVHWDeviceContext *)s->frames->device_ref->data;
     s->hwctx = s->device->hwctx;
 
-    profile_list = ff_vk_find_struct(s->hwfc->create_pnext,
-                                     VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR);
-    if (!profile_list) {
-        av_log(avctx, AV_LOG_ERROR, "Profile list missing from frames context!");
+    profile = get_video_profile(ctx, avctx->codec_id);
+    if (!profile) {
+        av_log(avctx, AV_LOG_ERROR, "Video profile missing from frames context!");
         return AVERROR(EINVAL);
     }
 
@@ -1101,7 +1142,7 @@ int ff_vk_decode_init(AVCodecContext *avctx)
         goto fail;
 
     /* Create queue context */
-    qf = ff_vk_qf_init(s, &qf_dec, VK_QUEUE_VIDEO_DECODE_BIT_KHR);
+    qf = ff_vk_qf_init(s, &ctx->qf, VK_QUEUE_VIDEO_DECODE_BIT_KHR);
 
     /* Check for support */
     if (!(s->video_props[qf].videoCodecOperations &
@@ -1123,14 +1164,14 @@ int ff_vk_decode_init(AVCodecContext *avctx)
     session_create.pictureFormat = s->hwfc->format[0];
     session_create.referencePictureFormat = session_create.pictureFormat;
     session_create.pStdHeaderVersion = dec_ext[avctx->codec_id];
-    session_create.pVideoProfile = &profile_list->pProfiles[0];
+    session_create.pVideoProfile = profile;
 
-    /* Create decode exec context.
+    /* Create decode exec context for this specific main thread.
      * 2 async contexts per thread was experimentally determined to be optimal
      * for a majority of streams. */
-    err = ff_vk_exec_pool_init(s, &qf_dec, &ctx->exec_pool, 2*avctx->thread_count,
+    err = ff_vk_exec_pool_init(s, &ctx->qf, &dec->exec_pool, 2,
                                nb_q, VK_QUERY_TYPE_RESULT_STATUS_ONLY_KHR, 0,
-                               session_create.pVideoProfile);
+                               profile);
     if (err < 0)
         goto fail;
 
@@ -1168,7 +1209,8 @@ int ff_vk_decode_init(AVCodecContext *avctx)
         dpb_frames->height    = s->frames->height;
 
         dpb_hwfc = dpb_frames->hwctx;
-        dpb_hwfc->create_pnext = (void *)profile_list;
+        dpb_hwfc->create_pnext = (void *)ff_vk_find_struct(ctx->s.hwfc->create_pnext,
+                                                           VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR);
         dpb_hwfc->format[0]    = s->hwfc->format[0];
         dpb_hwfc->tiling       = VK_IMAGE_TILING_OPTIMAL;
         dpb_hwfc->usage        = VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR |
diff --git a/libavcodec/vulkan_decode.h b/libavcodec/vulkan_decode.h
index 4e45cbde71..1b4e1cc712 100644
--- a/libavcodec/vulkan_decode.h
+++ b/libavcodec/vulkan_decode.h
@@ -37,7 +37,7 @@ typedef struct FFVulkanDecodeProfileData {
 typedef struct FFVulkanDecodeShared {
     FFVulkanContext s;
     FFVkVideoCommon common;
-    FFVkExecPool exec_pool;
+    FFVkQueueFamilyCtx qf;
 
     VkVideoCapabilitiesKHR caps;
     VkVideoDecodeCapabilitiesKHR dec_caps;
@@ -56,6 +56,7 @@ typedef struct FFVulkanDecodeShared {
 typedef struct FFVulkanDecodeContext {
     AVBufferRef *shared_ref;
     AVBufferRef *session_params;
+    FFVkExecPool exec_pool;
 
     int dedicated_dpb; /* Oddity  #1 - separate DPB images */
     int layered_dpb;   /* Madness #1 - layered  DPB images */
-- 
2.40.1


[-- Attachment #3: Type: text/plain, Size: 251 bytes --]

_______________________________________________
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] 4+ messages in thread

* [FFmpeg-devel] lavu/vulkan: remove threadsafe buffer index load and fix a signed overflow
       [not found] ` <N_gMYP2--3-9@lynne.ee-N_gMbDd----9>
@ 2023-07-19  4:19   ` Lynne
       [not found]   ` <N_gN3Pp--3-9@lynne.ee-N_gN6Vi----9>
  2023-07-21 18:08   ` [FFmpeg-devel] [PATCH 1/3] lavc/vulkan_decode: use a single execution pool per thread Lynne
  2 siblings, 0 replies; 4+ messages in thread
From: Lynne @ 2023-07-19  4:19 UTC (permalink / raw)
  To: FFmpeg development discussions and patches

[-- Attachment #1: Type: text/plain, Size: 134 bytes --]

It's not needed anymore, as no pools are used between threads.

This also fixes a small potential integer overflow.

Patch attached.


[-- Attachment #2: 0002-lavu-vulkan-remove-threadsafe-buffer-index-load-and-.patch --]
[-- Type: text/x-diff, Size: 1570 bytes --]

From 797c62be618fe8e6223b7b01184bce7c6f231a96 Mon Sep 17 00:00:00 2001
From: Lynne <dev@lynne.ee>
Date: Wed, 19 Jul 2023 04:54:37 +0200
Subject: [PATCH 2/3] lavu/vulkan: remove threadsafe buffer index load and fix
 a signed overflow

It's not needed anymore.
---
 libavutil/vulkan.c | 4 +---
 libavutil/vulkan.h | 2 +-
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/libavutil/vulkan.c b/libavutil/vulkan.c
index 26b9b6f1fb..48f5f4b5dc 100644
--- a/libavutil/vulkan.c
+++ b/libavutil/vulkan.c
@@ -282,8 +282,6 @@ int ff_vk_exec_pool_init(FFVulkanContext *s, FFVkQueueFamilyCtx *qf,
     VkCommandPoolCreateInfo cqueue_create;
     VkCommandBufferAllocateInfo cbuf_create;
 
-    atomic_init(&pool->idx, 0);
-
     /* Create command pool */
     cqueue_create = (VkCommandPoolCreateInfo) {
         .sType              = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
@@ -472,7 +470,7 @@ VkResult ff_vk_exec_get_query(FFVulkanContext *s, FFVkExecContext *e,
 
 FFVkExecContext *ff_vk_exec_get(FFVkExecPool *pool)
 {
-    int idx = atomic_fetch_add_explicit(&pool->idx, 1, memory_order_relaxed);
+    uint32_t idx = pool->idx++;
     idx %= pool->pool_size;
     return &pool->contexts[idx];
 }
diff --git a/libavutil/vulkan.h b/libavutil/vulkan.h
index bbbc9374ae..7171fb3c42 100644
--- a/libavutil/vulkan.h
+++ b/libavutil/vulkan.h
@@ -151,7 +151,7 @@ typedef struct FFVulkanPipeline {
 } FFVulkanPipeline;
 
 typedef struct FFVkExecContext {
-    int idx;
+    uint32_t idx;
     const struct FFVkExecPool *parent;
     pthread_mutex_t lock;
 
-- 
2.40.1


[-- Attachment #3: Type: text/plain, Size: 251 bytes --]

_______________________________________________
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] 4+ messages in thread

* [FFmpeg-devel] [PATCH 3/3] lavu/vulkan: remove unused field from the execution pool structure
       [not found]   ` <N_gN3Pp--3-9@lynne.ee-N_gN6Vi----9>
@ 2023-07-19  4:20     ` Lynne
  0 siblings, 0 replies; 4+ messages in thread
From: Lynne @ 2023-07-19  4:20 UTC (permalink / raw)
  To: FFmpeg development discussions and patches

[-- Attachment #1: Type: text/plain, Size: 43 bytes --]

Was never used anywhere.

Patch attached.


[-- Attachment #2: 0003-lavu-vulkan-remove-unused-field-from-the-execution-p.patch --]
[-- Type: text/x-diff, Size: 639 bytes --]

From edaf45f5db757bef95c1ffbf322b872f9d6b0ae0 Mon Sep 17 00:00:00 2001
From: Lynne <dev@lynne.ee>
Date: Wed, 19 Jul 2023 05:38:32 +0200
Subject: [PATCH 3/3] lavu/vulkan: remove unused field from the execution pool
 structure

---
 libavutil/vulkan.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/libavutil/vulkan.h b/libavutil/vulkan.h
index 7171fb3c42..20b81105dd 100644
--- a/libavutil/vulkan.h
+++ b/libavutil/vulkan.h
@@ -208,7 +208,6 @@ typedef struct FFVkExecContext {
 } FFVkExecContext;
 
 typedef struct FFVkExecPool {
-    FFVkQueueFamilyCtx *qf;
     FFVkExecContext *contexts;
     atomic_int_least64_t idx;
 
-- 
2.40.1


[-- Attachment #3: Type: text/plain, Size: 251 bytes --]

_______________________________________________
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] 4+ messages in thread

* Re: [FFmpeg-devel] [PATCH 1/3] lavc/vulkan_decode: use a single execution pool per thread
       [not found] ` <N_gMYP2--3-9@lynne.ee-N_gMbDd----9>
  2023-07-19  4:19   ` [FFmpeg-devel] lavu/vulkan: remove threadsafe buffer index load and fix a signed overflow Lynne
       [not found]   ` <N_gN3Pp--3-9@lynne.ee-N_gN6Vi----9>
@ 2023-07-21 18:08   ` Lynne
  2 siblings, 0 replies; 4+ messages in thread
From: Lynne @ 2023-07-21 18:08 UTC (permalink / raw)
  To: FFmpeg development discussions and patches

Jul 19, 2023, 06:17 by dev@lynne.ee:

> The spec says command buffer pools must be externally synchronized
> objects, which caused us to fail validation when decoding.
>
> This still lets us pool some resources, just not as much.
>
> Patch attached.
>

Pushed.
_______________________________________________
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] 4+ messages in thread

end of thread, other threads:[~2023-07-21 18:08 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-07-19  4:17 [FFmpeg-devel] [PATCH 1/3] lavc/vulkan_decode: use a single execution pool per thread Lynne
     [not found] ` <N_gMYP2--3-9@lynne.ee-N_gMbDd----9>
2023-07-19  4:19   ` [FFmpeg-devel] lavu/vulkan: remove threadsafe buffer index load and fix a signed overflow Lynne
     [not found]   ` <N_gN3Pp--3-9@lynne.ee-N_gN6Vi----9>
2023-07-19  4:20     ` [FFmpeg-devel] [PATCH 3/3] lavu/vulkan: remove unused field from the execution pool structure Lynne
2023-07-21 18:08   ` [FFmpeg-devel] [PATCH 1/3] lavc/vulkan_decode: use a single execution pool per thread Lynne

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