This is an automated email from the git hooks/post-receive script.

Git pushed a commit to branch master
in repository ffmpeg.

commit d4bc34a070c00069e3da81a86fbf22aedb680825
Author:     Lynne <[email protected]>
AuthorDate: Tue Aug 4 01:39:16 2026 +0900
Commit:     Lynne <[email protected]>
CommitDate: Wed Aug 5 16:04:36 2026 +0900

    vulkan: track semaphores/views directly as deps
    
    There's no need for them to live in bufferrefs.
---
 libavutil/hwcontext_vulkan.c |   8 +--
 libavutil/vulkan.c           | 146 ++++++++++++++-----------------------------
 libavutil/vulkan.h           |  22 +++++--
 3 files changed, 68 insertions(+), 108 deletions(-)

diff --git a/libavutil/hwcontext_vulkan.c b/libavutil/hwcontext_vulkan.c
index d32dc7997b..3d2bbb3c7c 100644
--- a/libavutil/hwcontext_vulkan.c
+++ b/libavutil/hwcontext_vulkan.c
@@ -3638,11 +3638,9 @@ static int 
vulkan_map_from_drm_frame_sync(AVHWFramesContext *hwfc, AVFrame *dst,
         ff_vk_exec_start(&p->vkctx, exec);
 
         /* Ownership of semaphores is passed */
-        err = ff_vk_exec_add_dep_bool_sem(&p->vkctx, exec,
-                                          drm_sync_sem, desc->nb_objects,
-                                          
VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT, 1);
-        if (err < 0)
-            return err;
+        ff_vk_exec_add_dep_bool_sem(&p->vkctx, exec,
+                                    drm_sync_sem, desc->nb_objects,
+                                    VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT, 1);
 
         err = ff_vk_exec_add_dep_frame(&p->vkctx, exec, dst,
                                        VK_PIPELINE_STAGE_2_NONE,
diff --git a/libavutil/vulkan.c b/libavutil/vulkan.c
index fd408785f0..c5d7a3e07f 100644
--- a/libavutil/vulkan.c
+++ b/libavutil/vulkan.c
@@ -567,7 +567,7 @@ FFVkExecContext *ff_vk_exec_get(FFVulkanContext *s, 
FFVkExecPool *pool)
         FFVkExecContext *e = &pool->contexts[i];
         if (pthread_mutex_trylock(&e->lock))
             continue; /* In use by a recording or submitting thread */
-        if ((e->nb_buf_deps || e->nb_refstruct_deps ||
+        if ((e->nb_buf_deps || e->nb_refstruct_deps || e->nb_obj_deps ||
              e->nb_frame_deps || e->nb_sw_frame_deps) &&
             vk->GetFenceStatus(s->hwctx->act_dev, e->fence) == VK_SUCCESS)
             ff_vk_exec_discard_deps(s, e);
@@ -625,6 +625,8 @@ int ff_vk_exec_start(FFVulkanContext *s, FFVkExecContext *e)
 
 void ff_vk_exec_discard_deps(FFVulkanContext *s, FFVkExecContext *e)
 {
+    FFVulkanFunctions *vk = &s->vkfn;
+
     for (int j = 0; j < e->nb_buf_deps; j++)
         av_buffer_unref(&e->buf_deps[j]);
     e->nb_buf_deps = 0;
@@ -633,6 +635,23 @@ void ff_vk_exec_discard_deps(FFVulkanContext *s, 
FFVkExecContext *e)
         av_refstruct_unref(&e->refstruct_deps[j]);
     e->nb_refstruct_deps = 0;
 
+    for (int j = 0; j < e->nb_obj_deps; j++) {
+        FFVkExecObjDep *od = &e->obj_deps[j];
+        switch (od->type) {
+        case VK_OBJECT_TYPE_IMAGE_VIEW:
+            vk->DestroyImageView(s->hwctx->act_dev,
+                                 (VkImageView)od->obj, s->hwctx->alloc);
+            break;
+        case VK_OBJECT_TYPE_SEMAPHORE:
+            vk->DestroySemaphore(s->hwctx->act_dev,
+                                 (VkSemaphore)od->obj, s->hwctx->alloc);
+            break;
+        default:
+            av_assert1(0);
+        }
+    }
+    e->nb_obj_deps = 0;
+
     for (int j = 0; j < e->nb_sw_frame_deps; j++)
         av_frame_free(&e->sw_frame_deps[j]);
     e->nb_sw_frame_deps = 0;
@@ -700,6 +719,13 @@ void ff_vk_exec_move_dep_refstruct(FFVulkanContext *s, 
FFVkExecContext *e,
     *ptr = NULL;
 }
 
+void ff_vk_exec_add_dep_obj(FFVulkanContext *s, FFVkExecContext *e,
+                            VkObjectType type, uint64_t obj)
+{
+    av_assert1(e->nb_obj_deps < FF_VK_EXEC_MAX_BUF_DEPS);
+    e->obj_deps[e->nb_obj_deps++] = (FFVkExecObjDep) { obj, type };
+}
+
 int ff_vk_exec_add_dep_sw_frame(FFVulkanContext *s, FFVkExecContext *e,
                                 AVFrame *f)
 {
@@ -716,23 +742,6 @@ int ff_vk_exec_add_dep_sw_frame(FFVulkanContext *s, 
FFVkExecContext *e,
     return 0;
 }
 
-typedef struct TempSyncCtx {
-    int nb_sem;
-    VkSemaphore sem[];
-} TempSyncCtx;
-
-static void destroy_tmp_semaphores(void *opaque, uint8_t *data)
-{
-    FFVulkanContext *s = opaque;
-    FFVulkanFunctions *vk = &s->vkfn;
-    TempSyncCtx *ts = (TempSyncCtx *)data;
-
-    for (int i = 0; i < ts->nb_sem; i++)
-        vk->DestroySemaphore(s->hwctx->act_dev, ts->sem[i], s->hwctx->alloc);
-
-    av_free(ts);
-}
-
 void ff_vk_exec_add_dep_wait_sem(FFVulkanContext *s, FFVkExecContext *e,
                                  VkSemaphore sem, uint64_t val,
                                  VkPipelineStageFlagBits2 stage)
@@ -747,17 +756,11 @@ void ff_vk_exec_add_dep_wait_sem(FFVulkanContext *s, 
FFVkExecContext *e,
     };
 }
 
-int ff_vk_exec_add_dep_bool_sem(FFVulkanContext *s, FFVkExecContext *e,
-                                VkSemaphore *sem, int nb,
-                                VkPipelineStageFlagBits2 stage,
-                                int wait)
+void ff_vk_exec_add_dep_bool_sem(FFVulkanContext *s, FFVkExecContext *e,
+                                 VkSemaphore *sem, int nb,
+                                 VkPipelineStageFlagBits2 stage,
+                                 int wait)
 {
-    int err;
-    size_t buf_size;
-    AVBufferRef *buf;
-    TempSyncCtx *ts;
-    FFVulkanFunctions *vk = &s->vkfn;
-
     /* Do not transfer ownership if we're signalling a binary semaphore,
      * since we're probably exporting it. */
     if (!wait) {
@@ -770,43 +773,15 @@ int ff_vk_exec_add_dep_bool_sem(FFVulkanContext *s, 
FFVkExecContext *e,
             };
         }
 
-        return 0;
-    }
-
-    buf_size = sizeof(*ts) + sizeof(VkSemaphore)*nb;
-    ts = av_mallocz(buf_size);
-    if (!ts) {
-        err = AVERROR(ENOMEM);
-        goto fail;
-    }
-
-    memcpy(ts->sem, sem, nb*sizeof(*sem));
-    ts->nb_sem = nb;
-
-    buf = av_buffer_create((uint8_t *)ts, buf_size, destroy_tmp_semaphores, s, 
0);
-    if (!buf) {
-        av_free(ts);
-        err = AVERROR(ENOMEM);
-        goto fail;
-    }
-
-    err = ff_vk_exec_add_dep_buf(s, e, &buf, 1, 0);
-    if (err < 0) {
-        av_buffer_unref(&buf);
-        return err;
+        return;
     }
 
+    /* Ownership of each semaphore passes to the execution */
     for (int i = 0; i < nb; i++) {
+        ff_vk_exec_add_dep_obj(s, e, VK_OBJECT_TYPE_SEMAPHORE,
+                               (uint64_t)sem[i]);
         ff_vk_exec_add_dep_wait_sem(s, e, sem[i], 0, stage);
     }
-
-    return 0;
-
-fail:
-    for (int i = 0; i < nb; i++)
-        vk->DestroySemaphore(s->hwctx->act_dev, sem[i], s->hwctx->alloc);
-
-    return err;
 }
 
 int ff_vk_exec_add_dep_frame(FFVulkanContext *s, FFVkExecContext *e, AVFrame 
*f,
@@ -1842,23 +1817,6 @@ const char *ff_vk_shader_rep_fmt(enum AVPixelFormat 
pix_fmt,
     }
 }
 
-typedef struct ImageViewCtx {
-    int nb_views;
-    VkImageView views[];
-} ImageViewCtx;
-
-static void destroy_imageviews(void *opaque, uint8_t *data)
-{
-    FFVulkanContext *s = opaque;
-    FFVulkanFunctions *vk = &s->vkfn;
-    ImageViewCtx *iv = (ImageViewCtx *)data;
-
-    for (int i = 0; i < iv->nb_views; i++)
-        vk->DestroyImageView(s->hwctx->act_dev, iv->views[i], s->hwctx->alloc);
-
-    av_free(iv);
-}
-
 static VkFormat map_fmt_to_rep(VkFormat fmt, enum FFVkShaderRepFormat rep_fmt)
 {
 #define REPS_FMT(fmt) \
@@ -2023,12 +1981,7 @@ int ff_vk_create_imageviews(FFVulkanContext *s, 
FFVkExecContext *e,
     AVVkFrame *vkf = (AVVkFrame *)f->data[0];
     const int nb_images = ff_vk_count_images(vkf);
     const int nb_planes = av_pix_fmt_count_planes(hwfc->sw_format);
-
-    ImageViewCtx *iv;
-    const size_t buf_size = sizeof(*iv) + nb_planes*sizeof(VkImageView);
-    iv = av_mallocz(buf_size);
-    if (!iv)
-        return AVERROR(ENOMEM);
+    VkImageView tmp_views[AV_NUM_DATA_POINTERS] = { 0 };
 
     for (int i = 0; i < nb_planes; i++) {
         VkImageViewUsageCreateInfo view_usage_info = {
@@ -2059,36 +2012,31 @@ int ff_vk_create_imageviews(FFVulkanContext *s, 
FFVkExecContext *e,
         }
 
         ret = vk->CreateImageView(s->hwctx->act_dev, &view_create_info,
-                                  s->hwctx->alloc, &iv->views[i]);
+                                  s->hwctx->alloc, &tmp_views[i]);
         if (ret != VK_SUCCESS) {
             av_log(s, AV_LOG_ERROR, "Failed to create imageview: %s\n",
                    ff_vk_ret2str(ret));
             err = AVERROR_EXTERNAL;
             goto fail;
         }
-
-        iv->nb_views++;
     }
 
-    buf = av_buffer_create((uint8_t *)iv, buf_size, destroy_imageviews, s, 0);
-    if (!buf) {
-        err = AVERROR(ENOMEM);
-        goto fail;
-    }
+    /* The execution context owns the views, destroying them on completion */
+    for (int i = 0; i < nb_planes; i++)
+        ff_vk_exec_add_dep_obj(s, e, VK_OBJECT_TYPE_IMAGE_VIEW,
+                               (uint64_t)tmp_views[i]);
 
-    /* Add to queue dependencies */
-    err = ff_vk_exec_add_dep_buf(s, e, &buf, 1, 0);
-    if (err < 0)
-        av_buffer_unref(&buf);
+    memcpy(views, tmp_views, nb_planes*sizeof(*views));
 
-    memcpy(views, iv->views, nb_planes*sizeof(*views));
+    return 0;
 
     return err;
 
 fail:
-    for (int i = 0; i < iv->nb_views; i++)
-        vk->DestroyImageView(s->hwctx->act_dev, iv->views[i], s->hwctx->alloc);
-    av_free(iv);
+    for (int i = 0; i < nb_planes; i++) {
+        if (tmp_views[i])
+            vk->DestroyImageView(s->hwctx->act_dev, tmp_views[i], 
s->hwctx->alloc);
+    }
     return err;
 }
 
diff --git a/libavutil/vulkan.h b/libavutil/vulkan.h
index ffdc1ff7b9..19734bf6bf 100644
--- a/libavutil/vulkan.h
+++ b/libavutil/vulkan.h
@@ -120,6 +120,11 @@ typedef struct FFVkBuffer {
 /* Default number of in-flight execution contexts per pool */
 #define FF_VK_DEFAULT_EXEC_CONTEXTS 4
 
+typedef struct FFVkExecObjDep {
+    uint64_t obj;
+    VkObjectType type;
+} FFVkExecObjDep;
+
 typedef struct FFVkExecContext {
     uint32_t idx;
     const struct FFVkExecPool *parent;
@@ -155,6 +160,10 @@ typedef struct FFVkExecContext {
     void *refstruct_deps[FF_VK_EXEC_MAX_BUF_DEPS];
     int nb_refstruct_deps;
 
+    /* Raw Vulkan object dependencies, destroyed on release */
+    FFVkExecObjDep obj_deps[FF_VK_EXEC_MAX_BUF_DEPS];
+    int nb_obj_deps;
+
     /* Frame dependencies */
     AVFrame *frame_deps[FF_VK_EXEC_MAX_FRAME_DEPS];
     int nb_frame_deps;
@@ -495,13 +504,18 @@ void ff_vk_exec_add_dep_refstruct(FFVulkanContext *s, 
FFVkExecContext *e,
 void ff_vk_exec_move_dep_refstruct(FFVulkanContext *s, FFVkExecContext *e,
                                    void *obj);
 
+/* Takes ownership of a raw Vulkan object, destroyed when the execution's
+ * dependencies are released. */
+void ff_vk_exec_add_dep_obj(FFVulkanContext *s, FFVkExecContext *e,
+                            VkObjectType type, uint64_t obj);
+
 void ff_vk_exec_add_dep_wait_sem(FFVulkanContext *s, FFVkExecContext *e,
                                  VkSemaphore sem, uint64_t val,
                                  VkPipelineStageFlagBits2 stage);
-int ff_vk_exec_add_dep_bool_sem(FFVulkanContext *s, FFVkExecContext *e,
-                                VkSemaphore *sem, int nb,
-                                VkPipelineStageFlagBits2 stage,
-                                int wait); /* Ownership transferred if !wait */
+void ff_vk_exec_add_dep_bool_sem(FFVulkanContext *s, FFVkExecContext *e,
+                                 VkSemaphore *sem, int nb,
+                                 VkPipelineStageFlagBits2 stage,
+                                 int wait); /* Ownership transferred if !wait 
*/
 int ff_vk_exec_add_dep_frame(FFVulkanContext *s, FFVkExecContext *e, AVFrame 
*f,
                              VkPipelineStageFlagBits2 wait_stage,
                              VkPipelineStageFlagBits2 signal_stage);

_______________________________________________
ffmpeg-cvslog mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to