From 4ef45d8d4e318f011ecc3cfc661e45352e59cc67 Mon Sep 17 00:00:00 2001 From: "Leder, Brendan Steve" Date: Wed, 6 Nov 2024 11:57:20 -0500 Subject: [PATCH] amd/vpelib: Move bg color Refactor bg gen as it check_bg_support simply calls into other version specific function. Move that function directly into check_bg_support call, and refactor unnecessary functions + format fix. Co-authored-by: Brendan Reviewed-by: Krunoslav Kovac Reviewed-by: Jesse Agate Reviewed-by: Navid Assadian Acked-by: Chenyu Chen Part-of: --- .../vpelib/src/chip/vpe10/vpe10_resource.c | 73 ++++++++++++++-- src/amd/vpelib/src/core/color_bg.c | 85 ++----------------- src/amd/vpelib/src/core/inc/color_bg.h | 8 +- src/amd/vpelib/src/core/inc/resource.h | 2 + src/amd/vpelib/src/core/inc/vpe_priv.h | 3 +- src/amd/vpelib/src/core/resource.c | 7 ++ src/amd/vpelib/src/core/vpe_visual_confirm.c | 3 +- src/amd/vpelib/src/core/vpelib.c | 15 ++-- 8 files changed, 101 insertions(+), 95 deletions(-) diff --git a/src/amd/vpelib/src/chip/vpe10/vpe10_resource.c b/src/amd/vpelib/src/chip/vpe10/vpe10_resource.c index 41211f5179e..38514451763 100644 --- a/src/amd/vpelib/src/chip/vpe10/vpe10_resource.c +++ b/src/amd/vpelib/src/chip/vpe10/vpe10_resource.c @@ -496,11 +496,6 @@ bool vpe10_check_h_mirror_support(bool *input_mirror, bool *output_mirror) return true; } -enum vpe_status vpe10_check_bg_color_support(struct vpe_priv* vpe_priv, struct vpe_color* bg_color) -{ - return vpe_is_valid_bg_color(vpe_priv, bg_color); -} - void vpe10_calculate_dst_viewport_and_active( struct segment_ctx *segment_ctx, uint32_t max_seg_width) { @@ -917,14 +912,14 @@ int32_t vpe10_program_backend( if (vpe_is_fp16(surface_info->format)) { if (vpe_priv->output_ctx.alpha_mode == VPE_ALPHA_BGCOLOR) vpe_convert_from_float_to_fp16( - (double)vpe_priv->output_ctx.bg_color.rgba.a, &alpha_16); + (double)vpe_priv->output_ctx.mpc_bg_color.rgba.a, &alpha_16); else vpe_convert_from_float_to_fp16(1.0, &alpha_16); opp_dig_bypass = true; } else { if (vpe_priv->output_ctx.alpha_mode == VPE_ALPHA_BGCOLOR) - alpha_16 = (uint16_t)(vpe_priv->output_ctx.bg_color.rgba.a * 0xffff); + alpha_16 = (uint16_t)(vpe_priv->output_ctx.mpc_bg_color.rgba.a * 0xffff); else alpha_16 = 0xffff; } @@ -1042,7 +1037,7 @@ void vpe10_create_stream_ops_config(struct vpe_priv *vpe_priv, uint32_t pipe_idx vpe_priv->output_ctx.output_tf, vpe_priv->output_ctx.surface.format, false); // 3DLUT should only affect input visual confirm } else { - blndcfg.bg_color = vpe_priv->output_ctx.bg_color; + blndcfg.bg_color = vpe_priv->output_ctx.mpc_bg_color; } blndcfg.global_gain = 0xff; blndcfg.pre_multiplied_alpha = false; @@ -1265,3 +1260,65 @@ enum vpe_status vpe10_update_blnd_gamma(struct vpe_priv *vpe_priv, } return status; } + +static enum vpe_status bg_color_outside_cs_gamut( + const struct vpe_priv *vpe_priv, struct vpe_color *bg_color) +{ + enum color_space cs; + enum color_transfer_func tf; + struct vpe_color bg_color_copy = *bg_color; + const struct vpe_color_space *vcs = &vpe_priv->output_ctx.surface.cs; + + vpe_color_get_color_space_and_tf(vcs, &cs, &tf); + + if ((bg_color->is_ycbcr)) { + // using the bg_color_copy instead as bg_csc will modify it + // we should not do modification in checking stage + // otherwise validate_cached_param() will fail + if (vpe_bg_csc(&bg_color_copy, cs)) { + return VPE_STATUS_BG_COLOR_OUT_OF_RANGE; + } + } + return VPE_STATUS_OK; +} + +/* + In order to support background color fill correctly, we need to do studio -> full range + conversion before the blend block. However, there is also a requirement for HDR output to be + blended in linear space. Hence, if we have PQ out and studio range, we need to make sure no + blending will occur. Otherwise the job is invalid. + +*/ +static enum vpe_status is_valid_blend(const struct vpe_priv *vpe_priv, struct vpe_color *bg_color) +{ + + enum vpe_status status = VPE_STATUS_OK; + const struct vpe_color_space *vcs = &vpe_priv->output_ctx.surface.cs; + struct stream_ctx *stream_ctx = vpe_priv->stream_ctx; // Only need to check the first stream. + + if ((vcs->range == VPE_COLOR_RANGE_STUDIO) && (vcs->tf == VPE_TF_PQ) && + ((stream_ctx->stream.surface_info.cs.encoding == VPE_PIXEL_ENCODING_RGB) || + vpe_is_global_bg_blend_applied(stream_ctx))) + status = VPE_STATUS_BG_COLOR_OUT_OF_RANGE; + + return status; +} + +enum vpe_status vpe10_check_bg_color_support(struct vpe_priv *vpe_priv, struct vpe_color *bg_color) +{ + + enum vpe_status status = VPE_STATUS_OK; + + /* no need for background filling as for target rect equal to dest rect */ + if (vpe_rec_is_equal(vpe_priv->output_ctx.target_rect, + vpe_priv->stream_ctx[0].stream.scaling_info.dst_rect)) { + return VPE_STATUS_OK; + } + + status = is_valid_blend(vpe_priv, bg_color); + + if (status == VPE_STATUS_OK) + status = bg_color_outside_cs_gamut(vpe_priv, bg_color); + + return status; +} diff --git a/src/amd/vpelib/src/core/color_bg.c b/src/amd/vpelib/src/core/color_bg.c index bc97a1a44d3..fd72a41f2ed 100644 --- a/src/amd/vpelib/src/core/color_bg.c +++ b/src/amd/vpelib/src/core/color_bg.c @@ -208,7 +208,7 @@ static void set_gamut_remap_matrix(double* res, enum color_space src_cs, enum co } -static bool bg_csc(struct vpe_color *bg_color, enum color_space cs) +bool vpe_bg_csc(struct vpe_color *bg_color, enum color_space cs) { struct csc_table *entry = &bgcolor_to_rgbfull_table[cs]; float csc_final[3] = {0}; @@ -250,35 +250,14 @@ static bool bg_csc(struct vpe_color *bg_color, enum color_space cs) return output_is_clipped; } -static inline bool is_global_bg_blend_applied(struct stream_ctx *stream_ctx) { +bool vpe_is_global_bg_blend_applied(struct stream_ctx *stream_ctx) +{ return (stream_ctx->stream.blend_info.blending) && (stream_ctx->stream.blend_info.global_alpha) && (stream_ctx->stream.blend_info.global_alpha_value != 1.0); } -/* - In order to support background color fill correctly, we need to do studio -> full range conversion - before the blend block. However, there is also a requirement for HDR output to be blended in linear space. - Hence, if we have PQ out and studio range, we need to make sure no blenidng will occur. Othewise the job - is invalid. - -*/ -static enum vpe_status is_valid_blend(const struct vpe_priv *vpe_priv, struct vpe_color *bg_color) { - - enum vpe_status status = VPE_STATUS_OK; - const struct vpe_color_space *vcs = &vpe_priv->output_ctx.surface.cs; - struct stream_ctx *stream_ctx = vpe_priv->stream_ctx; //Only need to check the first stream. - - if ((vcs->range == VPE_COLOR_RANGE_STUDIO) && - (vcs->tf == VPE_TF_PQ) && - ((stream_ctx->stream.surface_info.cs.encoding == VPE_PIXEL_ENCODING_RGB) || - is_global_bg_blend_applied(stream_ctx))) - status = VPE_STATUS_BG_COLOR_OUT_OF_RANGE; - - return status; -} - struct gamma_coefs { float a0; float a1; @@ -502,65 +481,17 @@ static void vpe_bg_inverse_gamut_remap(enum color_space output_cs, // To understand the logic for background color conversion, // please refer to vpe_update_output_gamma_sequence in color.c -void vpe_bg_color_convert( - enum color_space output_cs, struct transfer_func *output_tf, enum vpe_surface_pixel_format pixel_format, struct vpe_color *bg_color, bool enable_3dlut) +void vpe_bg_color_convert(enum color_space output_cs, struct transfer_func *output_tf, + enum vpe_surface_pixel_format pixel_format, struct vpe_color *mpc_bg_color, + struct vpe_color *opp_bg_color, bool enable_3dlut) { if (output_tf->type != TF_TYPE_BYPASS) { // inverse degam if (output_tf->tf == TRANSFER_FUNC_PQ2084 && !is_limited_cs(output_cs)) - vpe_bg_degam(output_tf, bg_color); + vpe_bg_degam(output_tf, mpc_bg_color); // inverse gamut remap if (enable_3dlut) - vpe_bg_inverse_gamut_remap(output_cs, output_tf, bg_color); + vpe_bg_inverse_gamut_remap(output_cs, output_tf, mpc_bg_color); } // for TF_TYPE_BYPASS, bg color should be programmed to mpc as linear } - -enum vpe_status vpe_bg_color_outside_cs_gamut( - const struct vpe_priv *vpe_priv, struct vpe_color *bg_color) -{ - enum color_space cs; - enum color_transfer_func tf; - struct vpe_color bg_color_copy = *bg_color; - const struct vpe_color_space *vcs = &vpe_priv->output_ctx.surface.cs; - - vpe_color_get_color_space_and_tf(vcs, &cs, &tf); - - if ((bg_color->is_ycbcr)) { - // using the bg_color_copy instead as bg_csc will modify it - // we should not do modification in checking stage - // otherwise validate_cached_param() will fail - if (bg_csc(&bg_color_copy, cs)) { - return VPE_STATUS_BG_COLOR_OUT_OF_RANGE; - } - } - return VPE_STATUS_OK; -} - -static inline bool is_target_rect_equal_to_dest_rect(const struct vpe_priv *vpe_priv) -{ - const struct vpe_rect *target_rect = &vpe_priv->output_ctx.target_rect; - const struct vpe_rect *dst_rect = &vpe_priv->stream_ctx[0].stream.scaling_info.dst_rect; - - return (target_rect->height == dst_rect ->height) && (target_rect->width == dst_rect ->width) && - (target_rect->x == dst_rect ->x) && (target_rect->y == dst_rect ->y); -} - -// These two checks are only necessary for VPE1.0 and contain a lot of quirks to work around VPE 1.0 -// limitations. -enum vpe_status vpe_is_valid_bg_color(const struct vpe_priv *vpe_priv, struct vpe_color *bg_color) { - - enum vpe_status status = VPE_STATUS_OK; - - /* no need for background filling as for target rect equal to dest rect */ - if (is_target_rect_equal_to_dest_rect(vpe_priv)) { - return VPE_STATUS_OK; - } - - status = is_valid_blend(vpe_priv, bg_color); - - if (status == VPE_STATUS_OK) - status = vpe_bg_color_outside_cs_gamut(vpe_priv, bg_color); - - return status; -} diff --git a/src/amd/vpelib/src/core/inc/color_bg.h b/src/amd/vpelib/src/core/inc/color_bg.h index 7a045f471a1..ee29bcb48a1 100644 --- a/src/amd/vpelib/src/core/inc/color_bg.h +++ b/src/amd/vpelib/src/core/inc/color_bg.h @@ -26,11 +26,13 @@ #include "color.h" -void vpe_bg_color_convert( - enum color_space cs, struct transfer_func *output_tf, enum vpe_surface_pixel_format pixel_format, struct vpe_color *bg_color, bool enable_3dlut); +void vpe_bg_color_convert(enum color_space cs, struct transfer_func *output_tf, + enum vpe_surface_pixel_format pixel_format, struct vpe_color *mpc_bg_color, + struct vpe_color *opp_bg_color, bool enable_3dlut); enum vpe_status vpe_bg_color_outside_cs_gamut( const struct vpe_priv *vpe_priv, struct vpe_color *bg_color); -enum vpe_status vpe_is_valid_bg_color(const struct vpe_priv *vpe_priv, struct vpe_color *bg_color); +bool vpe_bg_csc(struct vpe_color *bg_color, enum color_space cs); +bool vpe_is_global_bg_blend_applied(struct stream_ctx *stream_ctx); diff --git a/src/amd/vpelib/src/core/inc/resource.h b/src/amd/vpelib/src/core/inc/resource.h index ec9d7e8cf56..8f76383c85a 100644 --- a/src/amd/vpelib/src/core/inc/resource.h +++ b/src/amd/vpelib/src/core/inc/resource.h @@ -168,6 +168,8 @@ void vpe_frontend_config_callback( void vpe_backend_config_callback( void *ctx, uint64_t cfg_base_gpu, uint64_t cfg_base_cpu, uint64_t size, uint32_t pipe_idx); +bool vpe_rec_is_equal(struct vpe_rect rec1, struct vpe_rect rec2); + #ifdef __cplusplus } #endif diff --git a/src/amd/vpelib/src/core/inc/vpe_priv.h b/src/amd/vpelib/src/core/inc/vpe_priv.h index 57f8c4a0edc..613ebfef356 100644 --- a/src/amd/vpelib/src/core/inc/vpe_priv.h +++ b/src/amd/vpelib/src/core/inc/vpe_priv.h @@ -166,7 +166,8 @@ struct stream_ctx { struct output_ctx { // stores the paramters built for generating vpep configs struct vpe_surface_info surface; - struct vpe_color bg_color; + struct vpe_color mpc_bg_color; + struct vpe_color opp_bg_color; struct vpe_rect target_rect; enum vpe_alpha_mode alpha_mode; struct vpe_clamping_params clamping_params; diff --git a/src/amd/vpelib/src/core/resource.c b/src/amd/vpelib/src/core/resource.c index 2602a97bbdd..e9bb10a454a 100644 --- a/src/amd/vpelib/src/core/resource.c +++ b/src/amd/vpelib/src/core/resource.c @@ -789,3 +789,10 @@ void vpe_backend_config_callback( vpe_priv->vpe_desc_writer.add_config_desc( &vpe_priv->vpe_desc_writer, cfg_base_gpu, false, (uint8_t)vpe_priv->config_writer.buf->tmz); } + +bool vpe_rec_is_equal(struct vpe_rect rec1, struct vpe_rect rec2) +{ + return (rec1.x == rec2.x && rec1.y == rec2.y && rec1.width == rec2.width && + rec1.height == rec2.height); +} + diff --git a/src/amd/vpelib/src/core/vpe_visual_confirm.c b/src/amd/vpelib/src/core/vpe_visual_confirm.c index 1bb293d8964..27f465412db 100644 --- a/src/amd/vpelib/src/core/vpe_visual_confirm.c +++ b/src/amd/vpelib/src/core/vpe_visual_confirm.c @@ -158,7 +158,8 @@ struct vpe_color vpe_get_visual_confirm_color(enum vpe_surface_pixel_format form } // Due to there will be regamma (ogam), need convert the bg color for visual confirm - vpe_bg_color_convert(output_cs, output_tf, output_format, &visual_confirm_color, enable_3dlut); + vpe_bg_color_convert( + output_cs, output_tf, output_format, &visual_confirm_color, NULL, enable_3dlut); // Experimental: To make FP16 Linear color looks more visually ok if (vpe_is_fp16(output_format)) { diff --git a/src/amd/vpelib/src/core/vpelib.c b/src/amd/vpelib/src/core/vpelib.c index 67a37b775df..0c370929c3a 100644 --- a/src/amd/vpelib/src/core/vpelib.c +++ b/src/amd/vpelib/src/core/vpelib.c @@ -542,7 +542,8 @@ enum vpe_status vpe_check_support( // output resource preparation for further checking (cache the result) output_ctx = &vpe_priv->output_ctx; output_ctx->surface = param->dst_surface; - output_ctx->bg_color = param->bg_color; + output_ctx->mpc_bg_color = param->bg_color; + output_ctx->opp_bg_color = param->bg_color; output_ctx->target_rect = param->target_rect; output_ctx->alpha_mode = param->alpha_mode; output_ctx->flags.hdr_metadata = param->flags.hdr_metadata; @@ -576,7 +577,7 @@ enum vpe_status vpe_check_support( // if the bg_color support is false, there is a flag to verify if the bg_color falls in the // output gamut if (!vpe_priv->pub.caps->bg_color_check_support) { - status = vpe_priv->resource.check_bg_color_support(vpe_priv, &output_ctx->bg_color); + status = vpe_priv->resource.check_bg_color_support(vpe_priv, &output_ctx->mpc_bg_color); if (status != VPE_STATUS_OK) { vpe_log( "failed in checking the background color versus the output color space %d\n", @@ -649,7 +650,10 @@ static bool validate_cached_param(struct vpe_priv *vpe_priv, const struct vpe_bu if (output_ctx->alpha_mode != param->alpha_mode) return false; - if (memcmp(&output_ctx->bg_color, ¶m->bg_color, sizeof(struct vpe_color))) + if (memcmp(&output_ctx->mpc_bg_color, ¶m->bg_color, sizeof(struct vpe_color))) + return false; + + if (memcmp(&output_ctx->opp_bg_color, ¶m->bg_color, sizeof(struct vpe_color))) return false; if (memcmp(&output_ctx->target_rect, ¶m->target_rect, sizeof(struct vpe_rect))) @@ -776,8 +780,9 @@ enum vpe_status vpe_build_commands( * the 3dlut enablement for the background color conversion * is used based on the information of the first stream. */ - vpe_bg_color_convert(vpe_priv->output_ctx.cs, vpe_priv->output_ctx.output_tf, vpe_priv->output_ctx.surface.format, - &vpe_priv->output_ctx.bg_color, vpe_priv->stream_ctx[0].enable_3dlut); + vpe_bg_color_convert(vpe_priv->output_ctx.cs, vpe_priv->output_ctx.output_tf, + vpe_priv->output_ctx.surface.format, &vpe_priv->output_ctx.mpc_bg_color, + &vpe_priv->output_ctx.opp_bg_color, vpe_priv->stream_ctx[0].enable_3dlut); if (vpe_priv->collaboration_mode == true) { status = builder->build_collaborate_sync_cmd(vpe_priv, &curr_bufs);