Commit 7d9a77daed for ffmpeg

commit 7d9a77daedd6ac2f4f0d7cda3acd310805f16294
Author: Lynne <dev@lynne.ee>
Date:   Sat Sep 26 14:50:56 2026 +0900

    ffv1_vulkan: store the quant tables as int32

    The tables were uploaded as int16, so every lookup in the shaders was a
    dword load followed by an extract and a sign extension. Converting them
    on upload makes each lookup a single load. The buffer is shared by the
    encoder and the decoder, which now bind exactly the range the tables
    occupy.

    Decoding a 6464x4852 16-bit RGB frame with 1024 slices on an RX 6900
    XT, with the bitstream in VRAM, goes from 177.1/146.6/142.9 ms to
    171.6/143.7/139.6 ms with context model 1/0/2.

diff --git a/libavcodec/ffv1_vulkan.c b/libavcodec/ffv1_vulkan.c
index 81843b1701..9c34a479d3 100644
--- a/libavcodec/ffv1_vulkan.c
+++ b/libavcodec/ffv1_vulkan.c
@@ -87,11 +87,12 @@ int ff_ffv1_vk_init_consts(FFVulkanContext *s, FFVkBuffer *vkb, FFV1Context *f)
     int err;

     uint8_t *buf_mapped;
+    int32_t (*quant_tables)[MAX_CONTEXT_INPUTS][MAX_QUANT_TABLE_SIZE];
     size_t buf_len = 256*sizeof(uint32_t) + /* CRC */
                      512*sizeof(uint8_t) + /* Rangecoder */
                      MAX_QUANT_TABLES*
                      MAX_CONTEXT_INPUTS*
-                     MAX_QUANT_TABLE_SIZE*sizeof(int16_t);
+                     MAX_QUANT_TABLE_SIZE*sizeof(int32_t);

     RET(ff_vk_create_buf(s, vkb,
                          buf_len,
@@ -106,8 +107,11 @@ int ff_ffv1_vk_init_consts(FFVulkanContext *s, FFVkBuffer *vkb, FFV1Context *f)

     set_rc_state_tab(f, buf_mapped + 256*sizeof(uint32_t));

-    memcpy(buf_mapped + 256*sizeof(uint32_t) + 512*sizeof(uint8_t),
-           f->quant_tables, sizeof(f->quant_tables));
+    quant_tables = (void *)(buf_mapped + 256*sizeof(uint32_t) + 512*sizeof(uint8_t));
+    for (int i = 0; i < MAX_QUANT_TABLES; i++)
+        for (int j = 0; j < MAX_CONTEXT_INPUTS; j++)
+            for (int k = 0; k < MAX_QUANT_TABLE_SIZE; k++)
+                quant_tables[i][j][k] = f->quant_tables[i][j][k];

     RET(ff_vk_unmap_buffer(s, vkb, 1));

diff --git a/libavcodec/ffv1enc_vulkan.c b/libavcodec/ffv1enc_vulkan.c
index 6895c24769..5de2c15087 100644
--- a/libavcodec/ffv1enc_vulkan.c
+++ b/libavcodec/ffv1enc_vulkan.c
@@ -1389,7 +1389,8 @@ static av_cold int vulkan_encode_ffv1_init(AVCodecContext *avctx)
                                         &fv->enc, 0, 1, 0,
                                         &fv->consts_buf,
                                         256*sizeof(uint32_t) + 512*sizeof(uint8_t),
-                                        VK_WHOLE_SIZE,
+                                        MAX_QUANT_TABLES*MAX_CONTEXT_INPUTS*
+                                        MAX_QUANT_TABLE_SIZE*sizeof(int32_t),
                                         VK_FORMAT_UNDEFINED));
     RET(ff_vk_shader_update_desc_buffer(&fv->s, &fv->exec_pool.contexts[0],
                                         &fv->enc, 0, 2, 0,
diff --git a/libavcodec/vulkan/ffv1_common.glsl b/libavcodec/vulkan/ffv1_common.glsl
index 40520f9cbc..a3177b0d75 100644
--- a/libavcodec/vulkan/ffv1_common.glsl
+++ b/libavcodec/vulkan/ffv1_common.glsl
@@ -180,7 +180,7 @@ u16vec4 get_slice_bits(in SliceContext sc)
 }

 layout (set = 0, binding = 1, scalar) readonly uniform quant_buf {
-    int16_t quant_table[MAX_QUANT_TABLES]
+    int32_t quant_table[MAX_QUANT_TABLES]
                        [MAX_CONTEXT_INPUTS]
                        [MAX_QUANT_TABLE_SIZE];
 };
diff --git a/libavcodec/vulkan_ffv1.c b/libavcodec/vulkan_ffv1.c
index 779f316c51..161f21e7cb 100644
--- a/libavcodec/vulkan_ffv1.c
+++ b/libavcodec/vulkan_ffv1.c
@@ -941,7 +941,8 @@ static int vk_decode_ffv1_init(AVCodecContext *avctx)
                                         &fv->decode, 0, 1, 0,
                                         &fv->consts_buf,
                                         256*sizeof(uint32_t) + 512*sizeof(uint8_t),
-                                        VK_WHOLE_SIZE,
+                                        MAX_QUANT_TABLES*MAX_CONTEXT_INPUTS*
+                                        MAX_QUANT_TABLE_SIZE*sizeof(int32_t),
                                         VK_FORMAT_UNDEFINED));

 fail: