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 <Felipe.Clark@amd.com> Reviewed-by: Krunoslav Kovac <Krunoslav.Kovac@amd.com> Acked-by: Qingqing Zhuo <qingqing.zhuo@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
610c4974ad
commit
e10777a679
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue