From: Felipe <[email protected]>

[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 <[email protected]>
Reviewed-by: Krunoslav Kovac <[email protected]>
Acked-by: Qingqing Zhuo <[email protected]>
---
 .../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
[email protected]
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to