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

Git pushed a commit to branch master
in repository ffmpeg.

commit b6ac28aff6ca8efdf0be3a8a159ae37b7234e408
Author:     Lynne <[email protected]>
AuthorDate: Mon Aug 3 23:55:29 2026 +0900
Commit:     Lynne <[email protected]>
CommitDate: Wed Aug 5 16:04:36 2026 +0900

    vulkan: use fixed-size dependency arrays in FFVkExecContext
    
    Execution contexts track at most a few dozen dependencies so dynamically
    growing the arrays was just stupid, and ARR_REALLOC required the field
    name to also exist as a local variable.
---
 libavcodec/vulkan_ffv1.c |  4 +--
 libavutil/vulkan.c       | 90 +++++++-----------------------------------------
 libavutil/vulkan.h       | 49 +++++++++++---------------
 3 files changed, 35 insertions(+), 108 deletions(-)

diff --git a/libavcodec/vulkan_ffv1.c b/libavcodec/vulkan_ffv1.c
index 9dd96fc1a7..c21ddc66ac 100644
--- a/libavcodec/vulkan_ffv1.c
+++ b/libavcodec/vulkan_ffv1.c
@@ -310,8 +310,8 @@ static int vk_ffv1_end_frame(AVCodecContext *avctx)
 
         /* Wait on the previous frame, if its decode was ever submitted */
         if (vpl->sem)
-            RET(ff_vk_exec_add_dep_wait_sem(&ctx->s, exec, vpl->sem, 
vpl->sem_value,
-                                            
VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT));
+            ff_vk_exec_add_dep_wait_sem(&ctx->s, exec, vpl->sem, 
vpl->sem_value,
+                                        VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT);
     }
 
     RET(ff_vk_exec_add_dep_buf(&ctx->s, exec, &fp->slice_state, 1, 1));
diff --git a/libavutil/vulkan.c b/libavutil/vulkan.c
index 65b1ddba6e..52ca001cf9 100644
--- a/libavutil/vulkan.c
+++ b/libavutil/vulkan.c
@@ -310,18 +310,6 @@ void ff_vk_exec_pool_free(FFVulkanContext *s, FFVkExecPool 
*pool)
         }
 
         ff_vk_exec_discard_deps(s, e);
-
-        av_free(e->frame_deps);
-        av_free(e->sw_frame_deps);
-        av_free(e->buf_deps);
-        av_free(e->queue_family_dst);
-        av_free(e->layout_dst);
-        av_free(e->access_dst);
-        av_free(e->frame_update);
-        av_free(e->frame_locked);
-        av_free(e->sem_sig);
-        av_free(e->sem_sig_val_dst);
-        av_free(e->sem_wait);
     }
 
     /* Free shader-specific data */
@@ -641,14 +629,7 @@ void ff_vk_exec_discard_deps(FFVulkanContext *s, 
FFVkExecContext *e)
 int ff_vk_exec_add_dep_buf(FFVulkanContext *s, FFVkExecContext *e,
                            AVBufferRef **deps, int nb_deps, int ref)
 {
-    AVBufferRef **dst = av_fast_realloc(e->buf_deps, &e->buf_deps_alloc_size,
-                                        (e->nb_buf_deps + nb_deps) * 
sizeof(*dst));
-    if (!dst) {
-        ff_vk_exec_discard_deps(s, e);
-        return AVERROR(ENOMEM);
-    }
-
-    e->buf_deps = dst;
+    av_assert1((e->nb_buf_deps + nb_deps) <= FF_VK_EXEC_MAX_BUF_DEPS);
 
     for (int i = 0; i < nb_deps; i++) {
         if (!deps[i])
@@ -668,14 +649,7 @@ int ff_vk_exec_add_dep_buf(FFVulkanContext *s, 
FFVkExecContext *e,
 int ff_vk_exec_add_dep_sw_frame(FFVulkanContext *s, FFVkExecContext *e,
                                 AVFrame *f)
 {
-    AVFrame **dst = av_fast_realloc(e->sw_frame_deps, 
&e->sw_frame_deps_alloc_size,
-                                    (e->nb_sw_frame_deps + 1) * sizeof(*dst));
-    if (!dst) {
-        ff_vk_exec_discard_deps(s, e);
-        return AVERROR(ENOMEM);
-    }
-
-    e->sw_frame_deps = dst;
+    av_assert1(e->nb_sw_frame_deps < FF_VK_EXEC_MAX_SW_FRAME_DEPS);
 
     e->sw_frame_deps[e->nb_sw_frame_deps] = av_frame_clone(f);
     if (!e->sw_frame_deps[e->nb_sw_frame_deps]) {
@@ -688,16 +662,6 @@ int ff_vk_exec_add_dep_sw_frame(FFVulkanContext *s, 
FFVkExecContext *e,
     return 0;
 }
 
-#define ARR_REALLOC(str, arr, alloc_s, cnt)                               \
-    do {                                                                  \
-        arr = av_fast_realloc(str->arr, alloc_s, (cnt + 1)*sizeof(*arr)); \
-        if (!arr) {                                                       \
-            ff_vk_exec_discard_deps(s, e);                                \
-            return AVERROR(ENOMEM);                                       \
-        }                                                                 \
-        str->arr = arr;                                                   \
-    } while (0)
-
 typedef struct TempSyncCtx {
     int nb_sem;
     VkSemaphore sem[];
@@ -715,12 +679,11 @@ static void destroy_tmp_semaphores(void *opaque, uint8_t 
*data)
     av_free(ts);
 }
 
-int ff_vk_exec_add_dep_wait_sem(FFVulkanContext *s, FFVkExecContext *e,
-                                VkSemaphore sem, uint64_t val,
-                                VkPipelineStageFlagBits2 stage)
+void ff_vk_exec_add_dep_wait_sem(FFVulkanContext *s, FFVkExecContext *e,
+                                 VkSemaphore sem, uint64_t val,
+                                 VkPipelineStageFlagBits2 stage)
 {
-    VkSemaphoreSubmitInfo *sem_wait;
-    ARR_REALLOC(e, sem_wait, &e->sem_wait_alloc, e->sem_wait_cnt);
+    av_assert1(e->sem_wait_cnt < FF_VK_EXEC_MAX_SEM_OPS);
 
     e->sem_wait[e->sem_wait_cnt++] = (VkSemaphoreSubmitInfo) {
         .sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO,
@@ -728,8 +691,6 @@ int ff_vk_exec_add_dep_wait_sem(FFVulkanContext *s, 
FFVkExecContext *e,
         .value = val,
         .stageMask = stage,
     };
-
-    return 0;
 }
 
 int ff_vk_exec_add_dep_bool_sem(FFVulkanContext *s, FFVkExecContext *e,
@@ -746,10 +707,8 @@ int ff_vk_exec_add_dep_bool_sem(FFVulkanContext *s, 
FFVkExecContext *e,
     /* Do not transfer ownership if we're signalling a binary semaphore,
      * since we're probably exporting it. */
     if (!wait) {
+        av_assert1((e->sem_sig_cnt + nb) <= FF_VK_EXEC_MAX_SEM_OPS);
         for (int i = 0; i < nb; i++) {
-            VkSemaphoreSubmitInfo *sem_sig;
-            ARR_REALLOC(e, sem_sig, &e->sem_sig_alloc, e->sem_sig_cnt);
-
             e->sem_sig[e->sem_sig_cnt++] = (VkSemaphoreSubmitInfo) {
                 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO,
                 .semaphore = sem[i],
@@ -784,9 +743,7 @@ int ff_vk_exec_add_dep_bool_sem(FFVulkanContext *s, 
FFVkExecContext *e,
     }
 
     for (int i = 0; i < nb; i++) {
-        err = ff_vk_exec_add_dep_wait_sem(s, e, sem[i], 0, stage);
-        if (err < 0)
-            return err;
+        ff_vk_exec_add_dep_wait_sem(s, e, sem[i], 0, stage);
     }
 
     return 0;
@@ -802,14 +759,6 @@ int ff_vk_exec_add_dep_frame(FFVulkanContext *s, 
FFVkExecContext *e, AVFrame *f,
                              VkPipelineStageFlagBits2 wait_stage,
                              VkPipelineStageFlagBits2 signal_stage)
 {
-    uint8_t *frame_locked;
-    uint8_t *frame_update;
-    AVFrame **frame_deps;
-    AVBufferRef **buf_deps;
-    VkImageLayout *layout_dst;
-    uint32_t *queue_family_dst;
-    VkAccessFlagBits *access_dst;
-
     AVHWFramesContext *hwfc = (AVHWFramesContext *)f->hw_frames_ctx->data;
     AVVulkanFramesContext *vkfc = hwfc->hwctx;
     AVVkFrame *vkf = (AVVkFrame *)f->data[0];
@@ -820,19 +769,15 @@ int ff_vk_exec_add_dep_frame(FFVulkanContext *s, 
FFVkExecContext *e, AVFrame *f,
         if (e->frame_deps[i]->data[0] == f->data[0])
             return 1;
 
-    ARR_REALLOC(e, layout_dst,       &e->layout_dst_alloc,       
e->nb_frame_deps);
-    ARR_REALLOC(e, queue_family_dst, &e->queue_family_dst_alloc, 
e->nb_frame_deps);
-    ARR_REALLOC(e, access_dst,       &e->access_dst_alloc,       
e->nb_frame_deps);
-
-    ARR_REALLOC(e, frame_locked, &e->frame_locked_alloc_size, 
e->nb_frame_deps);
-    ARR_REALLOC(e, frame_update, &e->frame_update_alloc_size, 
e->nb_frame_deps);
-    ARR_REALLOC(e, frame_deps,   &e->frame_deps_alloc_size,   
e->nb_frame_deps);
+    av_assert1(e->nb_frame_deps < FF_VK_EXEC_MAX_FRAME_DEPS);
+    av_assert1((e->sem_wait_cnt + nb_images) <= FF_VK_EXEC_MAX_SEM_OPS);
+    av_assert1((e->sem_sig_cnt + nb_images) <= FF_VK_EXEC_MAX_SEM_OPS);
 
     /* prepare_frame in hwcontext_vulkan.c uses the regular frame management
      * code but has no frame yet, and it doesn't need to actually store a ref
      * to the frame. */
     if (f->buf[0]) {
-        ARR_REALLOC(e, buf_deps, &e->buf_deps_alloc_size, e->nb_buf_deps);
+        av_assert1(e->nb_buf_deps < FF_VK_EXEC_MAX_BUF_DEPS);
         e->buf_deps[e->nb_buf_deps] = av_buffer_ref(f->buf[0]);
         if (!e->buf_deps[e->nb_buf_deps]) {
             ff_vk_exec_discard_deps(s, e);
@@ -849,14 +794,6 @@ int ff_vk_exec_add_dep_frame(FFVulkanContext *s, 
FFVkExecContext *e, AVFrame *f,
     e->nb_frame_deps++;
 
     for (int i = 0; i < nb_images; i++) {
-        VkSemaphoreSubmitInfo *sem_wait;
-        VkSemaphoreSubmitInfo *sem_sig;
-        uint64_t **sem_sig_val_dst;
-
-        ARR_REALLOC(e, sem_wait, &e->sem_wait_alloc, e->sem_wait_cnt);
-        ARR_REALLOC(e, sem_sig, &e->sem_sig_alloc, e->sem_sig_cnt);
-        ARR_REALLOC(e, sem_sig_val_dst, &e->sem_sig_val_dst_alloc, 
e->sem_sig_val_dst_cnt);
-
         e->sem_wait[e->sem_wait_cnt++] = (VkSemaphoreSubmitInfo) {
             .sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO,
             .semaphore = vkf->sem[i],
@@ -901,7 +838,6 @@ int ff_vk_exec_mirror_sem_value(FFVulkanContext *s, 
FFVkExecContext *e,
                                 VkSemaphore *dst, uint64_t *dst_val,
                                 AVFrame *f)
 {
-    uint64_t **sem_sig_val_dst;
     AVVkFrame *vkf = (AVVkFrame *)f->data[0];
 
     /* Reject unknown frames */
@@ -912,7 +848,7 @@ int ff_vk_exec_mirror_sem_value(FFVulkanContext *s, 
FFVkExecContext *e,
     if (i == e->nb_frame_deps)
         return AVERROR(EINVAL);
 
-    ARR_REALLOC(e, sem_sig_val_dst, &e->sem_sig_val_dst_alloc, 
e->sem_sig_val_dst_cnt);
+    av_assert1(e->sem_sig_val_dst_cnt < FF_VK_EXEC_MAX_SEM_OPS);
 
     *dst     = vkf->sem[0];
     *dst_val = vkf->sem_value[0];
diff --git a/libavutil/vulkan.h b/libavutil/vulkan.h
index 15351036c8..daf5d3b280 100644
--- a/libavutil/vulkan.h
+++ b/libavutil/vulkan.h
@@ -108,6 +108,12 @@ typedef struct FFVkBuffer {
     AVBufferRef *host_ref;
 } FFVkBuffer;
 
+/* Fixed dependency limits per exec context (with room to spare) */
+#define FF_VK_EXEC_MAX_FRAME_DEPS 64
+#define FF_VK_EXEC_MAX_BUF_DEPS 256
+#define FF_VK_EXEC_MAX_SW_FRAME_DEPS 16
+#define FF_VK_EXEC_MAX_SEM_OPS (FF_VK_EXEC_MAX_FRAME_DEPS*AV_NUM_DATA_POINTERS)
+
 /* Default number of in-flight execution contexts per pool */
 #define FF_VK_DEFAULT_EXEC_CONTEXTS 4
 
@@ -134,46 +140,31 @@ typedef struct FFVkExecContext {
     int query_idx;
 
     /* Buffer dependencies */
-    AVBufferRef **buf_deps;
+    AVBufferRef *buf_deps[FF_VK_EXEC_MAX_BUF_DEPS];
     int nb_buf_deps;
-    unsigned int buf_deps_alloc_size;
 
     /* Frame dependencies */
-    AVFrame **frame_deps;
-    unsigned int frame_deps_alloc_size;
+    AVFrame *frame_deps[FF_VK_EXEC_MAX_FRAME_DEPS];
     int nb_frame_deps;
 
     /* Software frame dependencies */
-    AVFrame **sw_frame_deps;
-    unsigned int sw_frame_deps_alloc_size;
+    AVFrame *sw_frame_deps[FF_VK_EXEC_MAX_SW_FRAME_DEPS];
     int nb_sw_frame_deps;
 
-    VkSemaphoreSubmitInfo *sem_wait;
-    unsigned int sem_wait_alloc;
+    VkSemaphoreSubmitInfo sem_wait[FF_VK_EXEC_MAX_SEM_OPS];
     int sem_wait_cnt;
 
-    VkSemaphoreSubmitInfo *sem_sig;
-    unsigned int sem_sig_alloc;
+    VkSemaphoreSubmitInfo sem_sig[FF_VK_EXEC_MAX_SEM_OPS];
     int sem_sig_cnt;
 
-    uint64_t **sem_sig_val_dst;
-    unsigned int sem_sig_val_dst_alloc;
+    uint64_t *sem_sig_val_dst[FF_VK_EXEC_MAX_SEM_OPS];
     int sem_sig_val_dst_cnt;
 
-    uint8_t *frame_locked;
-    unsigned int frame_locked_alloc_size;
-
-    VkAccessFlagBits *access_dst;
-    unsigned int access_dst_alloc;
-
-    VkImageLayout *layout_dst;
-    unsigned int layout_dst_alloc;
-
-    uint32_t *queue_family_dst;
-    unsigned int queue_family_dst_alloc;
-
-    uint8_t *frame_update;
-    unsigned int frame_update_alloc_size;
+    uint8_t frame_locked[FF_VK_EXEC_MAX_FRAME_DEPS];
+    VkAccessFlagBits access_dst[FF_VK_EXEC_MAX_FRAME_DEPS];
+    VkImageLayout layout_dst[FF_VK_EXEC_MAX_FRAME_DEPS];
+    uint32_t queue_family_dst[FF_VK_EXEC_MAX_FRAME_DEPS];
+    uint8_t frame_update[FF_VK_EXEC_MAX_FRAME_DEPS];
 } FFVkExecContext;
 
 typedef struct FFVulkanDescriptorSet {
@@ -481,9 +472,9 @@ void ff_vk_exec_wait(FFVulkanContext *s, FFVkExecContext 
*e);
  */
 int ff_vk_exec_add_dep_buf(FFVulkanContext *s, FFVkExecContext *e,
                            AVBufferRef **deps, int nb_deps, int ref);
-int ff_vk_exec_add_dep_wait_sem(FFVulkanContext *s, FFVkExecContext *e,
-                                VkSemaphore sem, uint64_t val,
-                                VkPipelineStageFlagBits2 stage);
+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,

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

Reply via email to