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]
