vulkan_ffv1: initialize only the necessary shaders on init

The decoder will reinit the hwaccel upon pixfmt/dimension changes,
so we can remove the f->use32bit and is_rgb variants of all shaders.

This speeds up init time.
This commit is contained in:
Lynne
2025-11-22 22:37:17 +01:00
parent a1154b74a4
commit 56dea1a9e8

View File

@@ -59,11 +59,11 @@ typedef struct FFv1VulkanDecodePicture {
} FFv1VulkanDecodePicture; } FFv1VulkanDecodePicture;
typedef struct FFv1VulkanDecodeContext { typedef struct FFv1VulkanDecodeContext {
AVBufferRef *intermediate_frames_ref[2]; /* 16/32 bit */ AVBufferRef *intermediate_frames_ref;
FFVulkanShader setup; FFVulkanShader setup;
FFVulkanShader reset[2]; /* AC/Golomb */ FFVulkanShader reset;
FFVulkanShader decode[2][2][2]; /* 16/32 bit, AC/Golomb, Normal/RGB */ FFVulkanShader decode;
FFVkBuffer rangecoder_static_buf; FFVkBuffer rangecoder_static_buf;
FFVkBuffer quant_buf; FFVkBuffer quant_buf;
@@ -239,7 +239,7 @@ static int vk_ffv1_start_frame(AVCodecContext *avctx,
if (!vp->dpb_frame) if (!vp->dpb_frame)
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
err = av_hwframe_get_buffer(fv->intermediate_frames_ref[f->use32bit], err = av_hwframe_get_buffer(fv->intermediate_frames_ref,
vp->dpb_frame, 0); vp->dpb_frame, 0);
if (err < 0) if (err < 0)
return err; return err;
@@ -472,7 +472,7 @@ static int vk_ffv1_end_frame(AVCodecContext *avctx)
} }
/* Reset shader */ /* Reset shader */
reset_shader = &fv->reset[f->ac == AC_GOLOMB_RICE]; reset_shader = &fv->reset;
ff_vk_shader_update_desc_buffer(&ctx->s, exec, reset_shader, ff_vk_shader_update_desc_buffer(&ctx->s, exec, reset_shader,
1, 0, 0, 1, 0, 0,
slice_state, slice_state,
@@ -525,7 +525,7 @@ static int vk_ffv1_end_frame(AVCodecContext *avctx)
f->plane_count); f->plane_count);
/* Decode */ /* Decode */
decode_shader = &fv->decode[f->use32bit][f->ac == AC_GOLOMB_RICE][is_rgb]; decode_shader = &fv->decode;
ff_vk_shader_update_desc_buffer(&ctx->s, exec, decode_shader, ff_vk_shader_update_desc_buffer(&ctx->s, exec, decode_shader,
1, 0, 0, 1, 0, 0,
slice_state, slice_state,
@@ -821,7 +821,7 @@ static int init_decode_shader(FFV1Context *f, FFVulkanContext *s,
FFVulkanShader *shd, FFVulkanShader *shd,
AVHWFramesContext *dec_frames_ctx, AVHWFramesContext *dec_frames_ctx,
AVHWFramesContext *out_frames_ctx, AVHWFramesContext *out_frames_ctx,
int use32bit, int ac, int rgb) int ac, int rgb)
{ {
int err; int err;
FFVulkanDescriptorSetBinding *desc_set; FFVulkanDescriptorSetBinding *desc_set;
@@ -829,6 +829,7 @@ static int init_decode_shader(FFV1Context *f, FFVulkanContext *s,
uint8_t *spv_data; uint8_t *spv_data;
size_t spv_len; size_t spv_len;
void *spv_opaque = NULL; void *spv_opaque = NULL;
int use_cached_reader = ac != AC_GOLOMB_RICE && int use_cached_reader = ac != AC_GOLOMB_RICE &&
s->driver_props.driverID == VK_DRIVER_ID_MESA_RADV; s->driver_props.driverID == VK_DRIVER_ID_MESA_RADV;
@@ -877,7 +878,7 @@ static int init_decode_shader(FFV1Context *f, FFVulkanContext *s,
RET(ff_vk_shader_add_descriptor_set(s, shd, desc_set, 2, 1, 0)); RET(ff_vk_shader_add_descriptor_set(s, shd, desc_set, 2, 1, 0));
define_shared_code(shd, use32bit); define_shared_code(shd, f->use32bit);
if (ac == AC_GOLOMB_RICE) if (ac == AC_GOLOMB_RICE)
GLSLD(ff_source_ffv1_vlc_comp); GLSLD(ff_source_ffv1_vlc_comp);
@@ -973,18 +974,11 @@ static void vk_decode_ffv1_uninit(FFVulkanDecodeShared *ctx)
{ {
FFv1VulkanDecodeContext *fv = ctx->sd_ctx; FFv1VulkanDecodeContext *fv = ctx->sd_ctx;
av_buffer_unref(&fv->intermediate_frames_ref);
ff_vk_shader_free(&ctx->s, &fv->setup); ff_vk_shader_free(&ctx->s, &fv->setup);
ff_vk_shader_free(&ctx->s, &fv->reset);
for (int i = 0; i < 2; i++) /* 16/32 bit */ ff_vk_shader_free(&ctx->s, &fv->decode);
av_buffer_unref(&fv->intermediate_frames_ref[i]);
for (int i = 0; i < 2; i++) /* AC/Golomb */
ff_vk_shader_free(&ctx->s, &fv->reset[i]);
for (int i = 0; i < 2; i++) /* 16/32 bit */
for (int j = 0; j < 2; j++) /* AC/Golomb */
for (int k = 0; k < 2; k++) /* Normal/RGB */
ff_vk_shader_free(&ctx->s, &fv->decode[i][j][k]);
ff_vk_free_buf(&ctx->s, &fv->quant_buf); ff_vk_free_buf(&ctx->s, &fv->quant_buf);
ff_vk_free_buf(&ctx->s, &fv->rangecoder_static_buf); ff_vk_free_buf(&ctx->s, &fv->rangecoder_static_buf);
@@ -1029,38 +1023,33 @@ static int vk_decode_ffv1_init(AVCodecContext *avctx)
ctx->sd_ctx_free = &vk_decode_ffv1_uninit; ctx->sd_ctx_free = &vk_decode_ffv1_uninit;
AVHWFramesContext *hwfc = (AVHWFramesContext *)avctx->hw_frames_ctx->data;
AVHWFramesContext *dctx = hwfc;
enum AVPixelFormat sw_format = hwfc->sw_format;
int is_rgb = !(f->colorspace == 0 && sw_format != AV_PIX_FMT_YA8) &&
!(sw_format == AV_PIX_FMT_YA8);
/* Intermediate frame pool for RCT */ /* Intermediate frame pool for RCT */
for (int i = 0; i < 2; i++) { /* 16/32 bit */ if (is_rgb) {
RET(init_indirect(avctx, &ctx->s, &fv->intermediate_frames_ref[i], RET(init_indirect(avctx, &ctx->s, &fv->intermediate_frames_ref,
i ? AV_PIX_FMT_GBRAP32 : AV_PIX_FMT_GBRAP16)); f->use32bit ? AV_PIX_FMT_GBRAP32 : AV_PIX_FMT_GBRAP16));
dctx = (AVHWFramesContext *)fv->intermediate_frames_ref->data;
} }
/* Setup shader */ /* Setup shader */
RET(init_setup_shader(f, &ctx->s, &ctx->exec_pool, spv, &fv->setup)); RET(init_setup_shader(f, &ctx->s, &ctx->exec_pool, spv, &fv->setup));
/* Reset shaders */ /* Reset shader */
for (int i = 0; i < 2; i++) { /* AC/Golomb */ RET(init_reset_shader(f, &ctx->s, &ctx->exec_pool,
RET(init_reset_shader(f, &ctx->s, &ctx->exec_pool, spv, &fv->reset, f->ac));
spv, &fv->reset[i], !i ? AC_RANGE_CUSTOM_TAB : 0));
}
/* Decode shaders */ /* Decode shaders */
for (int i = 0; i < 2; i++) { /* 16/32 bit */ RET(init_decode_shader(f, &ctx->s, &ctx->exec_pool,
for (int j = 0; j < 2; j++) { /* AC/Golomb */ spv, &fv->decode,
for (int k = 0; k < 2; k++) { /* Normal/RGB */ dctx,
AVHWFramesContext *dec_frames_ctx; hwfc,
dec_frames_ctx = k ? (AVHWFramesContext *)fv->intermediate_frames_ref[i]->data : f->ac,
(AVHWFramesContext *)avctx->hw_frames_ctx->data; is_rgb));
RET(init_decode_shader(f, &ctx->s, &ctx->exec_pool,
spv, &fv->decode[i][j][k],
dec_frames_ctx,
(AVHWFramesContext *)avctx->hw_frames_ctx->data,
i,
!j ? AC_RANGE_CUSTOM_TAB : AC_GOLOMB_RICE,
k));
}
}
}
/* Range coder data */ /* Range coder data */
RET(ff_ffv1_vk_init_state_transition_data(&ctx->s, RET(ff_ffv1_vk_init_state_transition_data(&ctx->s,
@@ -1090,22 +1079,16 @@ static int vk_decode_ffv1_init(AVCodecContext *avctx)
VK_FORMAT_UNDEFINED)); VK_FORMAT_UNDEFINED));
/* Update decode global descriptors */ /* Update decode global descriptors */
for (int i = 0; i < 2; i++) { /* 16/32 bit */ RET(ff_vk_shader_update_desc_buffer(&ctx->s, &ctx->exec_pool.contexts[0],
for (int j = 0; j < 2; j++) { /* AC/Golomb */ &fv->decode, 0, 0, 0,
for (int k = 0; k < 2; k++) { /* Normal/RGB */ &fv->rangecoder_static_buf,
RET(ff_vk_shader_update_desc_buffer(&ctx->s, &ctx->exec_pool.contexts[0], 0, fv->rangecoder_static_buf.size,
&fv->decode[i][j][k], 0, 0, 0, VK_FORMAT_UNDEFINED));
&fv->rangecoder_static_buf, RET(ff_vk_shader_update_desc_buffer(&ctx->s, &ctx->exec_pool.contexts[0],
0, fv->rangecoder_static_buf.size, &fv->decode, 0, 1, 0,
VK_FORMAT_UNDEFINED)); &fv->quant_buf,
RET(ff_vk_shader_update_desc_buffer(&ctx->s, &ctx->exec_pool.contexts[0], 0, fv->quant_buf.size,
&fv->decode[i][j][k], 0, 1, 0, VK_FORMAT_UNDEFINED));
&fv->quant_buf,
0, fv->quant_buf.size,
VK_FORMAT_UNDEFINED));
}
}
}
fail: fail:
spv->uninit(&spv); spv->uninit(&spv);