This is an automated email from the git hooks/post-receive script. Git pushed a commit to branch master in repository ffmpeg.
commit 80229c161b6c04eb24c0f0319e1be4dfa939fd5d Author: Lynne <[email protected]> AuthorDate: Fri Jan 9 12:51:34 2026 +0100 Commit: Lynne <[email protected]> CommitDate: Mon Jan 12 17:28:43 2026 +0100 scale_vulkan: use compile-time SPIR-V generation for debayering --- libavfilter/vf_scale_vulkan.c | 107 +++++++++++++-------- libavfilter/vulkan/Makefile | 8 +- .../vulkan/{debayer.comp => debayer.comp.glsl} | 56 ++++++++--- 3 files changed, 107 insertions(+), 64 deletions(-) diff --git a/libavfilter/vf_scale_vulkan.c b/libavfilter/vf_scale_vulkan.c index f8e069f4a4..4db4be190f 100644 --- a/libavfilter/vf_scale_vulkan.c +++ b/libavfilter/vf_scale_vulkan.c @@ -27,7 +27,8 @@ #include "colorspace.h" #include "video.h" -extern const char *ff_source_debayer_comp; +extern const unsigned char ff_debayer_comp_spv_data[]; +extern const unsigned int ff_debayer_comp_spv_len; enum ScalerFunc { F_BILINEAR = 0, @@ -195,25 +196,6 @@ static int init_scale_shader(AVFilterContext *ctx, FFVulkanShader *shd, return 0; } -static int init_debayer_shader(ScaleVulkanContext *s, FFVulkanShader *shd, - FFVulkanDescriptorSetBinding *desc, AVFrame *in) -{ - GLSLD(ff_source_debayer_comp); - - GLSLC(0, void main(void)); - GLSLC(0, { ); - if (s->debayer == DB_BILINEAR) - GLSLC(1, debayer_bilinear();); - else if (s->debayer == DB_BILINEAR_HQ) - GLSLC(1, debayer_bilinear_hq();); - GLSLC(0, } ); - - shd->lg_size[0] <<= 1; - shd->lg_size[1] <<= 1; - - return 0; -} - static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in) { int err; @@ -227,7 +209,6 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in) FFVkSPIRVCompiler *spv; FFVulkanDescriptorSetBinding *desc; - int debayer = s->vkctx.input_format == AV_PIX_FMT_BAYER_RGGB16; int in_planes = av_pix_fmt_count_planes(s->vkctx.input_format); switch (s->scaler) { @@ -245,17 +226,9 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in) 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"); - err = AVERROR(ENOTSUP); - goto fail; - } - RET(ff_vk_exec_pool_init(vkctx, s->qf, &s->e, s->qf->num*4, 0, 0, 0, NULL)); - if (!debayer) - RET(ff_vk_init_sampler(vkctx, &s->sampler, 0, sampler_mode)); + RET(ff_vk_init_sampler(vkctx, &s->sampler, 0, sampler_mode)); RET(ff_vk_shader_init(vkctx, &s->shd, "scale", VK_SHADER_STAGE_COMPUTE_BIT, @@ -266,12 +239,8 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in) desc = (FFVulkanDescriptorSetBinding []) { { .name = "input_img", - .type = debayer ? - VK_DESCRIPTOR_TYPE_STORAGE_IMAGE : - VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - .mem_layout = debayer ? - ff_vk_shader_rep_fmt(s->vkctx.input_format, FF_VK_REP_FLOAT) : - NULL, + .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, + .mem_layout = NULL, .mem_quali = "readonly", .dimensions = 2, .elems = in_planes, @@ -303,10 +272,7 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in) ff_vk_shader_add_push_const(&s->shd, 0, sizeof(s->opts), VK_SHADER_STAGE_COMPUTE_BIT); - if (debayer) - err = init_debayer_shader(s, shd, desc, in); - else - err = init_scale_shader(ctx, shd, desc, in); + err = init_scale_shader(ctx, shd, desc, in); if (err < 0) goto fail; @@ -327,6 +293,52 @@ fail: return err; } +static av_cold int init_debayer(AVFilterContext *ctx, AVFrame *in) +{ + int err; + ScaleVulkanContext *s = ctx->priv; + FFVulkanContext *vkctx = &s->vkctx; + FFVulkanShader *shd = &s->shd; + + RET(ff_vk_exec_pool_init(vkctx, s->qf, &s->e, s->qf->num*2, 0, 0, 0, NULL)); + + SPEC_LIST_CREATE(sl, 1, 1*sizeof(int32_t)) + SPEC_LIST_ADD(sl, 0, 32, s->debayer); + ff_vk_shader_load(&s->shd, VK_SHADER_STAGE_COMPUTE_BIT, sl, + (uint32_t []) { 32, 32, 1 }, 0); + + ff_vk_shader_add_push_const(&s->shd, 0, sizeof(s->opts), + VK_SHADER_STAGE_COMPUTE_BIT); + + const FFVulkanDescriptorSetBinding desc[] = { + { + .name = "src", + .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, + .stages = VK_SHADER_STAGE_COMPUTE_BIT, + }, + { + .name = "dst", + .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, + .stages = VK_SHADER_STAGE_COMPUTE_BIT, + }, + }; + ff_vk_shader_add_descriptor_set(vkctx, &s->shd, desc, 2, 0, 0); + + RET(ff_vk_shader_link(vkctx, shd, + ff_debayer_comp_spv_data, + ff_debayer_comp_spv_len, "main")); + + RET(ff_vk_shader_register_exec(vkctx, &s->e, &s->shd)); + + shd->lg_size[0] <<= 1; + shd->lg_size[1] <<= 1; + + s->initialized = 1; + +fail: + return err; +} + static int scale_vulkan_filter_frame(AVFilterLink *link, AVFrame *in) { int err; @@ -340,8 +352,19 @@ static int scale_vulkan_filter_frame(AVFilterLink *link, AVFrame *in) goto fail; } - if (!s->initialized) - RET(init_filter(ctx, in)); + s->qf = ff_vk_qf_find(&s->vkctx, VK_QUEUE_COMPUTE_BIT, 0); + if (!s->qf) { + av_log(ctx, AV_LOG_ERROR, "Device has no compute queues\n"); + err = AVERROR(ENOTSUP); + goto fail; + } + + if (!s->initialized) { + if (s->vkctx.input_format == AV_PIX_FMT_BAYER_RGGB16) + RET(init_debayer(ctx, in)); + else + RET(init_filter(ctx, in)); + } s->opts.crop_x = in->crop_left; s->opts.crop_y = in->crop_top; diff --git a/libavfilter/vulkan/Makefile b/libavfilter/vulkan/Makefile index eaad9bbbaf..dc15353e9e 100644 --- a/libavfilter/vulkan/Makefile +++ b/libavfilter/vulkan/Makefile @@ -3,10 +3,4 @@ clean:: OBJS-$(CONFIG_AVGBLUR_VULKAN_FILTER) += vulkan/avgblur.comp.spv.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)) -.SECONDARY: $(VULKAN:.comp=.c) -libavfilter/vulkan/%.c: TAG = VULKAN -libavfilter/vulkan/%.c: $(SRC_PATH)/libavfilter/vulkan/%.comp - $(M)$(SRC_PATH)/tools/source2c $< $@ +OBJS-$(CONFIG_SCALE_VULKAN_FILTER) += vulkan/debayer.comp.spv.o diff --git a/libavfilter/vulkan/debayer.comp b/libavfilter/vulkan/debayer.comp.glsl similarity index 76% rename from libavfilter/vulkan/debayer.comp rename to libavfilter/vulkan/debayer.comp.glsl index c86c2f5eec..ccf4996c49 100644 --- a/libavfilter/vulkan/debayer.comp +++ b/libavfilter/vulkan/debayer.comp.glsl @@ -19,46 +19,62 @@ * 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 + +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 src; +layout (set = 0, binding = 1) uniform writeonly image2D dst; + +layout (constant_id = 0) const int debayer_mode = 0; + +layout(push_constant, std430) uniform pushConstants { + mat4 yuv_matrix; + int crop_x; + int crop_y; + int crop_w; + int crop_h; +}; + #define LD(xo, yo) \ - (imageLoad(input_img[0], pos + ivec2((xo), (yo))).r) + (imageLoad(src, pos + ivec2((xo), (yo))).r) -void debayer_bilinear(void) +void debayer_bilinear(ivec2 pos) { - ivec2 pos = ivec2(gl_GlobalInvocationID.xy) << 1; - /* R basis */ vec4 tl = vec4(LD(0, 0), (LD(1, 0) + LD(-1, 0) + LD(0, 1) + LD(0, -1)) / 4.0f, (LD(-1, -1) + LD(1, 1) + LD(-1, 1) + LD(1, -1)) / 4.0f, 1.0f); - imageStore(output_img[0], pos, tl); + imageStore(dst, pos, tl); /* G1 basis */ vec4 tr = vec4((LD(2, 0) + LD(0, 0)) / 2.0f, LD(1, 0), (LD(1, 1) + LD(1, -1)) / 2.0f, 1.0f); - imageStore(output_img[0], pos + ivec2(1, 0), tr); + imageStore(dst, pos + ivec2(1, 0), tr); /* G2 basis */ vec4 bl = vec4((LD(0, 2) + LD(0, 0)) / 2.0f, LD(0, 1), (LD(1, 1) + LD(-1, 1)) / 2.0f, 1.0f); - imageStore(output_img[0], pos + ivec2(0, 1), bl); + imageStore(dst, pos + ivec2(0, 1), bl); /* B basis */ vec4 br = vec4((LD(0, 0) + LD(2, 2) + LD(0, 2) + LD(2, 0)) / 4.0f, (LD(2, 1) + LD(0, 1) + LD(1, 2) + LD(1, 0)) / 4.0f, LD(1, 1), 1.0f); - imageStore(output_img[0], pos + ivec2(1, 1), br); + imageStore(dst, pos + ivec2(1, 1), br); } -void debayer_bilinear_hq(void) +void debayer_bilinear_hq(ivec2 pos) { - ivec2 pos = ivec2(gl_GlobalInvocationID.xy) << 1; - /* R basis */ vec4 tl = vec4(LD(0, 0), (4.0f*LD(0, 0) + 2.0f*(LD(0, -1) + LD(0, 1) + LD(-1, 0) + LD(1, 0)) - @@ -66,7 +82,7 @@ void debayer_bilinear_hq(void) (12.0f*LD(0, 0) + 4.0f*(LD(-1, -1) + LD(-1, 1) + LD(1, -1) + LD(1, 1)) - 3.0f*(LD(0, -2) + LD(0, 2) + LD(-2, 0) + LD(2, 0))) / 16.0f, 1.0f); - imageStore(output_img[0], pos, tl); + imageStore(dst, pos, tl); /* G1 basis */ vec4 tr = vec4((10.0f*LD(1, 0) + 8.0f*(LD(0, 0) + LD(2, 0)) - @@ -77,7 +93,7 @@ void debayer_bilinear_hq(void) 2.0f*(LD(0, -1) + LD(0, 1) + LD(2, -1) + LD(2, 1) + LD(1, -2) + LD(1, 2)) + LD(-1, 0) + LD(3, 0)) / 16.0f, 1.0f); - imageStore(output_img[0], pos + ivec2(1, 0), tr); + imageStore(dst, pos + ivec2(1, 0), tr); /* G2 basis */ @@ -89,7 +105,7 @@ void debayer_bilinear_hq(void) 2.0f*(LD(-1, 0) + LD(1, 2) + LD(-1, 2) + LD(1, 0) + LD(-2, 1) + LD(2, 1)) + LD(0, -1) + LD(0, 3)) / 16.0f, 1.0f); - imageStore(output_img[0], pos + ivec2(0, 1), bl); + imageStore(dst, pos + ivec2(0, 1), bl); /* B basis */ vec4 br = vec4((12.0f*LD(1, 1) + 4.0f*(LD(0, 0) + LD(0, 2) + LD(2, 0) + LD(2, 2)) - @@ -98,5 +114,15 @@ void debayer_bilinear_hq(void) (LD(1, -1) + LD(1, 3) + LD(-1, 1) + LD(3, 1))) / 8.0f, LD(1, 1), 1.0f); - imageStore(output_img[0], pos + ivec2(1, 1), br); + imageStore(dst, pos + ivec2(1, 1), br); +} + +void main(void) +{ + ivec2 pos = ivec2(gl_GlobalInvocationID.xy) << 1; + + if (debayer_mode == 0) + debayer_bilinear(pos); + else + debayer_bilinear_hq(pos); } _______________________________________________ ffmpeg-cvslog mailing list -- [email protected] To unsubscribe send an email to [email protected]
