vulkan_ffv1: always keep the decoder's fltmap descriptor valid

The setup shader statically uses the fltmap binding, but the decoder
only bound a buffer to it for float formats, leaving a dangling
descriptor on everything else, with the write reachable by any
bitstream signalling remap.

Gate remap on a new push-constant flag, so that streams signalling it
without a fltmap buffer error out, and point the descriptor at the
slice feedback buffer when no fltmap exists; the gate guarantees it is
never written through this binding.
This commit is contained in:
Lynne
2026-07-26 19:10:08 +08:00
parent 2b0c0b2c00
commit d42cd604d0
4 changed files with 24 additions and 9 deletions

View File

@@ -49,6 +49,9 @@ typedef struct FFv1ShaderParams {
int pic_mode;
uint32_t slice_size_max;
uint32_t max_pixels_per_slice;
/* Decoder-only */
uint32_t remap_allowed;
} FFv1ShaderParams;
#endif /* AVCODEC_FFV1_VULKAN_H */

View File

@@ -76,6 +76,9 @@ layout (push_constant, scalar) uniform pushConstants {
int pic_mode;
uint slice_size_max;
uint max_pixels_per_slice;
/* Decoder-only */
bool remap_allowed;
};
#include "rangecoder.glsl"

View File

@@ -202,8 +202,15 @@ bool decode_slice_header(uint slice_idx, inout SliceContext sc)
if (micro_version >= 4) {
sc.remap = get_usymbol(0);
if (sc.remap != 0 && decode_remap(slice_idx, sc))
return true;
if (sc.remap != 0) {
/* No fltmap buffer is bound unless the format can remap */
if (!remap_allowed) {
sc.remap = 0;
return true;
}
if (decode_remap(slice_idx, sc))
return true;
}
}
}

View File

@@ -347,13 +347,14 @@ static int vk_ffv1_end_frame(AVCodecContext *avctx)
2*f->slice_count*sizeof(uint32_t),
VK_WHOLE_SIZE,
VK_FORMAT_UNDEFINED);
if (fltmap_buf)
ff_vk_shader_update_desc_buffer(&ctx->s, exec, &fv->setup,
1, 3, 0,
fltmap_buf,
0,
VK_WHOLE_SIZE,
VK_FORMAT_UNDEFINED);
/* The binding is statically used by the shader, so it must always hold
* a valid buffer. */
ff_vk_shader_update_desc_buffer(&ctx->s, exec, &fv->setup,
1, 3, 0,
fltmap_buf ? fltmap_buf : slice_feedback,
0,
VK_WHOLE_SIZE,
VK_FORMAT_UNDEFINED);
ff_vk_exec_bind_shader(&ctx->s, exec, &fv->setup);
@@ -367,6 +368,7 @@ static int vk_ffv1_end_frame(AVCodecContext *avctx)
.key_frame = f->picture.f->flags & AV_FRAME_FLAG_KEY,
.crcref = f->crcref,
.micro_version = f->micro_version,
.remap_allowed = !!fltmap_buf,
};
for (int i = 0; i < f->quant_table_count; i++) {