Commit e10777a6 authored by Felipe's avatar Felipe Committed by Alex Deucher
Browse files

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: default avatarFelipe Clark <Felipe.Clark@amd.com>
Reviewed-by: default avatarKrunoslav Kovac <Krunoslav.Kovac@amd.com>
Acked-by: default avatarQingqing Zhuo <qingqing.zhuo@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 610c4974
Loading
Loading
Loading
Loading
+17 −5
Original line number Diff line number Diff line
@@ -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) {