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

Git pushed a commit to branch master
in repository ffmpeg.

commit f8f485fb3c4682c1aaf6601b802b68d59344cb48
Author:     Lynne <[email protected]>
AuthorDate: Tue Apr 21 06:44:51 2026 +0200
Commit:     Lynne <[email protected]>
CommitDate: Tue Apr 21 08:28:49 2026 +0200

    vf_interlace_vulkan: convert to compile-time SPIR-V generation
---
 configure                                          |   2 +-
 libavfilter/vf_interlace_vulkan.c                  | 141 +++++----------------
 libavfilter/vulkan/Makefile                        |   1 +
 libavfilter/vulkan/interlace.comp.glsl             |  73 +++++++++++
 .../vulkan/xfade.comp.glsl                         |  29 +++--
 5 files changed, 124 insertions(+), 122 deletions(-)

diff --git a/configure b/configure
index f5a1b4adb7..29c6748520 100755
--- a/configure
+++ b/configure
@@ -4202,7 +4202,7 @@ iccdetect_filter_deps="lcms2"
 iccgen_filter_deps="lcms2"
 identity_filter_select="scene_sad"
 interlace_filter_deps="gpl"
-interlace_vulkan_filter_deps="vulkan spirv_library"
+interlace_vulkan_filter_deps="vulkan spirv_compiler"
 kerndeint_filter_deps="gpl"
 ladspa_filter_deps="ladspa libdl"
 lcevc_filter_deps="liblcevc_dec"
diff --git a/libavfilter/vf_interlace_vulkan.c 
b/libavfilter/vf_interlace_vulkan.c
index afa8a634f8..6f393a7a08 100644
--- a/libavfilter/vf_interlace_vulkan.c
+++ b/libavfilter/vf_interlace_vulkan.c
@@ -18,7 +18,6 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "libavutil/vulkan_spirv.h"
 #include "libavutil/opt.h"
 #include "vulkan_filter.h"
 
@@ -26,6 +25,9 @@
 #include "filters.h"
 #include "video.h"
 
+extern const unsigned char ff_interlace_comp_spv_data[];
+extern const unsigned int ff_interlace_comp_spv_len;
+
 typedef struct InterlaceVulkanContext {
     FFVulkanContext vkctx;
 
@@ -41,51 +43,12 @@ typedef struct InterlaceVulkanContext {
     AVFrame *cur; /* first frame in pair */
 } InterlaceVulkanContext;
 
-static const char lowpass_off[] = {
-    C(0, vec4 get_line(sampler2D tex, const vec2 pos)                         )
-    C(0, {                                                                    )
-    C(1,     return texture(tex, pos);                                        )
-    C(0, }                                                                    )
-};
-
-static const char lowpass_lin[] = {
-    C(0, vec4 get_line(sampler2D tex, const vec2 pos)                         )
-    C(0, {                                                                    )
-    C(1,     return 0.50 * texture(tex, pos) +                                )
-    C(1,            0.25 * texture(tex, pos - ivec2(0, 1)) +                  )
-    C(1,            0.25 * texture(tex, pos + ivec2(0, 1));                   )
-    C(0, }                                                                    )
-};
-
-static const char lowpass_complex[] = {
-    C(0, vec4 get_line(sampler2D tex, const vec2 pos)                         )
-    C(0, {                                                                    )
-    C(1,     return  0.75  * texture(tex, pos) +                              )
-    C(1,             0.25  * texture(tex, pos - ivec2(0, 1)) +                )
-    C(1,             0.25  * texture(tex, pos + ivec2(0, 1)) +                )
-    C(1,            -0.125 * texture(tex, pos - ivec2(0, 2)) +                )
-    C(1,            -0.125 * texture(tex, pos + ivec2(0, 2));                 )
-    C(0, }                                                                    )
-};
-
 static av_cold int init_filter(AVFilterContext *ctx)
 {
     int err;
-    uint8_t *spv_data;
-    size_t spv_len;
-    void *spv_opaque = NULL;
     InterlaceVulkanContext *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;
-    }
 
     s->qf = ff_vk_qf_find(vkctx, VK_QUEUE_COMPUTE_BIT, 0);
     if (!s->qf) {
@@ -98,88 +61,44 @@ static av_cold int init_filter(AVFilterContext *ctx)
     RET(ff_vk_init_sampler(vkctx, &s->sampler, 1,
                            s->lowpass == VLPF_OFF ? VK_FILTER_NEAREST
                                                   : VK_FILTER_LINEAR));
-    RET(ff_vk_shader_init(vkctx, &s->shd, "interlace",
-                          VK_SHADER_STAGE_COMPUTE_BIT,
-                          NULL, 0,
-                          32, 32, 1,
-                          0));
-    shd = &s->shd;
-
-    desc = (FFVulkanDescriptorSetBinding []) {
-        {
-            .name       = "top_field",
-            .type       = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
-            .dimensions = 2,
-            .elems      = planes,
-            .stages     = VK_SHADER_STAGE_COMPUTE_BIT,
-            .samplers   = DUP_SAMPLER(s->sampler),
+
+    SPEC_LIST_CREATE(sl, 2, 2*sizeof(int))
+    SPEC_LIST_ADD(sl, 0, 32, s->lowpass);
+    SPEC_LIST_ADD(sl, 1, 32, planes);
+
+    ff_vk_shader_load(&s->shd, VK_SHADER_STAGE_COMPUTE_BIT,
+                      sl, (uint32_t []) { 32, 1, planes }, 0);
+
+    const FFVulkanDescriptorSetBinding desc[] = {
+        { /* top_field */
+            .type     = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
+            .stages   = VK_SHADER_STAGE_COMPUTE_BIT,
+            .samplers = DUP_SAMPLER(s->sampler),
+            .elems    = planes,
         },
-        {
-            .name       = "bot_field",
-            .type       = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
-            .dimensions = 2,
-            .elems      = planes,
-            .stages     = VK_SHADER_STAGE_COMPUTE_BIT,
-            .samplers   = DUP_SAMPLER(s->sampler),
+        { /* bot_field */
+            .type     = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
+            .stages   = VK_SHADER_STAGE_COMPUTE_BIT,
+            .samplers = DUP_SAMPLER(s->sampler),
+            .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,
+        { /* output_img */
+            .type   = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
+            .stages = VK_SHADER_STAGE_COMPUTE_BIT,
+            .elems  = planes,
         },
     };
+    ff_vk_shader_add_descriptor_set(vkctx, &s->shd, desc, 3, 0, 0);
 
-    RET(ff_vk_shader_add_descriptor_set(vkctx, shd, desc, 3, 0, 0));
-
-    switch (s->lowpass) {
-    case VLPF_OFF:
-        GLSLD(lowpass_off);
-        break;
-    case VLPF_LIN:
-        GLSLD(lowpass_lin);
-        break;
-    case VLPF_CMP:
-        GLSLD(lowpass_complex);
-        break;
-    }
-
-    GLSLC(0, void main()                                                  );
-    GLSLC(0, {                                                            );
-    GLSLC(1,     vec4 res;                                                );
-    GLSLC(1,     ivec2 size;                                              );
-    GLSLC(1,     const ivec2 pos = ivec2(gl_GlobalInvocationID.xy);       );
-    GLSLC(1,     const vec2 ipos = pos + vec2(0.5);                       );
-    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;                                             );
-        GLSLC(1,  if (pos.y %% 2 == 0)                                    );
-        GLSLF(1,      res = get_line(top_field[%i], ipos);              ,i);
-        GLSLC(1,  else                                                    );
-        GLSLF(1,      res = get_line(bot_field[%i], ipos);              ,i);
-        GLSLF(1,  imageStore(output_img[%i], pos, res);                 ,i);
-    }
-    GLSLC(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_interlace_comp_spv_data,
+                          ff_interlace_comp_spv_len, "main"));
 
     RET(ff_vk_shader_register_exec(vkctx, &s->e, &s->shd));
 
     s->initialized = 1;
 
 fail:
-    if (spv_opaque)
-        spv->free_shader(spv, &spv_opaque);
-    if (spv)
-        spv->uninit(&spv);
-
     return err;
 }
 
diff --git a/libavfilter/vulkan/Makefile b/libavfilter/vulkan/Makefile
index d033ee5b5f..c0e48207cc 100644
--- a/libavfilter/vulkan/Makefile
+++ b/libavfilter/vulkan/Makefile
@@ -5,3 +5,4 @@ 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.comp.spv.o
 OBJS-$(CONFIG_V360_VULKAN_FILTER) += vulkan/v360.comp.spv.o
+OBJS-$(CONFIG_INTERLACE_VULKAN_FILTER) += vulkan/interlace.comp.spv.o
diff --git a/libavfilter/vulkan/interlace.comp.glsl 
b/libavfilter/vulkan/interlace.comp.glsl
new file mode 100644
index 0000000000..8fe04af4f8
--- /dev/null
+++ b/libavfilter/vulkan/interlace.comp.glsl
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2025 (c) Niklas Haas
+ *
+ * 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
+ */
+
+#pragma shader_stage(compute)
+
+#extension GL_EXT_shader_image_load_formatted : require
+#extension GL_EXT_nonuniform_qualifier : require
+
+#define VLPF_OFF 0
+#define VLPF_LIN 1
+#define VLPF_CMP 2
+
+layout (constant_id = 0) const int lowpass = 0;
+layout (constant_id = 1) const int planes = 0;
+
+layout (local_size_x_id = 253, local_size_y_id = 254, local_size_z_id = 255) 
in;
+
+layout (set = 0, binding = 0) uniform sampler2D top_field[];
+layout (set = 0, binding = 1) uniform sampler2D bot_field[];
+layout (set = 0, binding = 2) uniform writeonly image2D output_img[];
+
+vec4 get_line(sampler2D tex, const vec2 pos)
+{
+    if (lowpass == VLPF_CMP) {
+        return  0.75  * texture(tex, pos) +
+                0.25  * texture(tex, pos - ivec2(0, 1)) +
+                0.25  * texture(tex, pos + ivec2(0, 1)) +
+               -0.125 * texture(tex, pos - ivec2(0, 2)) +
+               -0.125 * texture(tex, pos + ivec2(0, 2));
+    } else if (lowpass == VLPF_LIN) {
+        return 0.50 * texture(tex, pos) +
+               0.25 * texture(tex, pos - ivec2(0, 1)) +
+               0.25 * texture(tex, pos + ivec2(0, 1));
+    } else {
+        return texture(tex, pos);
+    }
+}
+
+void main()
+{
+    ivec2 pos = ivec2(gl_GlobalInvocationID.xy);
+    vec2 ipos = pos + vec2(0.5);
+
+    for (int i = 0; i < planes; i++) {
+        ivec2 size = imageSize(output_img[i]);
+        if (any(greaterThanEqual(pos, size)))
+            return;
+
+        vec4 res;
+        if ((pos.y % 2) == 0)
+            res = get_line(top_field[i], ipos);
+        else
+            res = get_line(bot_field[i], ipos);
+        imageStore(output_img[i], pos, res);
+    }
+}
diff --git a/libavcodec/vulkan/ffv1_dec_rgb_float_golomb.comp.glsl 
b/libavfilter/vulkan/xfade.comp.glsl
similarity index 69%
copy from libavcodec/vulkan/ffv1_dec_rgb_float_golomb.comp.glsl
copy to libavfilter/vulkan/xfade.comp.glsl
index e5f8a6691b..3a4759ad3d 100644
--- a/libavcodec/vulkan/ffv1_dec_rgb_float_golomb.comp.glsl
+++ b/libavfilter/vulkan/xfade.comp.glsl
@@ -1,8 +1,4 @@
 /*
- * FFv1 codec
- *
- * Copyright (c) 2026 Lynne <[email protected]>
- *
  * This file is part of FFmpeg.
  *
  * FFmpeg is free software; you can redistribute it and/or
@@ -21,12 +17,25 @@
  */
 
 #pragma shader_stage(compute)
-#extension GL_GOOGLE_include_directive : require
+
 #extension GL_EXT_shader_image_load_formatted : require
+#extension GL_EXT_scalar_block_layout : require
 
-layout (set = 1, binding = 5) writeonly uniform image2D dst[];
+#define FADE 0
+#define WIPELEFT 1
+#define WIPERIGHT 2
+#define WIPEUP 3
+#define WIPEDOWN 4
+#define SLIDEDOWN 5
+#define SLIDEUP 6
+#define SLIDELEFT 7
+#define SLIDERIGHT 8
+#define CIRCLEOPEN 9
+#define CIRCLECLOSE 10
+#define DISSOLVE 11
+#define PIXELIZE 12
+#define WIPETL 13
+#define WIPETR 14
+#define WIPEBL 15
+#define WIPEBR 16
 
-#define GOLOMB
-#define FLOAT
-#define RGB
-#include "ffv1_dec.comp.glsl"

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

Reply via email to