On 2025-12-08 18:44, Melissa Wen wrote:
> Commit 27fc10d1095f ("drm/amd/display: Fix the delta clamping for shaper
> LUT") fixed banding when using plane shaper LUT in DCN10 CM helper.  The
> problem is also present in DCN30 CM helper, fix banding by extending the
> same bug delta clamping fix to CM3.
> 
> Signed-off-by: Melissa Wen <[email protected]>

Reviewed-by: Harry Wentland <[email protected]>

Harry

> ---
>  .../amd/display/dc/dcn30/dcn30_cm_common.c    | 30 +++++++++++++++----
>  .../display/dc/dwb/dcn30/dcn30_cm_common.h    |  2 +-
>  .../amd/display/dc/hwss/dcn30/dcn30_hwseq.c   |  9 +++---
>  .../amd/display/dc/hwss/dcn32/dcn32_hwseq.c   | 17 ++++++-----
>  .../amd/display/dc/hwss/dcn401/dcn401_hwseq.c | 16 +++++-----
>  5 files changed, 49 insertions(+), 25 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.c 
> b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.c
> index ba20575be214..b1c2c8da1937 100644
> --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.c
> +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.c
> @@ -105,9 +105,12 @@ void cm_helper_program_gamcor_xfer_func(
>  #define NUMBER_REGIONS     32
>  #define NUMBER_SW_SEGMENTS 16
>  
> -bool cm3_helper_translate_curve_to_hw_format(
> -                             const struct dc_transfer_func *output_tf,
> -                             struct pwl_params *lut_params, bool fixpoint)
> +#define DC_LOGGER \
> +             ctx->logger
> +
> +bool cm3_helper_translate_curve_to_hw_format(struct dc_context *ctx,
> +                                          const struct dc_transfer_func 
> *output_tf,
> +                                          struct pwl_params *lut_params, 
> bool fixpoint)
>  {
>       struct curve_points3 *corner_points;
>       struct pwl_result_data *rgb_resulted;
> @@ -248,6 +251,10 @@ bool cm3_helper_translate_curve_to_hw_format(
>       if (fixpoint == true) {
>               i = 1;
>               while (i != hw_points + 2) {
> +                     uint32_t red_clamp;
> +                     uint32_t green_clamp;
> +                     uint32_t blue_clamp;
> +
>                       if (i >= hw_points) {
>                               if (dc_fixpt_lt(rgb_plus_1->red, rgb->red))
>                                       rgb_plus_1->red = dc_fixpt_add(rgb->red,
> @@ -260,9 +267,20 @@ bool cm3_helper_translate_curve_to_hw_format(
>                                                       
> rgb_minus_1->delta_blue);
>                       }
>  
> -                     rgb->delta_red_reg   = 
> dc_fixpt_clamp_u0d10(rgb->delta_red);
> -                     rgb->delta_green_reg = 
> dc_fixpt_clamp_u0d10(rgb->delta_green);
> -                     rgb->delta_blue_reg  = 
> dc_fixpt_clamp_u0d10(rgb->delta_blue);
> +                     rgb->delta_red   = dc_fixpt_sub(rgb_plus_1->red,   
> rgb->red);
> +                     rgb->delta_green = dc_fixpt_sub(rgb_plus_1->green, 
> rgb->green);
> +                     rgb->delta_blue  = dc_fixpt_sub(rgb_plus_1->blue,  
> rgb->blue);
> +
> +                     red_clamp = dc_fixpt_clamp_u0d14(rgb->delta_red);
> +                     green_clamp = dc_fixpt_clamp_u0d14(rgb->delta_green);
> +                     blue_clamp = dc_fixpt_clamp_u0d14(rgb->delta_blue);
> +
> +                     if (red_clamp >> 10 || green_clamp >> 10 || blue_clamp 
> >> 10)
> +                             DC_LOG_ERROR("Losing delta precision while 
> programming shaper LUT.");
> +
> +                     rgb->delta_red_reg   = red_clamp & 0x3ff;
> +                     rgb->delta_green_reg = green_clamp & 0x3ff;
> +                     rgb->delta_blue_reg  = blue_clamp & 0x3ff;
>                       rgb->red_reg         = dc_fixpt_clamp_u0d14(rgb->red);
>                       rgb->green_reg       = dc_fixpt_clamp_u0d14(rgb->green);
>                       rgb->blue_reg        = dc_fixpt_clamp_u0d14(rgb->blue);
> diff --git a/drivers/gpu/drm/amd/display/dc/dwb/dcn30/dcn30_cm_common.h 
> b/drivers/gpu/drm/amd/display/dc/dwb/dcn30/dcn30_cm_common.h
> index b86347c9b038..95f9318a54ef 100644
> --- a/drivers/gpu/drm/amd/display/dc/dwb/dcn30/dcn30_cm_common.h
> +++ b/drivers/gpu/drm/amd/display/dc/dwb/dcn30/dcn30_cm_common.h
> @@ -59,7 +59,7 @@ void cm_helper_program_gamcor_xfer_func(
>       const struct pwl_params *params,
>       const struct dcn3_xfer_func_reg *reg);
>  
> -bool cm3_helper_translate_curve_to_hw_format(
> +bool cm3_helper_translate_curve_to_hw_format(struct dc_context *ctx,
>       const struct dc_transfer_func *output_tf,
>       struct pwl_params *lut_params, bool fixpoint);
>  
> diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c 
> b/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c
> index 81bcadf5e57e..f2d4cd527874 100644
> --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c
> +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c
> @@ -239,7 +239,7 @@ bool dcn30_set_blend_lut(
>       if (plane_state->blend_tf.type == TF_TYPE_HWPWL)
>               blend_lut = &plane_state->blend_tf.pwl;
>       else if (plane_state->blend_tf.type == TF_TYPE_DISTRIBUTED_POINTS) {
> -             result = cm3_helper_translate_curve_to_hw_format(
> +             result = 
> cm3_helper_translate_curve_to_hw_format(plane_state->ctx,
>                               &plane_state->blend_tf, 
> &dpp_base->regamma_params, false);
>               if (!result)
>                       return result;
> @@ -334,8 +334,9 @@ bool dcn30_set_input_transfer_func(struct dc *dc,
>       if (plane_state->in_transfer_func.type == TF_TYPE_HWPWL)
>               params = &plane_state->in_transfer_func.pwl;
>       else if (plane_state->in_transfer_func.type == 
> TF_TYPE_DISTRIBUTED_POINTS &&
> -             
> cm3_helper_translate_curve_to_hw_format(&plane_state->in_transfer_func,
> -                             &dpp_base->degamma_params, false))
> +             cm3_helper_translate_curve_to_hw_format(plane_state->ctx,
> +                                                     
> &plane_state->in_transfer_func,
> +                                                     
> &dpp_base->degamma_params, false))
>               params = &dpp_base->degamma_params;
>  
>       result = dpp_base->funcs->dpp_program_gamcor_lut(dpp_base, params);
> @@ -406,7 +407,7 @@ bool dcn30_set_output_transfer_func(struct dc *dc,
>                               params = &stream->out_transfer_func.pwl;
>                       else if (pipe_ctx->stream->out_transfer_func.type ==
>                                       TF_TYPE_DISTRIBUTED_POINTS &&
> -                                     cm3_helper_translate_curve_to_hw_format(
> +                                     
> cm3_helper_translate_curve_to_hw_format(stream->ctx,
>                                       &stream->out_transfer_func,
>                                       &mpc->blender_params, false))
>                               params = &mpc->blender_params;
> diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c 
> b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c
> index b213a2ac827a..27abc08918bc 100644
> --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c
> +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c
> @@ -486,8 +486,9 @@ bool dcn32_set_mcm_luts(
>       if (plane_state->blend_tf.type == TF_TYPE_HWPWL)
>               lut_params = &plane_state->blend_tf.pwl;
>       else if (plane_state->blend_tf.type == TF_TYPE_DISTRIBUTED_POINTS) {
> -             result = 
> cm3_helper_translate_curve_to_hw_format(&plane_state->blend_tf,
> -                             &dpp_base->regamma_params, false);
> +             result = 
> cm3_helper_translate_curve_to_hw_format(plane_state->ctx,
> +                                                              
> &plane_state->blend_tf,
> +                                                              
> &dpp_base->regamma_params, false);
>               if (!result)
>                       return result;
>  
> @@ -502,8 +503,9 @@ bool dcn32_set_mcm_luts(
>       else if (plane_state->in_shaper_func.type == 
> TF_TYPE_DISTRIBUTED_POINTS) {
>               // TODO: dpp_base replace
>               ASSERT(false);
> -             
> cm3_helper_translate_curve_to_hw_format(&plane_state->in_shaper_func,
> -                             &dpp_base->shaper_params, true);
> +             cm3_helper_translate_curve_to_hw_format(plane_state->ctx,
> +                                                     
> &plane_state->in_shaper_func,
> +                                                     
> &dpp_base->shaper_params, true);
>               lut_params = &dpp_base->shaper_params;
>       }
>  
> @@ -543,8 +545,9 @@ bool dcn32_set_input_transfer_func(struct dc *dc,
>       if (plane_state->in_transfer_func.type == TF_TYPE_HWPWL)
>               params = &plane_state->in_transfer_func.pwl;
>       else if (plane_state->in_transfer_func.type == 
> TF_TYPE_DISTRIBUTED_POINTS &&
> -             
> cm3_helper_translate_curve_to_hw_format(&plane_state->in_transfer_func,
> -                             &dpp_base->degamma_params, false))
> +             cm3_helper_translate_curve_to_hw_format(plane_state->ctx,
> +                                                     
> &plane_state->in_transfer_func,
> +                                                     
> &dpp_base->degamma_params, false))
>               params = &dpp_base->degamma_params;
>  
>       dpp_base->funcs->dpp_program_gamcor_lut(dpp_base, params);
> @@ -575,7 +578,7 @@ bool dcn32_set_output_transfer_func(struct dc *dc,
>                               params = &stream->out_transfer_func.pwl;
>                       else if (pipe_ctx->stream->out_transfer_func.type ==
>                                       TF_TYPE_DISTRIBUTED_POINTS &&
> -                                     cm3_helper_translate_curve_to_hw_format(
> +                                     
> cm3_helper_translate_curve_to_hw_format(stream->ctx,
>                                       &stream->out_transfer_func,
>                                       &mpc->blender_params, false))
>                               params = &mpc->blender_params;
> diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c 
> b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
> index 2fbc22afb89c..5eda7648d0d2 100644
> --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
> +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
> @@ -430,7 +430,7 @@ void dcn401_populate_mcm_luts(struct dc *dc,
>               if (mcm_luts.lut1d_func->type == TF_TYPE_HWPWL)
>                       m_lut_params.pwl = &mcm_luts.lut1d_func->pwl;
>               else if (mcm_luts.lut1d_func->type == 
> TF_TYPE_DISTRIBUTED_POINTS) {
> -                     rval = cm3_helper_translate_curve_to_hw_format(
> +                     rval = cm3_helper_translate_curve_to_hw_format(mpc->ctx,
>                                       mcm_luts.lut1d_func,
>                                       &dpp_base->regamma_params, false);
>                       m_lut_params.pwl = rval ? &dpp_base->regamma_params : 
> NULL;
> @@ -450,7 +450,7 @@ void dcn401_populate_mcm_luts(struct dc *dc,
>                       m_lut_params.pwl = &mcm_luts.shaper->pwl;
>               else if (mcm_luts.shaper->type == TF_TYPE_DISTRIBUTED_POINTS) {
>                       ASSERT(false);
> -                     rval = cm3_helper_translate_curve_to_hw_format(
> +                     rval = cm3_helper_translate_curve_to_hw_format(mpc->ctx,
>                                       mcm_luts.shaper,
>                                       &dpp_base->regamma_params, true);
>                       m_lut_params.pwl = rval ? &dpp_base->regamma_params : 
> NULL;
> @@ -627,8 +627,9 @@ bool dcn401_set_mcm_luts(struct pipe_ctx *pipe_ctx,
>       if (plane_state->blend_tf.type == TF_TYPE_HWPWL)
>               lut_params = &plane_state->blend_tf.pwl;
>       else if (plane_state->blend_tf.type == TF_TYPE_DISTRIBUTED_POINTS) {
> -             rval = 
> cm3_helper_translate_curve_to_hw_format(&plane_state->blend_tf,
> -                             &dpp_base->regamma_params, false);
> +             rval = cm3_helper_translate_curve_to_hw_format(plane_state->ctx,
> +                                                            
> &plane_state->blend_tf,
> +                                                            
> &dpp_base->regamma_params, false);
>               lut_params = rval ? &dpp_base->regamma_params : NULL;
>       }
>       result = mpc->funcs->program_1dlut(mpc, lut_params, mpcc_id);
> @@ -639,8 +640,9 @@ bool dcn401_set_mcm_luts(struct pipe_ctx *pipe_ctx,
>               lut_params = &plane_state->in_shaper_func.pwl;
>       else if (plane_state->in_shaper_func.type == 
> TF_TYPE_DISTRIBUTED_POINTS) {
>               // TODO: dpp_base replace
> -             rval = 
> cm3_helper_translate_curve_to_hw_format(&plane_state->in_shaper_func,
> -                             &dpp_base->shaper_params, true);
> +             rval = cm3_helper_translate_curve_to_hw_format(plane_state->ctx,
> +                                                            
> &plane_state->in_shaper_func,
> +                                                            
> &dpp_base->shaper_params, true);
>               lut_params = rval ? &dpp_base->shaper_params : NULL;
>       }
>       result &= mpc->funcs->program_shaper(mpc, lut_params, mpcc_id);
> @@ -674,7 +676,7 @@ bool dcn401_set_output_transfer_func(struct dc *dc,
>                               params = &stream->out_transfer_func.pwl;
>                       else if (pipe_ctx->stream->out_transfer_func.type ==
>                                       TF_TYPE_DISTRIBUTED_POINTS &&
> -                                     cm3_helper_translate_curve_to_hw_format(
> +                                     
> cm3_helper_translate_curve_to_hw_format(stream->ctx,
>                                       &stream->out_transfer_func,
>                                       &mpc->blender_params, false))
>                               params = &mpc->blender_params;

Reply via email to