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]

Reply via email to