--- 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 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".