This is an automated email from the git hooks/post-receive script. Git pushed a commit to branch master in repository ffmpeg.
commit a6391168f2310941f2c021d257747de1103a0f4c Author: Lynne <[email protected]> AuthorDate: Fri Jan 2 10:00:10 2026 +0100 Commit: Lynne <[email protected]> CommitDate: Mon Jan 12 17:28:42 2026 +0100 bwdif_vulkan: use compile-time SPIR-V --- configure | 4 +- libavfilter/vf_bwdif_vulkan.c | 97 ++-------------------- libavfilter/vulkan/Makefile | 2 +- libavfilter/vulkan/{bwdif.comp => bwdif.comp.glsl} | 49 ++++++++++- 4 files changed, 57 insertions(+), 95 deletions(-) diff --git a/configure b/configure index 5a4fa45cf7..9cf4c5cf9b 100755 --- a/configure +++ b/configure @@ -4045,7 +4045,7 @@ boxblur_opencl_filter_deps="opencl gpl" bs2b_filter_deps="libbs2b" bwdif_cuda_filter_deps="ffnvcodec" bwdif_cuda_filter_deps_any="cuda_nvcc cuda_llvm" -bwdif_vulkan_filter_deps="vulkan spirv_library" +bwdif_vulkan_filter_deps="vulkan" chromaber_vulkan_filter_deps="vulkan spirv_library" color_vulkan_filter_deps="vulkan spirv_library" colorkey_opencl_filter_deps="opencl" @@ -4243,7 +4243,7 @@ avcodec_suggest="libm stdatomic spirv_library" avdevice_deps="avformat avcodec avutil" avdevice_suggest="libm stdatomic" avfilter_deps="avutil" -avfilter_suggest="libm stdatomic spirv_library" +avfilter_suggest="libm stdatomic zlib spirv_library" avformat_deps="avcodec avutil" avformat_suggest="libm network zlib stdatomic" avutil_suggest="clock_gettime ffnvcodec gcrypt libm zlib libdrm libmfx opencl openssl user32 vaapi vulkan videotoolbox corefoundation corevideo coremedia bcrypt stdatomic" diff --git a/libavfilter/vf_bwdif_vulkan.c b/libavfilter/vf_bwdif_vulkan.c index 549e814886..c6fb6abe9c 100644 --- a/libavfilter/vf_bwdif_vulkan.c +++ b/libavfilter/vf_bwdif_vulkan.c @@ -22,7 +22,6 @@ #include "libavutil/random_seed.h" #include "libavutil/opt.h" -#include "libavutil/vulkan_spirv.h" #include "vulkan_filter.h" #include "yadif.h" #include "filters.h" @@ -43,27 +42,17 @@ typedef struct BWDIFParameters { int current_field; } BWDIFParameters; -extern const char *ff_source_bwdif_comp; +extern const unsigned char ff_bwdif_comp_spv_data[]; +extern const unsigned int ff_bwdif_comp_spv_len; static av_cold int init_filter(AVFilterContext *ctx) { int err; - uint8_t *spv_data; - size_t spv_len; - void *spv_opaque = NULL; BWDIFVulkanContext *s = ctx->priv; FFVulkanContext *vkctx = &s->vkctx; const int planes = av_pix_fmt_count_planes(s->vkctx.output_format); - FFVulkanShader *shd; - FFVkSPIRVCompiler *spv; FFVulkanDescriptorSetBinding *desc; - spv = ff_vk_spirv_init(); - if (!spv) { - av_log(ctx, AV_LOG_ERROR, "Unable to initialize SPIR-V compiler!\n"); - return AVERROR_EXTERNAL; - } - s->qf = ff_vk_qf_find(vkctx, VK_QUEUE_COMPUTE_BIT, 0); if (!s->qf) { av_log(ctx, AV_LOG_ERROR, "Device has no compute queues\n"); @@ -73,119 +62,49 @@ static av_cold int init_filter(AVFilterContext *ctx) RET(ff_vk_exec_pool_init(vkctx, s->qf, &s->e, s->qf->num*4, 0, 0, 0, NULL)); - RET(ff_vk_shader_init(vkctx, &s->shd, "bwdif", - VK_SHADER_STAGE_COMPUTE_BIT, - NULL, 0, - 1, 64, 1, - 0)); - shd = &s->shd; + ff_vk_shader_load(&s->shd, VK_SHADER_STAGE_COMPUTE_BIT, NULL, + (uint32_t [3]) { 1, 64, planes }, 0); desc = (FFVulkanDescriptorSetBinding []) { { .name = "prev", .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, - .mem_layout = ff_vk_shader_rep_fmt(s->vkctx.input_format, FF_VK_REP_FLOAT), - .mem_quali = "readonly", - .dimensions = 2, .elems = planes, .stages = VK_SHADER_STAGE_COMPUTE_BIT, }, { .name = "cur", .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, - .mem_layout = ff_vk_shader_rep_fmt(s->vkctx.input_format, FF_VK_REP_FLOAT), - .mem_quali = "readonly", - .dimensions = 2, .elems = planes, .stages = VK_SHADER_STAGE_COMPUTE_BIT, }, { .name = "next", .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, - .mem_layout = ff_vk_shader_rep_fmt(s->vkctx.input_format, FF_VK_REP_FLOAT), - .mem_quali = "readonly", - .dimensions = 2, .elems = planes, .stages = VK_SHADER_STAGE_COMPUTE_BIT, }, { .name = "dst", .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, - .mem_layout = ff_vk_shader_rep_fmt(s->vkctx.output_format, FF_VK_REP_FLOAT), - .mem_quali = "writeonly", - .dimensions = 2, .elems = planes, .stages = VK_SHADER_STAGE_COMPUTE_BIT, }, }; - RET(ff_vk_shader_add_descriptor_set(vkctx, &s->shd, desc, 4, 0, 0)); - - GLSLC(0, layout(push_constant, std430) uniform pushConstants { ); - GLSLC(1, int parity; ); - GLSLC(1, int tff; ); - GLSLC(1, int current_field; ); - GLSLC(0, }; ); + ff_vk_shader_add_descriptor_set(vkctx, &s->shd, desc, 4, 0, 0); ff_vk_shader_add_push_const(&s->shd, 0, sizeof(BWDIFParameters), VK_SHADER_STAGE_COMPUTE_BIT); - GLSLD(ff_source_bwdif_comp ); - GLSLC(0, void main() ); - GLSLC(0, { ); - GLSLC(1, ivec2 size; ); - GLSLC(1, const ivec2 pos = ivec2(gl_GlobalInvocationID.xy); ); - GLSLC(1, bool filter_field = ((pos.y ^ parity) & 1) == 1; ); - GLSLF(1, bool is_intra = filter_field && (current_field == %i); ,YADIF_FIELD_END); - GLSLC(1, bool field_parity = (parity ^ tff) != 0; ); - GLSLC(0, ); - GLSLC(1, size = imageSize(dst[0]); ); - GLSLC(1, if (!IS_WITHIN(pos, size)) { ); - GLSLC(2, return; ); - GLSLC(1, } else if (is_intra) { ); - for (int i = 0; i < planes; i++) { - if (i == 1) { - GLSLF(2, size = imageSize(dst[%i]); ,i); - GLSLC(2, if (!IS_WITHIN(pos, size)) ); - GLSLC(3, return; ); - } - GLSLF(2, process_plane_intra(%i, pos); ,i); - } - GLSLC(1, } else if (filter_field) { ); - for (int i = 0; i < planes; i++) { - if (i == 1) { - GLSLF(2, size = imageSize(dst[%i]); ,i); - GLSLC(2, if (!IS_WITHIN(pos, size)) ); - GLSLC(3, return; ); - } - GLSLF(2, process_plane(%i, pos, filter_field, is_intra, field_parity); ,i); - } - GLSLC(1, } else { ); - for (int i = 0; i < planes; i++) { - if (i == 1) { - GLSLF(2, size = imageSize(dst[%i]); ,i); - GLSLC(2, if (!IS_WITHIN(pos, size)) ); - GLSLC(3, return; ); - } - GLSLF(2, imageStore(dst[%i], pos, imageLoad(cur[%i], pos)); ,i, i); - } - GLSLC(1, } ); - GLSLC(0, } ); - - RET(spv->compile_shader(vkctx, spv, &s->shd, &spv_data, &spv_len, "main", - &spv_opaque)); - RET(ff_vk_shader_link(vkctx, &s->shd, spv_data, spv_len, "main")); - + RET(ff_vk_shader_link(vkctx, &s->shd, + ff_bwdif_comp_spv_data, + ff_bwdif_comp_spv_len, "main")); RET(ff_vk_shader_register_exec(vkctx, &s->e, &s->shd)); s->initialized = 1; fail: - if (spv_opaque) - spv->free_shader(spv, &spv_opaque); - if (spv) - spv->uninit(&spv); - return err; } diff --git a/libavfilter/vulkan/Makefile b/libavfilter/vulkan/Makefile index 911cb1015e..851e3e0cbf 100644 --- a/libavfilter/vulkan/Makefile +++ b/libavfilter/vulkan/Makefile @@ -1,7 +1,7 @@ clean:: $(RM) $(CLEANSUFFIXES:%=libavfilter/vulkan/%) -OBJS-$(CONFIG_BWDIF_VULKAN_FILTER) += vulkan/bwdif.o +OBJS-$(CONFIG_BWDIF_VULKAN_FILTER) += vulkan/bwdif.comp.spv.o OBJS-$(CONFIG_SCALE_VULKAN_FILTER) += vulkan/debayer.o VULKAN = $(subst $(SRC_PATH)/,,$(wildcard $(SRC_PATH)/libavfilter/vulkan/*.comp)) diff --git a/libavfilter/vulkan/bwdif.comp b/libavfilter/vulkan/bwdif.comp.glsl similarity index 75% rename from libavfilter/vulkan/bwdif.comp rename to libavfilter/vulkan/bwdif.comp.glsl index 5152464823..043ded0d24 100644 --- a/libavfilter/vulkan/bwdif.comp +++ b/libavfilter/vulkan/bwdif.comp.glsl @@ -18,6 +18,26 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#version 460 +#pragma shader_stage(compute) + +#extension GL_EXT_shader_image_load_formatted : require +#extension GL_EXT_nonuniform_qualifier : require +#extension GL_EXT_scalar_block_layout : require + +layout (local_size_x_id = 253, local_size_y_id = 254, local_size_z_id = 255) in; + +layout (set = 0, binding = 0) uniform readonly image2D prev[]; +layout (set = 0, binding = 1) uniform readonly image2D cur[]; +layout (set = 0, binding = 2) uniform readonly image2D next[]; +layout (set = 0, binding = 3) uniform writeonly image2D dst[]; + +layout (push_constant, scalar) uniform pushConstants { + int parity; + int tff; + int current_field; +}; + const vec4 coef_lf[2] = { vec4(4309), vec4(213), }; const vec4 coef_hf[3] = { vec4(5570), vec4(3801), vec4(1016) }; const vec4 coef_sp[2] = { vec4(5077), vec4(981), }; @@ -27,8 +47,10 @@ vec4 process_intra(vec4 cur[4]) return (coef_sp[0]*(cur[1] + cur[2]) - coef_sp[1]*(cur[0] + cur[3])) / (1 << 13); } -void process_plane_intra(int idx, ivec2 pos) +void process_plane_intra(ivec2 pos) { + nonuniformEXT uint idx = gl_LocalInvocationID.z; + vec4 dcur[4]; dcur[0] = imageLoad(cur[idx], pos - ivec2(0, 3)); dcur[1] = imageLoad(cur[idx], pos - ivec2(0, 1)); @@ -72,9 +94,11 @@ vec4 process_line(vec4 prev2[5], vec4 prev1[2], vec4 cur[4], vec4 next1[2], vec4 return mix(interpol, fd, diff_mask); } -void process_plane(int idx, const ivec2 pos, bool filter_field, - bool is_intra, bool field_parity) +void process_plane(const ivec2 pos) { + nonuniformEXT uint idx = gl_LocalInvocationID.z; + bool field_parity = (parity ^ tff) != 0; + vec4 dcur[4]; vec4 prev1[2]; vec4 next1[2]; @@ -120,3 +144,22 @@ void process_plane(int idx, const ivec2 pos, bool filter_field, imageStore(dst[idx], pos, process_line(prev2, prev1, dcur, next1, next2)); } + +void main() +{ + const ivec2 pos = ivec2(gl_GlobalInvocationID.xy); + bool filter_field = ((pos.y ^ parity) & 1) == 1; + bool is_intra = filter_field && (current_field == 0); + +#define IS_WITHIN(v1, v2) ((v1.x < v2.x) && (v1.y < v2.y)) + if (!IS_WITHIN(pos, imageSize(dst[nonuniformEXT(gl_LocalInvocationID.z)]))) { + return; + } else if (is_intra) { + process_plane_intra(pos); + } else if (filter_field) { + process_plane(pos); + } else { + imageStore(dst[nonuniformEXT(gl_LocalInvocationID.z)], pos, + imageLoad(cur[nonuniformEXT(gl_LocalInvocationID.z)], pos)); + } +} _______________________________________________ ffmpeg-cvslog mailing list -- [email protected] To unsubscribe send an email to [email protected]
