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

Git pushed a commit to branch master
in repository ffmpeg.

commit f3b0ca4f2cb43b5f150af7608422af9dccb7f528
Author:     Lynne <[email protected]>
AuthorDate: Fri Jan 2 15:21:36 2026 +0100
Commit:     Lynne <[email protected]>
CommitDate: Mon Jan 12 17:28:42 2026 +0100

    avgblur_vulkan: generate SPIR-V during compilation
---
 configure                            |   2 +-
 libavfilter/vf_avgblur_vulkan.c      | 108 ++++++++---------------------------
 libavfilter/vulkan/Makefile          |   1 +
 libavfilter/vulkan/avgblur.comp.glsl |  63 ++++++++++++++++++++
 4 files changed, 89 insertions(+), 85 deletions(-)

diff --git a/configure b/configure
index 9cf4c5cf9b..d578581ec9 100755
--- a/configure
+++ b/configure
@@ -4035,7 +4035,7 @@ aresample_filter_deps="swresample"
 asr_filter_deps="pocketsphinx"
 ass_filter_deps="libass"
 avgblur_opencl_filter_deps="opencl"
-avgblur_vulkan_filter_deps="vulkan spirv_library"
+avgblur_vulkan_filter_deps="vulkan"
 azmq_filter_deps="libzmq"
 blackdetect_vulkan_filter_deps="vulkan spirv_library"
 blackframe_filter_deps="gpl"
diff --git a/libavfilter/vf_avgblur_vulkan.c b/libavfilter/vf_avgblur_vulkan.c
index 156278dd78..847390d064 100644
--- a/libavfilter/vf_avgblur_vulkan.c
+++ b/libavfilter/vf_avgblur_vulkan.c
@@ -19,13 +19,15 @@
  */
 
 #include "libavutil/random_seed.h"
-#include "libavutil/vulkan_spirv.h"
 #include "libavutil/opt.h"
 #include "vulkan_filter.h"
 
 #include "filters.h"
 #include "video.h"
 
+extern const unsigned char ff_avgblur_comp_spv_data[];
+extern const unsigned int ff_avgblur_comp_spv_len;
+
 typedef struct AvgBlurVulkanContext {
     FFVulkanContext vkctx;
 
@@ -38,43 +40,21 @@ typedef struct AvgBlurVulkanContext {
     struct {
         float filter_norm[4];
         int32_t filter_len[2];
+        uint32_t planes;
     } opts;
 
     int size_x;
     int size_y;
-    int planes;
 } AvgBlurVulkanContext;
 
-static const char blur_kernel[] = {
-    C(0, void distort(const ivec2 pos, const int idx)                         )
-    C(0, {                                                                    )
-    C(1,     vec4 sum = vec4(0);                                              )
-    C(1,     for (int y = -filter_len.y; y <= filter_len.y; y++)              )
-    C(1,        for (int x = -filter_len.x; x <= filter_len.x; x++)           )
-    C(2,            sum += imageLoad(input_img[idx], pos + ivec2(x, y));      )
-    C(0,                                                                      )
-    C(1,     imageStore(output_img[idx], pos, sum * filter_norm);             )
-    C(0, }                                                                    )
-};
-
 static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in)
 {
     int err;
-    uint8_t *spv_data;
-    size_t spv_len;
-    void *spv_opaque = NULL;
     AvgBlurVulkanContext *s = ctx->priv;
     FFVulkanContext *vkctx = &s->vkctx;
     const int planes = av_pix_fmt_count_planes(s->vkctx.output_format);
-    FFVulkanShader *shd;
-    FFVkSPIRVCompiler *spv;
-    FFVulkanDescriptorSetBinding *desc;
 
-    spv = ff_vk_spirv_init();
-    if (!spv) {
-        av_log(ctx, AV_LOG_ERROR, "Unable to initialize SPIR-V compiler!\n");
-        return AVERROR_EXTERNAL;
-    }
+    FFVulkanDescriptorSetBinding *desc;
 
     s->qf = ff_vk_qf_find(vkctx, VK_QUEUE_COMPUTE_BIT, 0);
     if (!s->qf) {
@@ -84,68 +64,33 @@ static av_cold int init_filter(AVFilterContext *ctx, 
AVFrame *in)
     }
 
     RET(ff_vk_exec_pool_init(vkctx, s->qf, &s->e, s->qf->num*4, 0, 0, 0, 
NULL));
-    RET(ff_vk_shader_init(vkctx, &s->shd, "avgblur",
-                          VK_SHADER_STAGE_COMPUTE_BIT,
-                          NULL, 0,
-                          32, 1, 1,
-                          0));
-    shd = &s->shd;
+
+    ff_vk_shader_load(&s->shd, VK_SHADER_STAGE_COMPUTE_BIT,
+                      NULL, (uint32_t []) { 32, 1, planes }, 0);
+
+    ff_vk_shader_add_push_const(&s->shd, 0, sizeof(s->opts),
+                                VK_SHADER_STAGE_COMPUTE_BIT);
 
     desc = (FFVulkanDescriptorSetBinding []) {
         {
-            .name       = "input_img",
-            .type       = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
-            .mem_layout = ff_vk_shader_rep_fmt(s->vkctx.input_format, 
FF_VK_REP_FLOAT),
-            .mem_quali  = "readonly",
-            .dimensions = 2,
-            .elems      = planes,
-            .stages     = VK_SHADER_STAGE_COMPUTE_BIT,
+            .name   = "input_img",
+            .type   = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
+            .stages = VK_SHADER_STAGE_COMPUTE_BIT,
+            .elems  = planes,
         },
         {
-            .name       = "output_img",
-            .type       = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
-            .mem_layout = ff_vk_shader_rep_fmt(s->vkctx.output_format, 
FF_VK_REP_FLOAT),
-            .mem_quali  = "writeonly",
-            .dimensions = 2,
-            .elems      = planes,
-            .stages     = VK_SHADER_STAGE_COMPUTE_BIT,
+            .name   = "output_img",
+            .type   = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
+            .stages = VK_SHADER_STAGE_COMPUTE_BIT,
+            .elems  = planes,
         },
     };
 
-    RET(ff_vk_shader_add_descriptor_set(vkctx, shd, desc, 2, 0, 0));
-
-    GLSLC(0, layout(push_constant, std430) uniform pushConstants {        );
-    GLSLC(1,    vec4 filter_norm;                                         );
-    GLSLC(1,    ivec2 filter_len;                                         );
-    GLSLC(0, };                                                           );
-    GLSLC(0,                                                              );
-
-    ff_vk_shader_add_push_const(&s->shd, 0, sizeof(s->opts),
-                                VK_SHADER_STAGE_COMPUTE_BIT);
-
-    GLSLD(   blur_kernel                                                  );
-    GLSLC(0, void main()                                                  );
-    GLSLC(0, {                                                            );
-    GLSLC(1,     ivec2 size;                                              );
-    GLSLC(1,     vec4 res;                                                );
-    GLSLC(1,     const ivec2 pos = ivec2(gl_GlobalInvocationID.xy);       );
-    for (int i = 0; i < planes; i++) {
-        GLSLC(0,                                                          );
-        GLSLF(1,  size = imageSize(output_img[%i]);                     ,i);
-        GLSLC(1,  if (!IS_WITHIN(pos, size))                              );
-        GLSLC(2,      return;                                             );
-        if (s->planes & (1 << i)) {
-            GLSLF(1, distort(pos, %i);                                  ,i);
-        } else {
-            GLSLF(1, res = imageLoad(input_img[%i], pos);               ,i);
-            GLSLF(1, imageStore(output_img[%i], pos, res);              ,i);
-        }
-    }
-    GLSLC(0, }                                                            );
+    ff_vk_shader_add_descriptor_set(vkctx, &s->shd, desc, 2, 0, 0);
 
-    RET(spv->compile_shader(vkctx, spv, &s->shd, &spv_data, &spv_len, "main",
-                            &spv_opaque));
-    RET(ff_vk_shader_link(vkctx, &s->shd, spv_data, spv_len, "main"));
+    RET(ff_vk_shader_link(vkctx, &s->shd,
+                          ff_avgblur_comp_spv_data,
+                          ff_avgblur_comp_spv_len, "main"));
 
     RET(ff_vk_shader_register_exec(vkctx, &s->e, &s->shd));
 
@@ -160,11 +105,6 @@ static av_cold int init_filter(AVFilterContext *ctx, 
AVFrame *in)
     s->opts.filter_norm[3] = s->opts.filter_norm[0];
 
 fail:
-    if (spv_opaque)
-        spv->free_shader(spv, &spv_opaque);
-    if (spv)
-        spv->uninit(&spv);
-
     return err;
 }
 
@@ -221,7 +161,7 @@ static void avgblur_vulkan_uninit(AVFilterContext *avctx)
 static const AVOption avgblur_vulkan_options[] = {
     { "sizeX",  "Set horizontal radius", OFFSET(size_x), AV_OPT_TYPE_INT, { 
.i64 = 3 }, 1, 32, .flags = FLAGS },
     { "sizeY",  "Set vertical radius", OFFSET(size_y), AV_OPT_TYPE_INT, { .i64 
= 3 }, 1, 32, .flags = FLAGS },
-    { "planes", "Set planes to filter (bitmask)", OFFSET(planes), 
AV_OPT_TYPE_INT, {.i64 = 0xF}, 0, 0xF, .flags = FLAGS },
+    { "planes", "Set planes to filter (bitmask)", OFFSET(opts.planes), 
AV_OPT_TYPE_INT, {.i64 = 0xF}, 0, 0xF, .flags = FLAGS },
     { NULL },
 };
 
diff --git a/libavfilter/vulkan/Makefile b/libavfilter/vulkan/Makefile
index 851e3e0cbf..eaad9bbbaf 100644
--- a/libavfilter/vulkan/Makefile
+++ b/libavfilter/vulkan/Makefile
@@ -1,6 +1,7 @@
 clean::
        $(RM) $(CLEANSUFFIXES:%=libavfilter/vulkan/%)
 
+OBJS-$(CONFIG_AVGBLUR_VULKAN_FILTER) += vulkan/avgblur.comp.spv.o
 OBJS-$(CONFIG_BWDIF_VULKAN_FILTER) += vulkan/bwdif.comp.spv.o
 OBJS-$(CONFIG_SCALE_VULKAN_FILTER) += vulkan/debayer.o
 
diff --git a/libavfilter/vulkan/avgblur.comp.glsl 
b/libavfilter/vulkan/avgblur.comp.glsl
new file mode 100644
index 0000000000..e7a476b98c
--- /dev/null
+++ b/libavfilter/vulkan/avgblur.comp.glsl
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2026 Lynne <[email protected]>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#version 460
+#pragma shader_stage(compute)
+
+#extension GL_EXT_shader_image_load_formatted : require
+#extension GL_EXT_scalar_block_layout : require
+#extension GL_EXT_nonuniform_qualifier : require
+
+layout (local_size_x_id = 253, local_size_y_id = 254, local_size_z_id = 255) 
in;
+
+layout (set = 0, binding = 0) uniform readonly  image2D input_img[];
+layout (set = 0, binding = 1) uniform writeonly image2D output_img[];
+
+layout (push_constant, scalar) uniform pushConstants {
+    vec4 filter_norm;
+    ivec2 filter_len;
+    uint planes;
+};
+
+void main()
+{
+    const ivec2 pos = ivec2(gl_GlobalInvocationID.xy);
+
+#define IS_WITHIN(v1, v2) ((v1.x < v2.x) && (v1.y < v2.y))
+    ivec2 size = imageSize(output_img[nonuniformEXT(gl_LocalInvocationID.z)]);
+    if (!IS_WITHIN(pos, size))
+        return;
+
+    if ((planes & (1 << gl_LocalInvocationID.z)) == 0) {
+        imageStore(output_img[gl_LocalInvocationID.z], pos,
+                   imageLoad(input_img[nonuniformEXT(gl_LocalInvocationID.z)],
+                             pos));
+        return;
+    }
+
+    vec4 sum = vec4(0);
+    for (int y = -filter_len.y; y <= filter_len.y; y++)
+        for (int x = -filter_len.x; x <= filter_len.x; x++)
+            sum += imageLoad(input_img[nonuniformEXT(gl_LocalInvocationID.z)],
+                             pos + ivec2(x, y));
+
+    imageStore(output_img[nonuniformEXT(gl_LocalInvocationID.z)],
+               pos, sum * filter_norm);
+}

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

Reply via email to