This is an automated email from the git hooks/post-receive script. Git pushed a commit to branch master in repository ffmpeg.
commit b736d1c73e834e1c9b09950eca3c3a24150e7712 Author: Lynne <[email protected]> AuthorDate: Wed Feb 4 15:50:59 2026 +0100 Commit: Lynne <[email protected]> CommitDate: Thu Feb 19 19:42:29 2026 +0100 ffv1enc_vulkan: convert encode shader to compile-time SPIR-V generation --- configure | 2 +- libavcodec/ffv1enc_vulkan.c | 424 ++++----------------- libavcodec/vulkan/Makefile | 9 +- libavcodec/vulkan/ffv1_common.comp | 177 --------- .../vulkan/{ffv1_enc.comp => ffv1_enc.comp.glsl} | 163 ++++---- ..._golomb.comp.glsl => ffv1_enc_golomb.comp.glsl} | 2 +- ...v1_dec_rgb.comp.glsl => ffv1_enc_rgb.comp.glsl} | 4 +- ...omb.comp.glsl => ffv1_enc_rgb_golomb.comp.glsl} | 2 +- 8 files changed, 168 insertions(+), 615 deletions(-) diff --git a/configure b/configure index 8c18012f74..5c9cd1e180 100755 --- a/configure +++ b/configure @@ -3119,7 +3119,7 @@ exr_decoder_select="bswapdsp" exr_encoder_deps="zlib" ffv1_decoder_select="rangecoder" ffv1_encoder_select="rangecoder" -ffv1_vulkan_encoder_select="vulkan spirv_library" +ffv1_vulkan_encoder_select="vulkan spirv_compiler" ffvhuff_decoder_select="huffyuv_decoder" ffvhuff_encoder_select="huffyuv_encoder" fic_decoder_select="golomb" diff --git a/libavcodec/ffv1enc_vulkan.c b/libavcodec/ffv1enc_vulkan.c index 2f7c217f09..db41ddcf70 100644 --- a/libavcodec/ffv1enc_vulkan.c +++ b/libavcodec/ffv1enc_vulkan.c @@ -20,7 +20,6 @@ #include "libavutil/mem.h" #include "libavutil/vulkan.h" -#include "libavutil/vulkan_spirv.h" #include "avcodec.h" #include "internal.h" @@ -121,85 +120,20 @@ extern const unsigned int ff_ffv1_enc_reset_comp_spv_len; extern const unsigned char ff_ffv1_enc_reset_golomb_comp_spv_data[]; extern const unsigned int ff_ffv1_enc_reset_golomb_comp_spv_len; -extern const unsigned char ff_ffv1_enc_rct_search_comp_spv_data[]; -extern const unsigned int ff_ffv1_enc_rct_search_comp_spv_len; +extern const unsigned char ff_ffv1_enc_comp_spv_data[]; +extern const unsigned int ff_ffv1_enc_comp_spv_len; -typedef struct FFv1VkParameters { - VkDeviceAddress slice_state; - VkDeviceAddress scratch_data; - VkDeviceAddress out_data; +extern const unsigned char ff_ffv1_enc_rgb_comp_spv_data[]; +extern const unsigned int ff_ffv1_enc_rgb_comp_spv_len; - int32_t fmt_lut[4]; - int32_t sar[2]; - uint32_t chroma_shift[2]; +extern const unsigned char ff_ffv1_enc_golomb_comp_spv_data[]; +extern const unsigned int ff_ffv1_enc_golomb_comp_spv_len; - uint32_t plane_state_size; - uint32_t context_count; - uint32_t crcref; - uint32_t slice_size_max; - int rct_offset; - - uint8_t extend_lookup[8]; - uint8_t bits_per_raw_sample; - uint8_t context_model; - uint8_t version; - uint8_t micro_version; - uint8_t force_pcm; - uint8_t key_frame; - uint8_t components; - uint8_t planes; - uint8_t codec_planes; - uint8_t planar_rgb; - uint8_t transparency; - uint8_t colorspace; - uint8_t pic_mode; - uint8_t ec; - uint8_t ppi; - uint8_t chunks; - uint8_t rct_search; - uint8_t padding[3]; -} FFv1VkParameters; - -static void add_push_data(FFVulkanShader *shd) -{ - GLSLC(0, layout(push_constant, scalar) uniform pushConstants { ); - GLSLC(1, u8buf slice_state; ); - GLSLC(1, u8buf scratch_data; ); - GLSLC(1, u8buf out_data; ); - GLSLC(0, ); - GLSLC(1, ivec4 fmt_lut; ); - GLSLC(1, ivec2 sar; ); - GLSLC(1, uvec2 chroma_shift; ); - GLSLC(0, ); - GLSLC(1, uint plane_state_size; ); - GLSLC(1, uint context_count; ); - GLSLC(1, uint32_t crcref; ); - GLSLC(1, uint32_t slice_size_max; ); - GLSLC(1, int rct_offset; ); - GLSLC(0, ); - GLSLC(1, uint8_t extend_lookup[8]; ); - GLSLC(1, uint8_t bits_per_raw_sample; ); - GLSLC(1, uint8_t context_model; ); - GLSLC(1, uint8_t version; ); - GLSLC(1, uint8_t micro_version; ); - GLSLC(1, uint8_t force_pcm; ); - GLSLC(1, uint8_t key_frame; ); - GLSLC(1, uint8_t components; ); - GLSLC(1, uint8_t planes; ); - GLSLC(1, uint8_t codec_planes; ); - GLSLC(1, uint8_t planar_rgb; ); - GLSLC(1, uint8_t transparency; ); - GLSLC(1, uint8_t colorspace; ); - GLSLC(1, uint8_t pic_mode; ); - GLSLC(1, uint8_t ec; ); - GLSLC(1, uint8_t ppi; ); - GLSLC(1, uint8_t chunks; ); - GLSLC(1, uint8_t rct_search; ); - GLSLC(1, uint8_t padding[3]; ); - GLSLC(0, }; ); - ff_vk_shader_add_push_const(shd, 0, sizeof(FFv1VkParameters), - VK_SHADER_STAGE_COMPUTE_BIT); -} +extern const unsigned char ff_ffv1_enc_rgb_golomb_comp_spv_data[]; +extern const unsigned int ff_ffv1_enc_rgb_golomb_comp_spv_len; + +extern const unsigned char ff_ffv1_enc_rct_search_comp_spv_data[]; +extern const unsigned int ff_ffv1_enc_rct_search_comp_spv_len; static int run_rct_search(AVCodecContext *avctx, FFVkExecContext *exec, AVFrame *enc_in, VkImageView *enc_in_views, @@ -242,7 +176,6 @@ static int vulkan_encode_ffv1_submit_frame(AVCodecContext *avctx, FFVulkanFunctions *vk = &fv->s.vkfn; VulkanEncodeFFv1FrameData *fd = exec->opaque; - FFv1VkParameters pd_old; /* Slice data */ AVBufferRef *slice_data_ref; @@ -260,7 +193,6 @@ static int vulkan_encode_ffv1_submit_frame(AVCodecContext *avctx, int has_inter = avctx->gop_size > 1; uint32_t context_count = f->context_count[f->context_model]; - const AVPixFmtDescriptor *fmt_desc = av_pix_fmt_desc_get(avctx->sw_pix_fmt); AVFrame *src = (AVFrame *)pict; VkImageView src_views[AV_NUM_DATA_POINTERS]; @@ -451,52 +383,6 @@ static int vulkan_encode_ffv1_submit_frame(AVCodecContext *avctx, nb_buf_bar = 0; } - /* Run setup shader */ - pd_old = (FFv1VkParameters) { - .slice_state = slice_data_buf->address + f->slice_count*256, - .out_data = out_data_buf->address, - .bits_per_raw_sample = f->bits_per_raw_sample, - .sar[0] = pict->sample_aspect_ratio.num, - .sar[1] = pict->sample_aspect_ratio.den, - .chroma_shift[0] = f->chroma_h_shift, - .chroma_shift[1] = f->chroma_v_shift, - .plane_state_size = plane_state_size, - .context_count = context_count, - .crcref = f->crcref, - .rct_offset = 1 << f->bits_per_raw_sample, - .slice_size_max = out_data_buf->size / f->slice_count, - .context_model = fv->ctx.context_model, - .version = f->version, - .micro_version = f->micro_version, - .force_pcm = fv->force_pcm, - .key_frame = f->key_frame, - .components = fmt_desc->nb_components, - .planes = av_pix_fmt_count_planes(avctx->sw_pix_fmt), - .codec_planes = f->plane_count, - .planar_rgb = ff_vk_mt_is_np_rgb(avctx->sw_pix_fmt) && - (ff_vk_count_images((AVVkFrame *)src->data[0]) > 1), - .transparency = f->transparency, - .colorspace = f->colorspace, - .pic_mode = !(pict->flags & AV_FRAME_FLAG_INTERLACED) ? 3 : - !(pict->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) ? 2 : 1, - .ec = f->ec, - .ppi = fv->ppi, - .chunks = fv->chunks, - .rct_search = fv->optimize_rct, - }; - - /* For some reason the C FFv1 encoder/decoder treats these differently */ - if (avctx->sw_pix_fmt == AV_PIX_FMT_GBRP10 || - avctx->sw_pix_fmt == AV_PIX_FMT_GBRP12 || - avctx->sw_pix_fmt == AV_PIX_FMT_GBRP14) - memcpy(pd_old.fmt_lut, (int [4]) { 2, 1, 0, 3 }, 4*sizeof(int)); - else - ff_vk_set_perm(avctx->sw_pix_fmt, pd_old.fmt_lut, 1); - - 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, @@ -603,16 +489,16 @@ static int vulkan_encode_ffv1_submit_frame(AVCodecContext *avctx, slice_data_buf, 0, slice_data_size*f->slice_count, VK_FORMAT_UNDEFINED); - ff_vk_shader_update_img_array(&fv->s, exec, &fv->enc, - src, src_views, - 1, 1, - VK_IMAGE_LAYOUT_GENERAL, - VK_NULL_HANDLE); ff_vk_shader_update_desc_buffer(&fv->s, exec, - &fv->enc, 1, 2, 0, + &fv->enc, 1, 1, 0, results_data_buf, 0, results_data_buf->size, VK_FORMAT_UNDEFINED); + ff_vk_shader_update_img_array(&fv->s, exec, &fv->enc, + src, src_views, + 1, 2, + VK_IMAGE_LAYOUT_GENERAL, + VK_NULL_HANDLE); if (fv->is_rgb) ff_vk_shader_update_img_array(&fv->s, exec, &fv->enc, tmp, tmp_views, @@ -623,7 +509,7 @@ static int vulkan_encode_ffv1_submit_frame(AVCodecContext *avctx, ff_vk_exec_bind_shader(&fv->s, exec, &fv->enc); ff_vk_shader_update_push_const(&fv->s, exec, &fv->enc, 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); /* Submit */ @@ -893,83 +779,6 @@ static int init_indirect(AVCodecContext *avctx, enum AVPixelFormat sw_format) return 0; } -static int check_support(AVHWFramesConstraints *constraints, - enum AVPixelFormat fmt) -{ - for (int i = 0; constraints->valid_sw_formats[i]; i++) { - if (constraints->valid_sw_formats[i] == fmt) - return 1; - } - return 0; -} - -static enum AVPixelFormat get_supported_rgb_buffer_fmt(AVCodecContext *avctx) -{ - VulkanEncodeFFv1Context *fv = avctx->priv_data; - - enum AVPixelFormat fmt; - AVHWFramesConstraints *constraints; - constraints = av_hwdevice_get_hwframe_constraints(fv->s.device_ref, - NULL); - - /* What we'd like to optimally have */ - fmt = fv->ctx.use32bit ? - (fv->ctx.transparency ? AV_PIX_FMT_RGBA128 : AV_PIX_FMT_RGB96) : - (fv->ctx.transparency ? AV_PIX_FMT_RGBA64 : AV_PIX_FMT_RGB48); - if (check_support(constraints, fmt)) - goto end; - - if (fv->ctx.use32bit) { - if (check_support(constraints, (fmt = AV_PIX_FMT_RGBA128))) - goto end; - } else { - if (check_support(constraints, (fmt = AV_PIX_FMT_RGBA64))) - goto end; - - if (!fv->ctx.transparency && - check_support(constraints, (fmt = AV_PIX_FMT_RGB96))) - goto end; - - if (check_support(constraints, (fmt = AV_PIX_FMT_RGBA128))) - goto end; - } - - fmt = AV_PIX_FMT_NONE; - -end: - av_hwframe_constraints_free(&constraints); - return fmt; -} - -static void define_shared_code(AVCodecContext *avctx, FFVulkanShader *shd) -{ - VulkanEncodeFFv1Context *fv = avctx->priv_data; - FFV1Context *f = &fv->ctx; - int smp_bits = fv->ctx.use32bit ? 32 : 16; - - av_bprintf(&shd->src, "#define RGB_LINECACHE %i\n" ,RGB_LINECACHE); - av_bprintf(&shd->src, "#define CONTEXT_SIZE %i\n" ,CONTEXT_SIZE); - av_bprintf(&shd->src, "#define MAX_QUANT_TABLE_MASK 0x%x\n" ,MAX_QUANT_TABLE_MASK); - - if (f->ac == AC_GOLOMB_RICE) { - av_bprintf(&shd->src, "#define PB_UNALIGNED\n" ); - av_bprintf(&shd->src, "#define GOLOMB\n" ); - } - - if (fv->is_rgb) - av_bprintf(&shd->src, "#define RGB\n"); - - GLSLF(0, #define TYPE int%i_t ,smp_bits); - GLSLF(0, #define VTYPE2 i%ivec2 ,smp_bits); - GLSLF(0, #define VTYPE3 i%ivec3 ,smp_bits); - GLSLD(ff_source_rangecoder_comp); - - if (f->ac == AC_GOLOMB_RICE) - GLSLD(ff_source_ffv1_vlc_comp); - - GLSLD(ff_source_ffv1_common_comp); -} - static int init_rct_search_shader(AVCodecContext *avctx, VkSpecializationInfo *sl) { int err; @@ -1096,123 +905,78 @@ fail: return err; } -static int init_encode_shader(AVCodecContext *avctx, FFVkSPIRVCompiler *spv) +static int init_encode_shader(AVCodecContext *avctx, VkSpecializationInfo *sl) { int err; VulkanEncodeFFv1Context *fv = avctx->priv_data; - FFV1Context *f = &fv->ctx; FFVulkanShader *shd = &fv->enc; - FFVulkanDescriptorSetBinding *desc_set; - - uint8_t *spv_data; - size_t spv_len; - void *spv_opaque = NULL; - int use_cached_reader = fv->ctx.ac != AC_GOLOMB_RICE && - fv->s.driver_props.driverID == VK_DRIVER_ID_MESA_RADV; - - RET(ff_vk_shader_init(&fv->s, shd, "ffv1_enc", - VK_SHADER_STAGE_COMPUTE_BIT, - (const char *[]) { "GL_EXT_buffer_reference", - "GL_EXT_buffer_reference2" }, 2, - use_cached_reader ? CONTEXT_SIZE : 1, 1, 1, - 0)); - - /* Common codec header */ - GLSLD(ff_source_common_comp); - - add_push_data(shd); - - 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); - - if (use_cached_reader) - av_bprintf(&shd->src, "#define CACHED_SYMBOL_READER 1\n"); - - 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];", + + ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl, + (uint32_t []) { 1, 1, 1 }, 0); + + ff_vk_shader_add_push_const(shd, 0, sizeof(FFv1ShaderParams), + VK_SHADER_STAGE_COMPUTE_BIT); + + const FFVulkanDescriptorSetBinding desc_set_const[] = { + { /* rangecoder_buf */ + .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + .stages = VK_SHADER_STAGE_COMPUTE_BIT, }, - { - .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];", + { /* quant_buf */ + .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + .stages = VK_SHADER_STAGE_COMPUTE_BIT, }, - { - .name = "crc_ieee_buf", - .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - .stages = VK_SHADER_STAGE_COMPUTE_BIT, - .mem_layout = "scalar", - .buf_content = "uint32_t crc_ieee[256];", + { /* crc_ieee_buf */ + .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + .stages = VK_SHADER_STAGE_COMPUTE_BIT, }, }; + ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set_const, 3, 1, 0); - RET(ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 3, 1, 0)); - - define_shared_code(avctx, shd); - - 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, + const FFVulkanDescriptorSetBinding desc_set[] = { + { /* slice_data_buf */ + .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + .stages = VK_SHADER_STAGE_COMPUTE_BIT, }, - { - .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, + { /* slice_results_buf */ + .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + .stages = VK_SHADER_STAGE_COMPUTE_BIT, }, - { - .name = "results_data_buf", - .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, - .stages = VK_SHADER_STAGE_COMPUTE_BIT, - .mem_quali = "writeonly", - .buf_content = "uint64_t slice_results[2048];", + { /* src */ + .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, + .stages = VK_SHADER_STAGE_COMPUTE_BIT, + .elems = av_pix_fmt_count_planes(fv->s.frames->sw_format), }, - { /* place holder for desc_set[3] */ - .name = "placeholder", + { /* tmp */ + .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, + .stages = VK_SHADER_STAGE_COMPUTE_BIT, }, }; - if (fv->is_rgb) { - AVHWFramesContext *intermediate_frames_ctx; - intermediate_frames_ctx = (AVHWFramesContext *)fv->intermediate_frames_ref->data; - desc_set[3] = (FFVulkanDescriptorSetBinding) { - .name = "tmp", - .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, - .dimensions = 2, - .mem_layout = ff_vk_shader_rep_fmt(intermediate_frames_ctx->sw_format, - FF_VK_REP_NATIVE), - .stages = VK_SHADER_STAGE_COMPUTE_BIT, - }; + ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 3 + fv->is_rgb, 0, 0); + + if (fv->ctx.ac == AC_GOLOMB_RICE) { + if (fv->is_rgb) + ff_vk_shader_link(&fv->s, shd, + ff_ffv1_enc_rgb_golomb_comp_spv_data, + ff_ffv1_enc_rgb_golomb_comp_spv_len, "main"); + else + ff_vk_shader_link(&fv->s, shd, + ff_ffv1_enc_golomb_comp_spv_data, + ff_ffv1_enc_golomb_comp_spv_len, "main"); + } else { + if (fv->is_rgb) + ff_vk_shader_link(&fv->s, shd, + ff_ffv1_enc_rgb_comp_spv_data, + ff_ffv1_enc_rgb_comp_spv_len, "main"); + else + ff_vk_shader_link(&fv->s, shd, + ff_ffv1_enc_comp_spv_data, + ff_ffv1_enc_comp_spv_len, "main"); } - RET(ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 3 + fv->is_rgb, 0, 0)); - - GLSLD(ff_source_ffv1_enc_comp); - - 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_register_exec(&fv->s, &fv->exec_pool, shd)); fail: - if (spv_opaque) - spv->free_shader(spv, &spv_opaque); - return err; } @@ -1222,7 +986,6 @@ static av_cold int vulkan_encode_ffv1_init(AVCodecContext *avctx) size_t maxsize, max_heap_size, max_host_size; VulkanEncodeFFv1Context *fv = avctx->priv_data; FFV1Context *f = &fv->ctx; - FFVkSPIRVCompiler *spv; if ((err = ff_ffv1_common_init(avctx, f)) < 0) return err; @@ -1416,12 +1179,6 @@ static av_cold int vulkan_encode_ffv1_init(AVCodecContext *avctx) if (err < 0) return err; - spv = ff_vk_spirv_init(); - if (!spv) { - av_log(avctx, AV_LOG_ERROR, "Unable to initialize SPIR-V compiler!\n"); - return AVERROR_EXTERNAL; - } - /* Detect the special RGB coding mode */ fv->is_rgb = !(f->colorspace == 0 && avctx->sw_pix_fmt != AV_PIX_FMT_YA8) && !(avctx->sw_pix_fmt == AV_PIX_FMT_YA8); @@ -1432,6 +1189,8 @@ static av_cold int vulkan_encode_ffv1_init(AVCodecContext *avctx) /* Init shader specialization consts */ SPEC_LIST_CREATE(sl, 18, 18*sizeof(uint32_t)) + SPEC_LIST_ADD(sl, 0, 32, RGB_LINECACHE); + SPEC_LIST_ADD(sl, 1, 32, f->ec); 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); @@ -1439,45 +1198,28 @@ static av_cold int vulkan_encode_ffv1_init(AVCodecContext *avctx) if (fv->optimize_rct) { err = init_rct_search_shader(avctx, sl); - if (err < 0) { - spv->uninit(&spv); + if (err < 0) return err; - } } /* Init setup shader */ err = init_setup_shader(avctx, sl); - if (err < 0) { - spv->uninit(&spv); + if (err < 0) return err; - } /* Init reset shader */ err = init_reset_shader(avctx, sl); - if (err < 0) { - spv->uninit(&spv); + if (err < 0) return err; - } - if (fv->is_rgb) { - enum AVPixelFormat intermediate_fmt = get_supported_rgb_buffer_fmt(avctx); - if (intermediate_fmt == AV_PIX_FMT_NONE) { - av_log(avctx, AV_LOG_ERROR, "Unable to find a supported compatible " - "pixel format for RCT buffer!\n"); - return AVERROR(ENOTSUP); - } - - RET(init_indirect(avctx, intermediate_fmt)); - } + if (fv->is_rgb) + RET(init_indirect(avctx, fv->ctx.use32bit ? + AV_PIX_FMT_RGBA128 : AV_PIX_FMT_RGBA64)); /* Encode shader */ - err = init_encode_shader(avctx, spv); - if (err < 0) { - spv->uninit(&spv); + err = init_encode_shader(avctx, sl); + if (err < 0) return err; - } - - spv->uninit(&spv); /* Range coder data */ err = ff_ffv1_vk_init_state_transition_data(&fv->s, @@ -1516,12 +1258,12 @@ 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->enc, 0, 1, 0, &fv->quant_buf, - 0, fv->quant_buf.size, + 0, VK_WHOLE_SIZE, VK_FORMAT_UNDEFINED)); RET(ff_vk_shader_update_desc_buffer(&fv->s, &fv->exec_pool.contexts[0], &fv->enc, 0, 2, 0, &fv->crc_tab_buf, - 0, fv->crc_tab_buf.size, + 0, 256*sizeof(uint32_t), VK_FORMAT_UNDEFINED)); /* Temporary frame */ diff --git a/libavcodec/vulkan/Makefile b/libavcodec/vulkan/Makefile index 0899632528..8fa593df27 100644 --- a/libavcodec/vulkan/Makefile +++ b/libavcodec/vulkan/Makefile @@ -1,14 +1,13 @@ clean:: $(RM) $(CLEANSUFFIXES:%=libavcodec/vulkan/%) -OBJS-$(CONFIG_FFV1_VULKAN_ENCODER) += vulkan/common.o \ - vulkan/rangecoder.o vulkan/ffv1_vlc.o \ - vulkan/ffv1_common.o \ - vulkan/ffv1_enc.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.comp.spv.o \ + vulkan/ffv1_enc_golomb.comp.spv.o \ + vulkan/ffv1_enc_rgb.comp.spv.o \ + vulkan/ffv1_enc_rgb_golomb.comp.spv.o \ vulkan/ffv1_enc_rct_search.comp.spv.o OBJS-$(CONFIG_FFV1_VULKAN_HWACCEL) += vulkan/ffv1_dec_setup.comp.spv.o \ diff --git a/libavcodec/vulkan/ffv1_common.comp b/libavcodec/vulkan/ffv1_common.comp deleted file mode 100644 index b4bfd61217..0000000000 --- a/libavcodec/vulkan/ffv1_common.comp +++ /dev/null @@ -1,177 +0,0 @@ -/* - * FFv1 codec - * - * Copyright (c) 2024 Lynne <[email protected]> - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -struct SliceContext { - RangeCoder c; - - ivec2 slice_dim; - ivec2 slice_pos; - ivec2 slice_rct_coef; - u8vec3 quant_table_idx; - - uint slice_coding_mode; - bool slice_reset_contexts; -}; - -/* -1, { -1, 0 } */ -int predict(int L, ivec2 top) -{ - return mid_pred(L, L + top[1] - top[0], top[1]); -} - -/* { -2, -1 }, { -1, 0, 1 }, 0 */ -int get_context(VTYPE2 cur_l, VTYPE3 top_l, TYPE top2, uint8_t quant_table_idx) -{ - const int LT = top_l[0]; /* -1 */ - const int T = top_l[1]; /* 0 */ - const int RT = top_l[2]; /* 1 */ - const int L = cur_l[1]; /* -1 */ - - int base = quant_table[quant_table_idx][0][(L - LT) & MAX_QUANT_TABLE_MASK] + - quant_table[quant_table_idx][1][(LT - T) & MAX_QUANT_TABLE_MASK] + - quant_table[quant_table_idx][2][(T - RT) & MAX_QUANT_TABLE_MASK]; - - if ((quant_table[quant_table_idx][3][127] == 0) && - (quant_table[quant_table_idx][4][127] == 0)) - return base; - - const int TT = top2; /* -2 */ - const int LL = cur_l[0]; /* -2 */ - return base + - quant_table[quant_table_idx][3][(LL - L) & MAX_QUANT_TABLE_MASK] + - quant_table[quant_table_idx][4][(TT - T) & MAX_QUANT_TABLE_MASK]; -} - -const uint32_t log2_run[41] = { - 0, 0, 0, 0, 1, 1, 1, 1, - 2, 2, 2, 2, 3, 3, 3, 3, - 4, 4, 5, 5, 6, 6, 7, 7, - 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, - 24, -}; - -uint slice_coord(uint width, uint sx, uint num_h_slices, uint chroma_shift) -{ - uint mpw = 1 << chroma_shift; - uint awidth = align(width, mpw); - - if ((version < 4) || ((version == 4) && (micro_version < 3))) - return width * sx / num_h_slices; - - sx = (2 * awidth * sx + num_h_slices * mpw) / (2 * num_h_slices * mpw) * mpw; - if (sx == awidth) - sx = width; - - return sx; -} - -#ifdef RGB -#define RGB_LBUF (RGB_LINECACHE - 1) -#define LADDR(p) (ivec2((p).x, ((p).y & RGB_LBUF))) - -ivec2 get_pred(readonly uimage2D pred, ivec2 sp, ivec2 off, - int comp, int sw, uint8_t quant_table_idx, bool extend_lookup) -{ - const ivec2 yoff_border1 = expectEXT(off.x == 0, false) ? off + ivec2(1, -1) : off; - - /* Thanks to the same coincidence as below, we can skip checking if off == 0, 1 */ - VTYPE3 top = VTYPE3(TYPE(imageLoad(pred, sp + LADDR(yoff_border1 + ivec2(-1, -1)))[comp]), - TYPE(imageLoad(pred, sp + LADDR(off + ivec2(0, -1)))[comp]), - TYPE(imageLoad(pred, sp + LADDR(off + ivec2(min(1, sw - off.x - 1), -1)))[comp])); - - /* Normally, we'd need to check if off != ivec2(0, 0) here, since otherwise, we must - * return zero. However, ivec2(-1, 0) + ivec2(1, -1) == ivec2(0, -1), e.g. previous - * row, 0 offset, same slice, which is zero since we zero out the buffer for RGB */ - TYPE cur = TYPE(imageLoad(pred, sp + LADDR(yoff_border1 + ivec2(-1, 0)))[comp]); - - int base = quant_table[quant_table_idx][0][(cur - top[0]) & MAX_QUANT_TABLE_MASK] + - quant_table[quant_table_idx][1][(top[0] - top[1]) & MAX_QUANT_TABLE_MASK] + - quant_table[quant_table_idx][2][(top[1] - top[2]) & MAX_QUANT_TABLE_MASK]; - - if (expectEXT(extend_lookup, false)) { - TYPE cur2 = TYPE(0); - if (expectEXT(off.x > 0, true)) { - const ivec2 yoff_border2 = expectEXT(off.x == 1, false) ? ivec2(-1, -1) : ivec2(-2, 0); - cur2 = TYPE(imageLoad(pred, sp + LADDR(off + yoff_border2))[comp]); - } - base += quant_table[quant_table_idx][3][(cur2 - cur) & MAX_QUANT_TABLE_MASK]; - -#if RGB_LINECACHE == 2 - /* top-2 became current upon swap */ - TYPE top2 = TYPE(imageLoad(pred, sp + LADDR(off))[comp]); -#else - TYPE top2 = TYPE(imageLoad(pred, sp + LADDR(off + ivec2(0, -2)))[comp]); -#endif - base += quant_table[quant_table_idx][4][(top2 - top[1]) & MAX_QUANT_TABLE_MASK]; - } - - /* context, prediction */ - return ivec2(base, predict(cur, VTYPE2(top))); -} - -#else /* RGB */ - -#define LADDR(p) (p) - -ivec2 get_pred(readonly uimage2D pred, ivec2 sp, ivec2 off, - int comp, int sw, uint8_t quant_table_idx, bool extend_lookup) -{ - const ivec2 yoff_border1 = off.x == 0 ? ivec2(1, -1) : ivec2(0, 0); - sp += off; - - VTYPE3 top = VTYPE3(TYPE(0), - TYPE(0), - TYPE(0)); - if (off.y > 0 && off != ivec2(0, 1)) - top[0] = TYPE(imageLoad(pred, sp + ivec2(-1, -1) + yoff_border1)[comp]); - if (off.y > 0) { - top[1] = TYPE(imageLoad(pred, sp + ivec2(0, -1))[comp]); - top[2] = TYPE(imageLoad(pred, sp + ivec2(min(1, sw - off.x - 1), -1))[comp]); - } - - TYPE cur = TYPE(0); - if (off != ivec2(0, 0)) - cur = TYPE(imageLoad(pred, sp + ivec2(-1, 0) + yoff_border1)[comp]); - - int base = quant_table[quant_table_idx][0][(cur - top[0]) & MAX_QUANT_TABLE_MASK] + - quant_table[quant_table_idx][1][(top[0] - top[1]) & MAX_QUANT_TABLE_MASK] + - quant_table[quant_table_idx][2][(top[1] - top[2]) & MAX_QUANT_TABLE_MASK]; - - if (expectEXT(extend_lookup, false)) { - TYPE cur2 = TYPE(0); - if (off.x > 0 && off != ivec2(1, 0)) { - const ivec2 yoff_border2 = off.x == 1 ? ivec2(1, -1) : ivec2(0, 0); - cur2 = TYPE(imageLoad(pred, sp + ivec2(-2, 0) + yoff_border2)[comp]); - } - base += quant_table[quant_table_idx][3][(cur2 - cur) & MAX_QUANT_TABLE_MASK]; - - TYPE top2 = TYPE(0); - if (off.y > 1) - top2 = TYPE(imageLoad(pred, sp + ivec2(0, -2))[comp]); - base += quant_table[quant_table_idx][4][(top2 - top[1]) & MAX_QUANT_TABLE_MASK]; - } - - /* context, prediction */ - return ivec2(base, predict(cur, VTYPE2(top))); -} -#endif diff --git a/libavcodec/vulkan/ffv1_enc.comp b/libavcodec/vulkan/ffv1_enc.comp.glsl similarity index 69% rename from libavcodec/vulkan/ffv1_enc.comp rename to libavcodec/vulkan/ffv1_enc.comp.glsl index 0a997b8a79..71d5bb982c 100644 --- a/libavcodec/vulkan/ffv1_enc.comp +++ b/libavcodec/vulkan/ffv1_enc.comp.glsl @@ -20,13 +20,24 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#pragma shader_stage(compute) +#extension GL_GOOGLE_include_directive : require + +#define ENCODE +#include "common.comp" +#include "ffv1_common.glsl" + +layout (set = 0, binding = 2, scalar) uniform crc_ieee_buf { + uint32_t crc_ieee[256]; +}; + +layout (set = 1, binding = 1, scalar) writeonly buffer slice_results_buf { + uint64_t slice_results[]; +}; +layout (set = 1, binding = 2) uniform uimage2D src[]; + #ifndef GOLOMB -#ifdef CACHED_SYMBOL_READER -shared uint8_t state[CONTEXT_SIZE]; -#define WRITE(c, off, val) put_rac_direct(c, state[off], val) -#else #define WRITE(c, off, val) put_rac(c, uint64_t(slice_state) + (state_off + off), val) -#endif /* Note - only handles signed values */ void put_symbol(inout RangeCoder c, uint state_off, int v) @@ -50,15 +61,10 @@ void put_symbol(inout RangeCoder c, uint state_off, int v) } void encode_line_pcm(inout SliceContext sc, readonly uimage2D img, - ivec2 sp, int y, int p, int comp, int bits) + ivec2 sp, int y, int p, int comp) { int w = sc.slice_dim.x; -#ifdef CACHED_SYMBOL_READER - if (gl_LocalInvocationID.x > 0) - return; -#endif - #ifndef RGB if (p > 0 && p < 3) { w = ceil_rshift(w, chroma_shift.x); @@ -68,13 +74,15 @@ void encode_line_pcm(inout SliceContext sc, readonly uimage2D img, for (int x = 0; x < w; x++) { uint v = imageLoad(img, sp + LADDR(ivec2(x, y)))[comp]; - for (int i = (bits - 1); i >= 0; i--) - put_rac_equi(sc.c, bool(bitfieldExtract(v, i, 1))); + + [[unroll]] + for (uint i = (rct_offset >> 1); i > 0; i >>= 1) + put_rac_equi(sc.c, bool(v & i)); } } void encode_line(inout SliceContext sc, readonly uimage2D img, uint state_off, - ivec2 sp, int y, int p, int comp, int bits, + ivec2 sp, int y, int p, int comp, uint8_t quant_table_idx, const int run_index) { int w = sc.slice_dim.x; @@ -88,7 +96,7 @@ void encode_line(inout SliceContext sc, readonly uimage2D img, uint state_off, for (int x = 0; x < w; x++) { ivec2 d = get_pred(img, sp, ivec2(x, y), comp, w, - quant_table_idx, extend_lookup[quant_table_idx] > 0); + quant_table_idx, extend_lookup[quant_table_idx]); d[1] = int(imageLoad(img, sp + LADDR(ivec2(x, y)))[comp]) - d[1]; if (d[0] < 0) @@ -97,19 +105,8 @@ void encode_line(inout SliceContext sc, readonly uimage2D img, uint state_off, d[1] = fold(d[1], bits); uint context_off = state_off + CONTEXT_SIZE*d[0]; -#ifdef CACHED_SYMBOL_READER - u8buf sb = u8buf(uint64_t(slice_state) + context_off + gl_LocalInvocationID.x); - state[gl_LocalInvocationID.x] = sb.v; - barrier(); - if (gl_LocalInvocationID.x == 0) -#endif - put_symbol(sc.c, context_off, d[1]); - -#ifdef CACHED_SYMBOL_READER - barrier(); - sb.v = state[gl_LocalInvocationID.x]; -#endif + put_symbol(sc.c, context_off, d[1]); } } @@ -127,7 +124,7 @@ void init_golomb(inout SliceContext sc) } void encode_line(inout SliceContext sc, readonly uimage2D img, uint state_off, - ivec2 sp, int y, int p, int comp, int bits, + ivec2 sp, int y, int p, int comp, uint8_t quant_table_idx, inout int run_index) { int w = sc.slice_dim.x; @@ -144,7 +141,7 @@ void encode_line(inout SliceContext sc, readonly uimage2D img, uint state_off, for (int x = 0; x < w; x++) { ivec2 d = get_pred(img, sp, ivec2(x, y), comp, w, - quant_table_idx, extend_lookup[quant_table_idx] > 0); + quant_table_idx, extend_lookup[quant_table_idx]); d[1] = int(imageLoad(img, sp + LADDR(ivec2(x, y)))[comp]) - d[1]; if (d[0] < 0) @@ -177,7 +174,8 @@ void encode_line(inout SliceContext sc, readonly uimage2D img, uint state_off, } if (!run_mode) { - VlcState sb = VlcState(uint64_t(slice_state) + state_off + VLC_STATE_SIZE*d[0]); + VlcState sb = VlcState(uint64_t(slice_state) + + state_off + VLC_STATE_SIZE*d[0]); Symbol sym = get_vlc_symbol(sb, d[1], bits); put_bits(pb, sym.bits, sym.val); } @@ -200,8 +198,8 @@ void encode_line(inout SliceContext sc, readonly uimage2D img, uint state_off, ivec4 load_components(ivec2 pos) { ivec4 pix = ivec4(imageLoad(src[0], pos)); - if (planar_rgb != 0) { - for (int i = 1; i < (3 + transparency); i++) + if (planar_rgb) { + for (int i = 1; i < (3 + int(transparency)); i++) pix[i] = int(imageLoad(src[i], pos)[0]); } @@ -238,20 +236,14 @@ void encode_slice(inout SliceContext sc, const uint slice_idx) { ivec2 sp = sc.slice_pos; -#ifndef RGB - int bits = bits_per_raw_sample; -#else - int bits = 9; - if (bits != 8 || sc.slice_coding_mode != 0) - bits = bits_per_raw_sample + int(sc.slice_coding_mode != 1); - - sp.y = int(gl_WorkGroupID.y)*RGB_LINECACHE; +#ifdef RGB + sp.y = int(gl_WorkGroupID.y)*rgb_linecache; #endif #ifndef GOLOMB if (sc.slice_coding_mode == 1) { #ifndef RGB - for (int c = 0; c < components; c++) { + for (int c = 0; c < color_planes; c++) { int h = sc.slice_dim.y; if (c > 0 && c < 3) @@ -262,66 +254,66 @@ void encode_slice(inout SliceContext sc, const uint slice_idx) int comp = c - p; for (int y = 0; y < h; y++) - encode_line_pcm(sc, src[p], sp, y, p, comp, bits); + encode_line_pcm(sc, src[p], sp, y, p, comp); } #else for (int y = 0; y < sc.slice_dim.y; y++) { preload_rgb(sc, sp, sc.slice_dim.x, y, false); - encode_line_pcm(sc, tmp, sp, y, 0, 1, bits); - encode_line_pcm(sc, tmp, sp, y, 0, 2, bits); - encode_line_pcm(sc, tmp, sp, y, 0, 0, bits); - if (transparency == 1) - encode_line_pcm(sc, tmp, sp, y, 0, 3, bits); + encode_line_pcm(sc, tmp, sp, y, 0, 1); + encode_line_pcm(sc, tmp, sp, y, 0, 2); + encode_line_pcm(sc, tmp, sp, y, 0, 0); + if (transparency) + encode_line_pcm(sc, tmp, sp, y, 0, 3); } #endif - } else + return; + } +#endif + + u8vec4 quant_table_idx = sc.quant_table_idx.xyyz; + u32vec4 slice_state_off = (slice_idx*codec_planes + + uvec4(0, 1, 1, 2))*plane_state_size; + +#ifdef GOLOMB + init_golomb(slice_ctx[slice_idx]); #endif - { - u8vec4 quant_table_idx = sc.quant_table_idx.xyyz; - u32vec4 slice_state_off = (slice_idx*codec_planes + uvec4(0, 1, 1, 2))*plane_state_size; #ifndef RGB - for (int c = 0; c < components; c++) { - int run_index = 0; + for (int c = 0; c < color_planes; c++) { + int run_index = 0; - int h = sc.slice_dim.y; - if (c > 0 && c < 3) - h = ceil_rshift(h, chroma_shift.y); + int h = sc.slice_dim.y; + if (c > 0 && c < 3) + h = ceil_rshift(h, chroma_shift.y); - int p = min(c, planes - 1); - int comp = c - p; + int p = min(c, planes - 1); + int comp = c - p; - for (int y = 0; y < h; y++) - encode_line(sc, src[p], slice_state_off[c], sp, y, p, - comp, bits, quant_table_idx[c], run_index); - } + for (int y = 0; y < h; y++) + encode_line(sc, src[p], slice_state_off[c], sp, y, p, + comp, quant_table_idx[c], run_index); + } #else - int run_index = 0; - for (int y = 0; y < sc.slice_dim.y; y++) { - preload_rgb(sc, sp, sc.slice_dim.x, y, true); - - encode_line(sc, tmp, slice_state_off[0], - sp, y, 0, 1, bits, quant_table_idx[0], run_index); - encode_line(sc, tmp, slice_state_off[1], - sp, y, 0, 2, bits, quant_table_idx[1], run_index); - encode_line(sc, tmp, slice_state_off[2], - sp, y, 0, 0, bits, quant_table_idx[2], run_index); - if (transparency == 1) - encode_line(sc, tmp, slice_state_off[3], - sp, y, 0, 3, bits, quant_table_idx[3], run_index); - } -#endif + int run_index = 0; + for (int y = 0; y < sc.slice_dim.y; y++) { + preload_rgb(sc, sp, sc.slice_dim.x, y, true); + + encode_line(sc, tmp, slice_state_off[0], + sp, y, 0, 1, quant_table_idx[0], run_index); + encode_line(sc, tmp, slice_state_off[1], + sp, y, 0, 2, quant_table_idx[1], run_index); + encode_line(sc, tmp, slice_state_off[2], + sp, y, 0, 0, quant_table_idx[2], run_index); + if (transparency) + encode_line(sc, tmp, slice_state_off[3], + sp, y, 0, 3, quant_table_idx[3], run_index); } +#endif } void finalize_slice(inout SliceContext sc, const uint slice_idx) { -#ifdef CACHED_SYMBOL_READER - if (gl_LocalInvocationID.x > 0) - return; -#endif - #ifdef GOLOMB uint32_t enc_len = hdr_len + flush_put_bits(pb); #else @@ -338,7 +330,7 @@ void finalize_slice(inout SliceContext sc, const uint slice_idx) enc_len += 3; /* Calculate and write CRC */ - if (ec != 0) { + if (has_crc) { bs[enc_len].v = uint8_t(0); enc_len++; @@ -358,15 +350,12 @@ void finalize_slice(inout SliceContext sc, const uint slice_idx) } slice_results[slice_idx*2 + 0] = enc_len; - slice_results[slice_idx*2 + 1] = uint64_t(bs) - uint64_t(out_data); + slice_results[slice_idx*2 + 1] = uint64_t(bs) - uint64_t(slice_data); } void main(void) { const uint slice_idx = gl_WorkGroupID.y*gl_NumWorkGroups.x + gl_WorkGroupID.x; -#ifdef GOLOMB - init_golomb(slice_ctx[slice_idx]); -#endif encode_slice(slice_ctx[slice_idx], slice_idx); finalize_slice(slice_ctx[slice_idx], slice_idx); } diff --git a/libavcodec/vulkan/ffv1_dec_golomb.comp.glsl b/libavcodec/vulkan/ffv1_enc_golomb.comp.glsl similarity index 96% copy from libavcodec/vulkan/ffv1_dec_golomb.comp.glsl copy to libavcodec/vulkan/ffv1_enc_golomb.comp.glsl index 4de62a4888..a120564602 100644 --- a/libavcodec/vulkan/ffv1_dec_golomb.comp.glsl +++ b/libavcodec/vulkan/ffv1_enc_golomb.comp.glsl @@ -24,4 +24,4 @@ #extension GL_GOOGLE_include_directive : require #define GOLOMB -#include "ffv1_dec.comp.glsl" +#include "ffv1_enc.comp.glsl" diff --git a/libavcodec/vulkan/ffv1_dec_rgb.comp.glsl b/libavcodec/vulkan/ffv1_enc_rgb.comp.glsl similarity index 91% copy from libavcodec/vulkan/ffv1_dec_rgb.comp.glsl copy to libavcodec/vulkan/ffv1_enc_rgb.comp.glsl index fe0d6957df..24c79c222e 100644 --- a/libavcodec/vulkan/ffv1_dec_rgb.comp.glsl +++ b/libavcodec/vulkan/ffv1_enc_rgb.comp.glsl @@ -24,7 +24,7 @@ #extension GL_GOOGLE_include_directive : require #extension GL_EXT_shader_image_load_formatted : require -layout (set = 1, binding = 4) writeonly uniform uimage2D dst[]; +layout (set = 1, binding = 3) uniform uimage2D tmp; #define RGB -#include "ffv1_dec.comp.glsl" +#include "ffv1_enc.comp.glsl" diff --git a/libavcodec/vulkan/ffv1_dec_golomb.comp.glsl b/libavcodec/vulkan/ffv1_enc_rgb_golomb.comp.glsl similarity index 96% copy from libavcodec/vulkan/ffv1_dec_golomb.comp.glsl copy to libavcodec/vulkan/ffv1_enc_rgb_golomb.comp.glsl index 4de62a4888..8efffd19e8 100644 --- a/libavcodec/vulkan/ffv1_dec_golomb.comp.glsl +++ b/libavcodec/vulkan/ffv1_enc_rgb_golomb.comp.glsl @@ -24,4 +24,4 @@ #extension GL_GOOGLE_include_directive : require #define GOLOMB -#include "ffv1_dec.comp.glsl" +#include "ffv1_enc_rgb.comp.glsl" _______________________________________________ ffmpeg-cvslog mailing list -- [email protected] To unsubscribe send an email to [email protected]
