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: