From: Felipe <Felipe.Clark@xxxxxxx> [Why] The OGAM LUT precision was accumulating too much error in the higher end. [How] Instead of calculating all points of the LUT in relation to the previous ones, perform a full calculation in one of the intermediate segments to stop error propagation. Signed-off-by: Felipe Clark <Felipe.Clark@xxxxxxx> Reviewed-by: Krunoslav Kovac <Krunoslav.Kovac@xxxxxxx> Acked-by: Qingqing Zhuo <qingqing.zhuo@xxxxxxx> --- .../amd/display/modules/color/color_gamma.c | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c index eced40a2fce4..5c67e12b2e55 100644 --- a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c +++ b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c @@ -30,6 +30,14 @@ #include "opp.h" #include "color_gamma.h" +/* When calculating LUT values the first region and at least one subsequent + * region are calculated with full precision. These defines are a demarcation + * of where the second region starts and ends. + * These are hardcoded values to avoid recalculating them in loops. + */ +#define PRECISE_LUT_REGION_START 224 +#define PRECISE_LUT_REGION_END 239 + static struct hw_x_point coordinates_x[MAX_HW_POINTS + 2]; // these are helpers for calculations to reduce stack usage @@ -346,7 +354,13 @@ static struct fixed31_32 translate_from_linear_space( dc_fixpt_recip(args->gamma)); } scratch_1 = dc_fixpt_add(one, args->a3); - if (cal_buffer->buffer_index < 16) + /* In the first region (first 16 points) and in the + * region delimited by START/END we calculate with + * full precision to avoid error accumulation. + */ + if ((cal_buffer->buffer_index >= PRECISE_LUT_REGION_START && + cal_buffer->buffer_index <= PRECISE_LUT_REGION_END) || + (cal_buffer->buffer_index < 16)) scratch_2 = dc_fixpt_pow(args->arg, dc_fixpt_recip(args->gamma)); else @@ -397,9 +411,7 @@ static struct fixed31_32 translate_from_linear_space_long( dc_fixpt_recip(args->gamma))), args->a2); else - return dc_fixpt_mul( - args->arg, - args->a1); + return dc_fixpt_mul(args->arg, args->a1); } static struct fixed31_32 calculate_gamma22(struct fixed31_32 arg, bool use_eetf, struct calculate_buffer *cal_buffer) @@ -717,7 +729,6 @@ static struct fixed31_32 calculate_mapped_value( BREAK_TO_DEBUGGER(); result = dc_fixpt_zero; } else { - BREAK_TO_DEBUGGER(); result = dc_fixpt_one; } @@ -976,6 +987,7 @@ static bool build_freesync_hdr(struct pwl_float_data_ex *rgb_regamma, cal_buffer->buffer_index = 0; // see var definition for more info rgb += 32; // first 32 points have problems with fixed point, too small coord_x += 32; + for (i = 32; i <= hw_points_num; i++) { if (!is_clipped) { if (use_eetf) { -- 2.17.1 _______________________________________________ amd-gfx mailing list amd-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/amd-gfx