From: Felipe Date: Mon, 30 Nov 2020 22:38:02 +0000 (-0500) Subject: drm/amd/display: Fix OGAM LUT calculation precision X-Git-Tag: accepted/tizen/unified/20230118.172025~7733^2~22^2~143 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e10777a67963163055f9ca43292cb21ff52967d2;p=platform%2Fkernel%2Flinux-rpi.git drm/amd/display: Fix OGAM LUT calculation precision [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 Reviewed-by: Krunoslav Kovac Acked-by: Qingqing Zhuo Signed-off-by: Alex Deucher --- 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 eced40a..5c67e12 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) {