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

Git pushed a commit to branch master
in repository ffmpeg.

commit 4038af3da81948d5b7e51d3c21ecd80c17177a14
Author:     Lynne <[email protected]>
AuthorDate: Wed Feb 4 13:48:10 2026 +0100
Commit:     Lynne <[email protected]>
CommitDate: Thu Feb 19 19:42:29 2026 +0100

    ffv1enc_vulkan: convert setup shader to compile-time SPIR-V generation
---
 libavcodec/ffv1_vulkan.h                           |   5 +
 libavcodec/ffv1enc_vulkan.c                        | 126 +++++++--------------
 libavcodec/vulkan/Makefile                         |   5 +-
 libavcodec/vulkan/ffv1_common.glsl                 |   7 ++
 ...fv1_enc_setup.comp => ffv1_enc_setup.comp.glsl} |  16 ++-
 5 files changed, 69 insertions(+), 90 deletions(-)

diff --git a/libavcodec/ffv1_vulkan.h b/libavcodec/ffv1_vulkan.h
index 8ec50ca3f1..fcd6f98532 100644
--- a/libavcodec/ffv1_vulkan.h
+++ b/libavcodec/ffv1_vulkan.h
@@ -54,6 +54,11 @@ typedef struct FFv1ShaderParams {
     uint32_t key_frame;
     uint32_t crcref;
     int micro_version;
+
+    /* Encoder-only */
+    int sar[2];
+    int pic_mode;
+    uint32_t slice_size_max;
 } FFv1ShaderParams;
 
 #endif /* AVCODEC_FFV1_VULKAN_H */
diff --git a/libavcodec/ffv1enc_vulkan.c b/libavcodec/ffv1enc_vulkan.c
index 8eac6d47eb..2f7c217f09 100644
--- a/libavcodec/ffv1enc_vulkan.c
+++ b/libavcodec/ffv1enc_vulkan.c
@@ -110,9 +110,11 @@ extern const char *ff_source_common_comp;
 extern const char *ff_source_rangecoder_comp;
 extern const char *ff_source_ffv1_vlc_comp;
 extern const char *ff_source_ffv1_common_comp;
-extern const char *ff_source_ffv1_enc_setup_comp;
 extern const char *ff_source_ffv1_enc_comp;
 
+extern const unsigned char ff_ffv1_enc_setup_comp_spv_data[];
+extern const unsigned int ff_ffv1_enc_setup_comp_spv_len;
+
 extern const unsigned char ff_ffv1_enc_reset_comp_spv_data[];
 extern const unsigned int ff_ffv1_enc_reset_comp_spv_len;
 
@@ -388,6 +390,12 @@ static int vulkan_encode_ffv1_submit_frame(AVCodecContext 
*avctx,
         .key_frame = f->key_frame,
         .crcref = f->crcref,
         .micro_version = f->micro_version,
+
+        .sar[0] = pict->sample_aspect_ratio.num,
+        .sar[1] = pict->sample_aspect_ratio.den,
+        .pic_mode = !(pict->flags & AV_FRAME_FLAG_INTERLACED) ? 3 :
+                    !(pict->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) ? 2 : 1,
+        .slice_size_max = out_data_buf->size / f->slice_count,
     };
 
     for (int i = 0; i < f->quant_table_count; i++) {
@@ -404,18 +412,6 @@ static int vulkan_encode_ffv1_submit_frame(AVCodecContext 
*avctx,
     else
         ff_vk_set_perm(avctx->sw_pix_fmt, pd.fmt_lut, 1);
 
-    /* Setup shader */
-    ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->setup,
-                                    1, 0, 0,
-                                    slice_data_buf,
-                                    0, slice_data_size*f->slice_count,
-                                    VK_FORMAT_UNDEFINED);
-    ff_vk_shader_update_img_array(&fv->s, exec, &fv->setup,
-                                  src, src_views,
-                                  1, 1,
-                                  VK_IMAGE_LAYOUT_GENERAL,
-                                  VK_NULL_HANDLE);
-
     /* Add a buffer barrier between previous and current frame */
     if (!f->key_frame)
         ff_vk_buf_barrier(buf_bar[nb_buf_bar++], slice_data_buf,
@@ -456,7 +452,6 @@ static int vulkan_encode_ffv1_submit_frame(AVCodecContext 
*avctx,
     }
 
     /* Run setup shader */
-    ff_vk_exec_bind_shader(&fv->s, exec, &fv->setup);
     pd_old = (FFv1VkParameters) {
         .slice_state = slice_data_buf->address + f->slice_count*256,
         .out_data = out_data_buf->address,
@@ -501,9 +496,19 @@ static int vulkan_encode_ffv1_submit_frame(AVCodecContext 
*avctx,
     for (int i = 0; i < f->quant_table_count; i++)
         pd_old.extend_lookup[i] = (f->quant_tables[i][3][127] != 0) ||
                                   (f->quant_tables[i][4][127] != 0);
+
+    /* Setup shader */
+    ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->setup,
+                                    1, 0, 0,
+                                    slice_data_buf,
+                                    0, slice_data_size*f->slice_count,
+                                    VK_FORMAT_UNDEFINED);
+
+    ff_vk_exec_bind_shader(&fv->s, exec, &fv->setup);
     ff_vk_shader_update_push_const(&fv->s, exec, &fv->setup,
                                    VK_SHADER_STAGE_COMPUTE_BIT,
-                                   0, sizeof(pd_old), &pd_old);
+                                   0, sizeof(FFv1ShaderParams), &pd);
+
     vk->CmdDispatch(exec->buf, fv->ctx.num_h_slices, fv->ctx.num_v_slices, 1);
 
     /* Clean up temporary image */
@@ -1008,88 +1013,41 @@ fail:
     return err;
 }
 
-static int init_setup_shader(AVCodecContext *avctx, FFVkSPIRVCompiler *spv)
+static int init_setup_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
 {
     int err;
     VulkanEncodeFFv1Context *fv = avctx->priv_data;
-    FFV1Context *f = &fv->ctx;
     FFVulkanShader *shd = &fv->setup;
-    FFVulkanDescriptorSetBinding *desc_set;
-
-    uint8_t *spv_data;
-    size_t spv_len;
-    void *spv_opaque = NULL;
-
-    RET(ff_vk_shader_init(&fv->s, shd, "ffv1_setup",
-                          VK_SHADER_STAGE_COMPUTE_BIT,
-                          (const char *[]) { "GL_EXT_buffer_reference",
-                                             "GL_EXT_buffer_reference2" }, 2,
-                          1, 1, 1,
-                          0));
 
-    /* Common codec header */
-    GLSLD(ff_source_common_comp);
-    add_push_data(shd);
+    ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
+                      (uint32_t []) { 1, 1, 1 }, 0);
 
-    av_bprintf(&shd->src, "#define MAX_QUANT_TABLES %i\n", MAX_QUANT_TABLES);
-    av_bprintf(&shd->src, "#define MAX_CONTEXT_INPUTS %i\n", 
MAX_CONTEXT_INPUTS);
-    av_bprintf(&shd->src, "#define MAX_QUANT_TABLE_SIZE %i\n", 
MAX_QUANT_TABLE_SIZE);
-    av_bprintf(&shd->src, "#define FULL_RENORM\n");
+    ff_vk_shader_add_push_const(shd, 0, sizeof(FFv1ShaderParams),
+                                VK_SHADER_STAGE_COMPUTE_BIT);
 
-    desc_set = (FFVulkanDescriptorSetBinding []) {
-        {
-            .name        = "rangecoder_static_buf",
-            .type        = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
-            .stages      = VK_SHADER_STAGE_COMPUTE_BIT,
-            .mem_layout  = "scalar",
-            .buf_content = "uint8_t zero_one_state[512];",
-        },
-        { /* This descriptor is never used */
-            .name        = "quant_buf",
-            .type        = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
-            .stages      = VK_SHADER_STAGE_COMPUTE_BIT,
-            .mem_layout  = "scalar",
-            .buf_content = "int16_t quant_table[MAX_QUANT_TABLES]"
-                           "[MAX_CONTEXT_INPUTS][MAX_QUANT_TABLE_SIZE];",
+    const FFVulkanDescriptorSetBinding desc_set_const[] = {
+        { /* rangecoder_buf */
+            .type   = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
+            .stages = VK_SHADER_STAGE_COMPUTE_BIT,
         },
     };
-    RET(ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 2, 1, 0));
-
-    define_shared_code(avctx, shd);
+    ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set_const, 1, 1, 0);
 
-    desc_set = (FFVulkanDescriptorSetBinding []) {
-        {
-            .name        = "slice_data_buf",
-            .type        = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
-            .stages      = VK_SHADER_STAGE_COMPUTE_BIT,
-            .buf_content = "SliceContext slice_ctx",
-            .buf_elems   = f->max_slice_count,
-        },
-        {
-            .name       = "src",
-            .type       = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
-            .dimensions = 2,
-            .mem_layout = ff_vk_shader_rep_fmt(fv->s.frames->sw_format,
-                                               FF_VK_REP_NATIVE),
-            .elems      = av_pix_fmt_count_planes(fv->s.frames->sw_format),
-            .mem_quali  = "readonly",
-            .stages     = VK_SHADER_STAGE_COMPUTE_BIT,
+    const FFVulkanDescriptorSetBinding desc_set[] = {
+        { /* slice_data_buf */
+            .type   = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
+            .stages = VK_SHADER_STAGE_COMPUTE_BIT,
         },
     };
-    RET(ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 2, 0, 0));
-
-    GLSLD(ff_source_ffv1_enc_setup_comp);
+    ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 1, 0, 0);
 
-    RET(spv->compile_shader(&fv->s, spv, shd, &spv_data, &spv_len, "main",
-                            &spv_opaque));
-    RET(ff_vk_shader_link(&fv->s, shd, spv_data, spv_len, "main"));
+    RET(ff_vk_shader_link(&fv->s, shd,
+                          ff_ffv1_enc_setup_comp_spv_data,
+                          ff_ffv1_enc_setup_comp_spv_len, "main"));
 
     RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
 
 fail:
-    if (spv_opaque)
-        spv->free_shader(spv, &spv_opaque);
-
     return err;
 }
 
@@ -1473,9 +1431,11 @@ static av_cold int 
vulkan_encode_ffv1_init(AVCodecContext *avctx)
                        !fv->force_pcm && fv->optimize_rct;
 
     /* Init shader specialization consts */
-    SPEC_LIST_CREATE(sl, 16, 16*sizeof(uint32_t))
+    SPEC_LIST_CREATE(sl, 18, 18*sizeof(uint32_t))
     ff_ffv1_vk_set_common_sl(avctx, f, sl, fv->s.frames->sw_format);
     SPEC_LIST_ADD(sl, 15, 32, fv->force_pcm);
+    SPEC_LIST_ADD(sl, 16, 32, fv->optimize_rct);
+    SPEC_LIST_ADD(sl, 17, 32, f->context_model);
 
     if (fv->optimize_rct) {
         err = init_rct_search_shader(avctx, sl);
@@ -1486,7 +1446,7 @@ static av_cold int vulkan_encode_ffv1_init(AVCodecContext 
*avctx)
     }
 
     /* Init setup shader */
-    err = init_setup_shader(avctx, spv);
+    err = init_setup_shader(avctx, sl);
     if (err < 0) {
         spv->uninit(&spv);
         return err;
@@ -1544,7 +1504,7 @@ static av_cold int vulkan_encode_ffv1_init(AVCodecContext 
*avctx)
     RET(ff_vk_shader_update_desc_buffer(&fv->s, &fv->exec_pool.contexts[0],
                                         &fv->setup, 0, 0, 0,
                                         &fv->rangecoder_static_buf,
-                                        0, fv->rangecoder_static_buf.size,
+                                        0, 512*sizeof(uint8_t),
                                         VK_FORMAT_UNDEFINED));
 
     /* Update encode global descriptors */
diff --git a/libavcodec/vulkan/Makefile b/libavcodec/vulkan/Makefile
index 72cfeb7fd2..0899632528 100644
--- a/libavcodec/vulkan/Makefile
+++ b/libavcodec/vulkan/Makefile
@@ -4,9 +4,10 @@ clean::
 OBJS-$(CONFIG_FFV1_VULKAN_ENCODER)  +=  vulkan/common.o \
                                        vulkan/rangecoder.o vulkan/ffv1_vlc.o \
                                        vulkan/ffv1_common.o \
-                                       vulkan/ffv1_enc_setup.o 
vulkan/ffv1_enc.o
+                                       vulkan/ffv1_enc.o
 
-OBJS-$(CONFIG_FFV1_VULKAN_ENCODER) += vulkan/ffv1_enc_reset.comp.spv.o \
+OBJS-$(CONFIG_FFV1_VULKAN_ENCODER) += vulkan/ffv1_enc_setup.comp.spv.o \
+                                      vulkan/ffv1_enc_reset.comp.spv.o \
                                       vulkan/ffv1_enc_reset_golomb.comp.spv.o \
                                       vulkan/ffv1_enc_rct_search.comp.spv.o
 
diff --git a/libavcodec/vulkan/ffv1_common.glsl 
b/libavcodec/vulkan/ffv1_common.glsl
index e835cc7c9f..3c13ab2c6a 100644
--- a/libavcodec/vulkan/ffv1_common.glsl
+++ b/libavcodec/vulkan/ffv1_common.glsl
@@ -54,6 +54,8 @@ const ivec2 chroma_shift = ivec2(chroma_shift_x, 
chroma_shift_y);
 
 /* Encoder-only */
 layout (constant_id = 15) const bool force_pcm = false;
+layout (constant_id = 16) const bool rct_search = false;
+layout (constant_id = 17) const bool context_model = false;
 
 layout (push_constant, scalar) uniform pushConstants {
     u8buf slice_data;
@@ -69,6 +71,11 @@ layout (push_constant, scalar) uniform pushConstants {
     bool key_frame;
     uint32_t crcref;
     int micro_version;
+
+    /* Encoder-only */
+    ivec2 sar;
+    int pic_mode;
+    uint slice_size_max;
 };
 
 #define TYPE int32_t
diff --git a/libavcodec/vulkan/ffv1_enc_setup.comp 
b/libavcodec/vulkan/ffv1_enc_setup.comp.glsl
similarity index 89%
rename from libavcodec/vulkan/ffv1_enc_setup.comp
rename to libavcodec/vulkan/ffv1_enc_setup.comp.glsl
index 5338f94360..68ec6b7b88 100644
--- a/libavcodec/vulkan/ffv1_enc_setup.comp
+++ b/libavcodec/vulkan/ffv1_enc_setup.comp.glsl
@@ -20,12 +20,18 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#pragma shader_stage(compute)
+#extension GL_GOOGLE_include_directive : require
+
+#define FULL_RENORM
+#include "common.comp"
+#include "ffv1_common.glsl"
+
 uint8_t state[CONTEXT_SIZE];
 
-void init_slice(inout SliceContext sc, const uint slice_idx)
+void init_slice(inout SliceContext sc, uint slice_idx)
 {
     /* Set coordinates */
-    uvec2 img_size = imageSize(src[0]);
     uint sxs = slice_coord(img_size.x, gl_WorkGroupID.x + 0,
                            gl_NumWorkGroups.x, chroma_shift.x);
     uint sxe = slice_coord(img_size.x, gl_WorkGroupID.x + 1,
@@ -37,15 +43,15 @@ void init_slice(inout SliceContext sc, const uint slice_idx)
 
     sc.slice_pos = ivec2(sxs, sys);
     sc.slice_dim = ivec2(sxe - sxs, sye - sys);
-    sc.slice_coding_mode = int(force_pcm == 1);
+    sc.slice_coding_mode = int(force_pcm);
     sc.slice_reset_contexts = sc.slice_coding_mode == 1;
     sc.quant_table_idx = u8vec3(context_model);
 
-    if ((rct_search == 0) || (sc.slice_coding_mode == 1))
+    if (!rct_search || (sc.slice_coding_mode == 1))
         sc.slice_rct_coef = ivec2(1, 1);
 
     rac_init(sc.c,
-             OFFBUF(u8buf, out_data, slice_idx * slice_size_max),
+             OFFBUF(u8buf, slice_data, slice_idx * slice_size_max),
              slice_size_max);
 }
 

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

Reply via email to