[FFmpeg-devel] [PATCH v2 10/13] scale_vulkan: refactor shader initialization
Lynne
dev at lynne.ee
Sat Jul 12 21:51:19 EEST 2025
---
libavfilter/vf_scale_vulkan.c | 160 ++++++++++++++++++----------------
1 file changed, 85 insertions(+), 75 deletions(-)
diff --git a/libavfilter/vf_scale_vulkan.c b/libavfilter/vf_scale_vulkan.c
index 1d6492e213..46b1476933 100644
--- a/libavfilter/vf_scale_vulkan.c
+++ b/libavfilter/vf_scale_vulkan.c
@@ -112,6 +112,78 @@ static const char write_444[] = {
C(0, } )
};
+static int init_scale_shader(ScaleVulkanContext *s, FFVulkanShader *shd,
+ FFVulkanDescriptorSetBinding *desc, AVFrame *in)
+{
+ GLSLD( scale_bilinear );
+
+ if (s->vkctx.output_format != s->vkctx.input_format) {
+ GLSLD( rgb2yuv );
+ }
+
+ switch (s->vkctx.output_format) {
+ case AV_PIX_FMT_NV12: GLSLD(write_nv12); break;
+ case AV_PIX_FMT_YUV420P: GLSLD( write_420); break;
+ case AV_PIX_FMT_YUV444P: GLSLD( write_444); break;
+ default: break;
+ }
+
+ GLSLC(0, void main() );
+ GLSLC(0, { );
+ GLSLC(1, ivec2 size; );
+ GLSLC(1, ivec2 pos = ivec2(gl_GlobalInvocationID.xy); );
+ GLSLF(1, vec2 in_d = vec2(%i, %i); ,in->width, in->height);
+ GLSLC(1, vec2 c_r = vec2(crop_w, crop_h) / in_d; );
+ GLSLC(1, vec2 c_o = vec2(crop_x, crop_y) / in_d; );
+ GLSLC(0, );
+
+ if (s->vkctx.output_format == s->vkctx.input_format) {
+ for (int i = 0; i < desc[1].elems; i++) {
+ GLSLF(1, size = imageSize(output_img[%i]); ,i);
+ GLSLC(1, if (IS_WITHIN(pos, size)) { );
+ switch (s->scaler) {
+ case F_NEAREST:
+ case F_BILINEAR:
+ GLSLF(2, vec4 res = scale_bilinear(%i, pos, c_r, c_o); ,i);
+ GLSLF(2, imageStore(output_img[%i], pos, res); ,i);
+ break;
+ };
+ GLSLC(1, } );
+ }
+ } else {
+ GLSLC(1, vec4 res = scale_bilinear(0, pos, c_r, c_o); );
+ GLSLF(1, res = rgb2yuv(res, %i); ,s->out_range == AVCOL_RANGE_JPEG);
+ switch (s->vkctx.output_format) {
+ case AV_PIX_FMT_NV12: GLSLC(1, write_nv12(res, pos); ); break;
+ case AV_PIX_FMT_YUV420P: GLSLC(1, write_420(res, pos); ); break;
+ case AV_PIX_FMT_YUV444P: GLSLC(1, write_444(res, pos); ); break;
+ default: return AVERROR(EINVAL);
+ }
+ }
+
+ GLSLC(0, } );
+
+ if (s->vkctx.output_format != s->vkctx.input_format) {
+ const AVLumaCoefficients *lcoeffs;
+ double tmp_mat[3][3];
+
+ lcoeffs = av_csp_luma_coeffs_from_avcsp(in->colorspace);
+ if (!lcoeffs) {
+ av_log(s, AV_LOG_ERROR, "Unsupported colorspace\n");
+ return AVERROR(EINVAL);
+ }
+
+ ff_fill_rgb2yuv_table(lcoeffs, tmp_mat);
+
+ for (int y = 0; y < 3; y++)
+ for (int x = 0; x < 3; x++)
+ s->opts.yuv_matrix[x][y] = tmp_mat[x][y];
+ s->opts.yuv_matrix[3][3] = 1.0;
+ }
+
+ return 0;
+}
+
static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in)
{
int err;
@@ -157,18 +229,6 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in)
32, 32, 1,
0));
- GLSLC(0, layout(push_constant, std430) uniform pushConstants { );
- GLSLC(1, mat4 yuv_matrix; );
- GLSLC(1, int crop_x; );
- GLSLC(1, int crop_y; );
- GLSLC(1, int crop_w; );
- GLSLC(1, int crop_h; );
- GLSLC(0, }; );
- GLSLC(0, );
-
- ff_vk_shader_add_push_const(&s->shd, 0, sizeof(s->opts),
- VK_SHADER_STAGE_COMPUTE_BIT);
-
desc = (FFVulkanDescriptorSetBinding []) {
{
.name = "input_img",
@@ -191,71 +251,21 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in)
RET(ff_vk_shader_add_descriptor_set(vkctx, &s->shd, desc, 2, 0, 0));
- GLSLD( scale_bilinear );
-
- if (s->vkctx.output_format != s->vkctx.input_format) {
- GLSLD( rgb2yuv );
- }
-
- switch (s->vkctx.output_format) {
- case AV_PIX_FMT_NV12: GLSLD(write_nv12); break;
- case AV_PIX_FMT_YUV420P: GLSLD( write_420); break;
- case AV_PIX_FMT_YUV444P: GLSLD( write_444); break;
- default: break;
- }
-
- GLSLC(0, void main() );
- GLSLC(0, { );
- GLSLC(1, ivec2 size; );
- GLSLC(1, ivec2 pos = ivec2(gl_GlobalInvocationID.xy); );
- GLSLF(1, vec2 in_d = vec2(%i, %i); ,in->width, in->height);
- GLSLC(1, vec2 c_r = vec2(crop_w, crop_h) / in_d; );
- GLSLC(1, vec2 c_o = vec2(crop_x, crop_y) / in_d; );
- GLSLC(0, );
-
- if (s->vkctx.output_format == s->vkctx.input_format) {
- for (int i = 0; i < desc[1].elems; i++) {
- GLSLF(1, size = imageSize(output_img[%i]); ,i);
- GLSLC(1, if (IS_WITHIN(pos, size)) { );
- switch (s->scaler) {
- case F_NEAREST:
- case F_BILINEAR:
- GLSLF(2, vec4 res = scale_bilinear(%i, pos, c_r, c_o); ,i);
- GLSLF(2, imageStore(output_img[%i], pos, res); ,i);
- break;
- };
- GLSLC(1, } );
- }
- } else {
- GLSLC(1, vec4 res = scale_bilinear(0, pos, c_r, c_o); );
- GLSLF(1, res = rgb2yuv(res, %i); ,s->out_range == AVCOL_RANGE_JPEG);
- switch (s->vkctx.output_format) {
- case AV_PIX_FMT_NV12: GLSLC(1, write_nv12(res, pos); ); break;
- case AV_PIX_FMT_YUV420P: GLSLC(1, write_420(res, pos); ); break;
- case AV_PIX_FMT_YUV444P: GLSLC(1, write_444(res, pos); ); break;
- default: return AVERROR(EINVAL);
- }
- }
-
- GLSLC(0, } );
-
- if (s->vkctx.output_format != s->vkctx.input_format) {
- const AVLumaCoefficients *lcoeffs;
- double tmp_mat[3][3];
-
- lcoeffs = av_csp_luma_coeffs_from_avcsp(in->colorspace);
- if (!lcoeffs) {
- av_log(ctx, AV_LOG_ERROR, "Unsupported colorspace\n");
- return AVERROR(EINVAL);
- }
+ GLSLC(0, layout(push_constant, std430) uniform pushConstants { );
+ GLSLC(1, mat4 yuv_matrix; );
+ GLSLC(1, int crop_x; );
+ GLSLC(1, int crop_y; );
+ GLSLC(1, int crop_w; );
+ GLSLC(1, int crop_h; );
+ GLSLC(0, }; );
+ GLSLC(0, );
- ff_fill_rgb2yuv_table(lcoeffs, tmp_mat);
+ ff_vk_shader_add_push_const(&s->shd, 0, sizeof(s->opts),
+ VK_SHADER_STAGE_COMPUTE_BIT);
- for (int y = 0; y < 3; y++)
- for (int x = 0; x < 3; x++)
- s->opts.yuv_matrix[x][y] = tmp_mat[x][y];
- s->opts.yuv_matrix[3][3] = 1.0;
- }
+ err = init_scale_shader(s, shd, desc, in);
+ if (err < 0)
+ goto fail;
RET(spv->compile_shader(vkctx, spv, shd, &spv_data, &spv_len, "main",
&spv_opaque));
--
2.50.0
More information about the ffmpeg-devel
mailing list