PR #22660 opened by Lynne URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22660 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22660.patch
The main issues stemmed from the Vulkan framework - it was not designed around main context reusability. These commit fix dependency issues. >From acbb293282bc555939a66e43cdaba38e82ae8644 Mon Sep 17 00:00:00 2001 From: Lynne <[email protected]> Date: Thu, 26 Mar 2026 08:44:58 +0100 Subject: [PATCH 1/3] swscale/vulkan: fix potential memory issues The issue is that updating descriptors relies on the pointers of the structures remaining the same since creation. Sponsored-by: Sovereign Tech Fund --- libswscale/vulkan/ops.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/libswscale/vulkan/ops.c b/libswscale/vulkan/ops.c index 4d684116ca..bf8e9242f9 100644 --- a/libswscale/vulkan/ops.c +++ b/libswscale/vulkan/ops.c @@ -387,13 +387,14 @@ static int compile(SwsContext *sws, SwsOpList *ops, SwsCompiledOp *out) if (!s) return AVERROR(ENOTSUP); - VulkanPriv p = { - .s = s, - }; + VulkanPriv *p = av_mallocz(sizeof(*p)); + if (!p) + return AVERROR(ENOMEM); + p->s = s; #if CONFIG_LIBSHADERC || CONFIG_LIBGLSLANG { - err = add_ops_glsl(&p, s, ops, &p.shd); + err = add_ops_glsl(p, s, ops, &p.shd); if (err < 0) return err; } @@ -401,17 +402,22 @@ static int compile(SwsContext *sws, SwsOpList *ops, SwsCompiledOp *out) return AVERROR(ENOTSUP); #endif - err = ff_vk_shader_register_exec(&s->vkctx, &s->e, &p.shd); + err = ff_vk_shader_register_exec(&s->vkctx, &s->e, &p->shd); if (err < 0) - return err; + goto fail; *out = (SwsCompiledOp) { .opaque = true, .func_opaque = process, - .priv = av_memdup(&p, sizeof(p)), + .priv = p, .free = free_fn, }; + return 0; + +fail: + free_fn(p); + return err; } const SwsOpBackend backend_vulkan = { -- 2.52.0 >From 930a84639db8692c9f7154a9c62616f1ad637757 Mon Sep 17 00:00:00 2001 From: Lynne <[email protected]> Date: Mon, 30 Mar 2026 17:12:40 +0200 Subject: [PATCH 2/3] swscale/vulkan: move execution context to be a part of a shader The issue is that the main Vulkan context is shared between possibly multiple shaders, and registering a new shader requires allocating descriptors. Sponsored-by: Sovereign Tech Fund --- libswscale/vulkan/ops.c | 18 +++++++++--------- libswscale/vulkan/ops.h | 1 - 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/libswscale/vulkan/ops.c b/libswscale/vulkan/ops.c index bf8e9242f9..b3fb0ba022 100644 --- a/libswscale/vulkan/ops.c +++ b/libswscale/vulkan/ops.c @@ -34,7 +34,6 @@ static void ff_sws_vk_uninit(AVRefStructOpaque opaque, void *obj) if (s->spvc) s->spvc->uninit(&s->spvc); #endif - ff_vk_exec_pool_free(&s->vkctx, &s->e); ff_vk_uninit(&s->vkctx); } @@ -53,7 +52,6 @@ int ff_sws_vk_init(SwsContext *sws, AVBufferRef *dev_ref) FFVulkanOpsCtx *s = c->hw_priv; if (s->vkctx.device_ref && s->vkctx.device_ref->data != dev_ref->data) { /* Reinitialize with new context */ - ff_vk_exec_pool_free(&s->vkctx, &s->e); ff_vk_uninit(&s->vkctx); } else if (s->vkctx.device_ref && s->vkctx.device_ref->data == dev_ref->data) { return 0; @@ -69,11 +67,6 @@ int ff_sws_vk_init(SwsContext *sws, AVBufferRef *dev_ref) return AVERROR(ENOTSUP); } - err = ff_vk_exec_pool_init(&s->vkctx, s->qf, &s->e, 1, - 0, 0, 0, NULL); - if (err < 0) - return err; - #if CONFIG_LIBSHADERC || CONFIG_LIBGLSLANG if (!s->spvc) { s->spvc = ff_vk_spirv_init(); @@ -87,6 +80,7 @@ int ff_sws_vk_init(SwsContext *sws, AVBufferRef *dev_ref) typedef struct VulkanPriv { FFVulkanOpsCtx *s; + FFVkExecPool e; FFVulkanShader shd; enum FFVkShaderRepFormat src_rep; enum FFVkShaderRepFormat dst_rep; @@ -96,7 +90,7 @@ static void process(const SwsFrame *dst, const SwsFrame *src, int y, int h, const SwsPass *pass) { VulkanPriv *p = (VulkanPriv *) pass->priv; - FFVkExecContext *ec = ff_vk_exec_get(&p->s->vkctx, &p->s->e); + FFVkExecContext *ec = ff_vk_exec_get(&p->s->vkctx, &p->e); FFVulkanFunctions *vk = &p->s->vkctx.vkfn; ff_vk_exec_start(&p->s->vkctx, ec); @@ -153,6 +147,7 @@ static void process(const SwsFrame *dst, const SwsFrame *src, int y, int h, static void free_fn(void *priv) { VulkanPriv *p = priv; + ff_vk_exec_pool_free(&p->s->vkctx, &p->e); ff_vk_shader_free(&p->s->vkctx, &p->shd); av_free(priv); } @@ -392,6 +387,11 @@ static int compile(SwsContext *sws, SwsOpList *ops, SwsCompiledOp *out) return AVERROR(ENOMEM); p->s = s; + err = ff_vk_exec_pool_init(&s->vkctx, s->qf, &p->e, 1, + 0, 0, 0, NULL); + if (err < 0) + return err; + #if CONFIG_LIBSHADERC || CONFIG_LIBGLSLANG { err = add_ops_glsl(p, s, ops, &p.shd); @@ -402,7 +402,7 @@ static int compile(SwsContext *sws, SwsOpList *ops, SwsCompiledOp *out) return AVERROR(ENOTSUP); #endif - err = ff_vk_shader_register_exec(&s->vkctx, &s->e, &p->shd); + err = ff_vk_shader_register_exec(&s->vkctx, &p->e, &p->shd); if (err < 0) goto fail; diff --git a/libswscale/vulkan/ops.h b/libswscale/vulkan/ops.h index 9427ac0b73..0421dba446 100644 --- a/libswscale/vulkan/ops.h +++ b/libswscale/vulkan/ops.h @@ -31,7 +31,6 @@ typedef struct FFVulkanOpsCtx { FFVulkanContext vkctx; AVVulkanDeviceQueueFamily *qf; - FFVkExecPool e; #if CONFIG_LIBSHADERC || CONFIG_LIBGLSLANG FFVkSPIRVCompiler *spvc; #endif -- 2.52.0 >From b5d98053761fbe09bfeddd710406adf1bfbf0247 Mon Sep 17 00:00:00 2001 From: Lynne <[email protected]> Date: Mon, 30 Mar 2026 17:15:21 +0200 Subject: [PATCH 3/3] swscale/vulkan: reference the Vulkan context for each shader The issue is that the main Vulkan context could get freed before the shader's context. This makes the shader context depend on the main Vulkan context. Sponsored-by: Sovereign Tech Fund --- libswscale/vulkan/ops.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libswscale/vulkan/ops.c b/libswscale/vulkan/ops.c index b3fb0ba022..e1021b950e 100644 --- a/libswscale/vulkan/ops.c +++ b/libswscale/vulkan/ops.c @@ -149,6 +149,7 @@ static void free_fn(void *priv) VulkanPriv *p = priv; ff_vk_exec_pool_free(&p->s->vkctx, &p->e); ff_vk_shader_free(&p->s->vkctx, &p->shd); + av_refstruct_unref(&p->s); av_free(priv); } @@ -385,7 +386,7 @@ static int compile(SwsContext *sws, SwsOpList *ops, SwsCompiledOp *out) VulkanPriv *p = av_mallocz(sizeof(*p)); if (!p) return AVERROR(ENOMEM); - p->s = s; + p->s = av_refstruct_ref(c->hw_priv); err = ff_vk_exec_pool_init(&s->vkctx, s->qf, &p->e, 1, 0, 0, 0, NULL); -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
