]> git.dujemihanovic.xyz Git - linux.git/commitdiff
drm/amd/display: Add debug options to change sharpen policies
authorSamson Tam <Samson.Tam@amd.com>
Tue, 27 Aug 2024 15:53:10 +0000 (11:53 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 18 Sep 2024 20:15:07 +0000 (16:15 -0400)
[WHY]
Add options to change sharpen policy based on surface format
and scaling ratios.

[HOW]
Add sharpen_policy to change policy based on surface format
and scale_to_sharpness_policy based on scaling ratios.

Reviewed-by: Jun Lei <jun.lei@amd.com>
Signed-off-by: Samson Tam <Samson.Tam@amd.com>
Signed-off-by: Alex Hung <alex.hung@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/dc.h
drivers/gpu/drm/amd/display/dc/dc_spl_translate.c
drivers/gpu/drm/amd/display/dc/spl/dc_spl.c
drivers/gpu/drm/amd/display/dc/spl/dc_spl_isharp_filters.c
drivers/gpu/drm/amd/display/dc/spl/dc_spl_isharp_filters.h
drivers/gpu/drm/amd/display/dc/spl/dc_spl_types.h

index dcf8a90e961d30be8c1c468c9836f73b14a87785..7c4812dd1a71878d9a5dbac4bbaafc79b186519d 100644 (file)
@@ -1056,6 +1056,8 @@ struct dc_debug_options {
        unsigned int force_lls;
        bool notify_dpia_hr_bw;
        bool enable_ips_visual_confirm;
+       unsigned int sharpen_policy;
+       unsigned int scale_to_sharpness_policy;
 };
 
 
index f711fc2e3e6517739589a7f642624447fe42a94d..603552dbd7716480cecf3f811901671db511c221 100644 (file)
@@ -186,6 +186,11 @@ void translate_SPL_in_params_from_pipe_ctx(struct pipe_ctx *pipe_ctx, struct spl
 
        spl_in->h_active = pipe_ctx->plane_res.scl_data.h_active;
        spl_in->v_active = pipe_ctx->plane_res.scl_data.v_active;
+
+       spl_in->debug.sharpen_policy = (enum sharpen_policy)pipe_ctx->stream->ctx->dc->debug.sharpen_policy;
+       spl_in->debug.scale_to_sharpness_policy =
+               (enum scale_to_sharpness_policy)pipe_ctx->stream->ctx->dc->debug.scale_to_sharpness_policy;
+
        /* Check if it is stream is in fullscreen and if its HDR.
         * Use this to determine sharpness levels
         */
index a59aa6b596875d698680693a2f037c971e2aef4a..f7a654b3a092f3afb8556e6100d04721828211f2 100644 (file)
@@ -813,6 +813,14 @@ static bool enable_easf(struct spl_in *spl_in, struct spl_scratch *spl_scratch)
        return skip_easf;
 }
 
+/* Check if video is in fullscreen mode */
+static bool spl_is_video_fullscreen(struct spl_in *spl_in)
+{
+       if (spl_is_yuv420(spl_in->basic_in.format) && spl_in->is_fullscreen)
+               return true;
+       return false;
+}
+
 static bool spl_get_isharp_en(struct spl_in *spl_in,
        struct spl_scratch *spl_scratch)
 {
@@ -820,6 +828,7 @@ static bool spl_get_isharp_en(struct spl_in *spl_in,
        int vratio = 0;
        int hratio = 0;
        struct spl_taps taps = spl_scratch->scl_data.taps;
+       bool fullscreen = spl_is_video_fullscreen(spl_in);
 
        /* Return if adaptive sharpness is disabled */
        if (spl_in->adaptive_sharpness.enable == false)
@@ -835,9 +844,15 @@ static bool spl_get_isharp_en(struct spl_in *spl_in,
        // Scaling is up to 1:1 (no scaling) or upscaling
 
        /*
-        * Apply sharpness to all RGB surfaces and to
-        *  NV12/P010 surfaces
+        * Apply sharpness to RGB and YUV (NV12/P010)
+        *  surfaces based on policy setting
         */
+       if (!spl_is_yuv420(spl_in->basic_in.format) &&
+               (spl_in->debug.sharpen_policy == SHARPEN_YUV))
+               return enable_isharp;
+       else if ((spl_is_yuv420(spl_in->basic_in.format) && !fullscreen) &&
+               (spl_in->debug.sharpen_policy == SHARPEN_RGB_FULLSCREEN_YUV))
+               return enable_isharp;
 
        /*
         * Apply sharpness if supports horizontal taps 4,6 AND
@@ -1562,7 +1577,7 @@ static void spl_set_isharp_data(struct dscl_prog_data *dscl_prog_data,
                struct adaptive_sharpness adp_sharpness, bool enable_isharp,
                enum linear_light_scaling lls_pref, enum spl_pixel_format format,
                const struct spl_scaler_data *data, struct spl_fixed31_32 ratio,
-               enum system_setup setup)
+               enum system_setup setup, enum scale_to_sharpness_policy scale_to_sharpness_policy)
 {
        /* Turn off sharpener if not required */
        if (!enable_isharp) {
@@ -1570,6 +1585,11 @@ static void spl_set_isharp_data(struct dscl_prog_data *dscl_prog_data,
                return;
        }
 
+       spl_build_isharp_1dlut_from_reference_curve(ratio, setup, adp_sharpness,
+               scale_to_sharpness_policy);
+       dscl_prog_data->isharp_delta = spl_get_pregen_filter_isharp_1D_lut(setup);
+       dscl_prog_data->sharpness_level = adp_sharpness.sharpness_level;
+
        dscl_prog_data->isharp_en = 1;  // ISHARP_EN
        // Set ISHARP_NOISEDET_MODE if htaps = 6-tap
        if (data->taps.h_taps == 6) {
@@ -1667,11 +1687,6 @@ static void spl_set_isharp_data(struct dscl_prog_data *dscl_prog_data,
                dscl_prog_data->isharp_lba.base_seg[5] = 0;     // ISHARP LBA PWL for Seg 5. BASE value in U0.6 format
        }
 
-
-       spl_build_isharp_1dlut_from_reference_curve(ratio, setup, adp_sharpness);
-       dscl_prog_data->isharp_delta = spl_get_pregen_filter_isharp_1D_lut(setup);
-       dscl_prog_data->sharpness_level = adp_sharpness.sharpness_level;
-
        // Program the nldelta soft clip values
        if (lls_pref == LLS_PREF_YES) {
                dscl_prog_data->isharp_nldelta_sclip.enable_p = 0;      /* ISHARP_NLDELTA_SCLIP_EN_P */
@@ -1766,7 +1781,8 @@ bool spl_calculate_scaler_params(struct spl_in *spl_in, struct spl_out *spl_out)
                isharp_scale_ratio = spl_scratch.scl_data.recip_ratios.horz;
 
        spl_set_isharp_data(spl_out->dscl_prog_data, spl_in->adaptive_sharpness, enable_isharp,
-               spl_in->lls_pref, spl_in->basic_in.format, data, isharp_scale_ratio, setup);
+               spl_in->lls_pref, spl_in->basic_in.format, data, isharp_scale_ratio, setup,
+               spl_in->debug.scale_to_sharpness_policy);
 
        return res;
 }
index 33712f50d303b71760e4e0d3c8ebf330e490bdaf..e0572252c640464fe9ed484d814456d3aa15d8a4 100644 (file)
@@ -500,6 +500,15 @@ struct isharp_1D_lut_pregen filter_isharp_1D_lut_pregen[NUM_SHARPNESS_SETUPS] =
        },
 };
 
+struct scale_ratio_to_sharpness_level_adj sharpness_level_adj[NUM_SHARPNESS_ADJ_LEVELS] = {
+       {1125, 1000, 0},
+       {11, 10, 1},
+       {1075, 1000, 2},
+       {105, 100, 3},
+       {1025, 1000, 4},
+       {1, 1, 5},
+};
+
 const uint32_t *spl_get_filter_isharp_1D_lut_0(void)
 {
        return filter_isharp_1D_lut_0;
@@ -541,19 +550,72 @@ uint16_t *spl_get_filter_isharp_bs_3tap_64p(void)
        return filter_isharp_bs_3tap_64p_s1_12;
 }
 
-static unsigned int spl_calculate_sharpness_level(int discrete_sharpness_level, enum system_setup setup,
-               struct spl_sharpness_range sharpness_range)
+static unsigned int spl_calculate_sharpness_level_adj(struct spl_fixed31_32 ratio)
+{
+       int j;
+       struct spl_fixed31_32 ratio_level;
+       struct scale_ratio_to_sharpness_level_adj *lookup_ptr;
+       unsigned int sharpness_level_down_adj;
+
+       /*
+        * Adjust sharpness level based on current scaling ratio
+        *
+        * We have 5 discrete scaling ratios which we will use to adjust the
+        *  sharpness level down by 1 as we pass each ratio.  The ratios
+        *  are
+        *
+        * 1.125 upscale and higher - no adj
+        * 1.100 - under 1.125 - adj level down 1
+        * 1.075 - under 1.100 - adj level down 2
+        * 1.050 - under 1.075 - adj level down 3
+        * 1.025 - under 1.050 - adj level down 4
+        * 1.000 - under 1.025 - adj level down 5
+        *
+        */
+       j = 0;
+       sharpness_level_down_adj = 0;
+       lookup_ptr = sharpness_level_adj;
+       while (j < NUM_SHARPNESS_ADJ_LEVELS) {
+               ratio_level = spl_fixpt_from_fraction(lookup_ptr->ratio_numer,
+                       lookup_ptr->ratio_denom);
+               if (ratio.value >= ratio_level.value) {
+                       sharpness_level_down_adj = lookup_ptr->level_down_adj;
+                       break;
+               }
+               lookup_ptr++;
+               j++;
+       }
+       return sharpness_level_down_adj;
+}
+
+static unsigned int spl_calculate_sharpness_level(struct spl_fixed31_32 ratio,
+               int discrete_sharpness_level, enum system_setup setup,
+               struct spl_sharpness_range sharpness_range,
+               enum scale_to_sharpness_policy scale_to_sharpness_policy)
 {
        unsigned int sharpness_level = 0;
+       unsigned int sharpness_level_down_adj = 0;
 
        int min_sharpness, max_sharpness, mid_sharpness;
 
+       /*
+        * Adjust sharpness level if policy requires we adjust it based on
+        *  scale ratio.  Based on scale ratio, we may adjust the sharpness
+        *  level down by a certain number of steps.  We will not select
+        *  a sharpness value of 0 so the lowest sharpness level will be
+        *  0 or 1 depending on what the min_sharpness is
+        *
+        * If the policy is no required, this code maybe removed at a later
+        *  date
+        */
        switch (setup) {
 
        case HDR_L:
                min_sharpness = sharpness_range.hdr_rgb_min;
                max_sharpness = sharpness_range.hdr_rgb_max;
                mid_sharpness = sharpness_range.hdr_rgb_mid;
+               if (scale_to_sharpness_policy == SCALE_TO_SHARPNESS_ADJ_ALL)
+                       sharpness_level_down_adj = spl_calculate_sharpness_level_adj(ratio);
                break;
        case HDR_NL:
                /* currently no use case, use Non-linear SDR values for now */
@@ -561,15 +623,26 @@ static unsigned int spl_calculate_sharpness_level(int discrete_sharpness_level,
                min_sharpness = sharpness_range.sdr_yuv_min;
                max_sharpness = sharpness_range.sdr_yuv_max;
                mid_sharpness = sharpness_range.sdr_yuv_mid;
+               if (scale_to_sharpness_policy >= SCALE_TO_SHARPNESS_ADJ_YUV)
+                       sharpness_level_down_adj = spl_calculate_sharpness_level_adj(ratio);
                break;
        case SDR_L:
        default:
                min_sharpness = sharpness_range.sdr_rgb_min;
                max_sharpness = sharpness_range.sdr_rgb_max;
                mid_sharpness = sharpness_range.sdr_rgb_mid;
+               if (scale_to_sharpness_policy == SCALE_TO_SHARPNESS_ADJ_ALL)
+                       sharpness_level_down_adj = spl_calculate_sharpness_level_adj(ratio);
                break;
        }
 
+       if ((min_sharpness == 0) && (sharpness_level_down_adj >= discrete_sharpness_level))
+               discrete_sharpness_level = 1;
+       else if (sharpness_level_down_adj >= discrete_sharpness_level)
+               discrete_sharpness_level = 0;
+       else
+               discrete_sharpness_level -= sharpness_level_down_adj;
+
        int lower_half_step_size = (mid_sharpness - min_sharpness) / 5;
        int upper_half_step_size = (max_sharpness - mid_sharpness) / 5;
 
@@ -584,7 +657,7 @@ static unsigned int spl_calculate_sharpness_level(int discrete_sharpness_level,
 }
 
 void spl_build_isharp_1dlut_from_reference_curve(struct spl_fixed31_32 ratio, enum system_setup setup,
-       struct adaptive_sharpness sharpness)
+       struct adaptive_sharpness sharpness, enum scale_to_sharpness_policy scale_to_sharpness_policy)
 {
        uint8_t *byte_ptr_1dlut_src, *byte_ptr_1dlut_dst;
        struct spl_fixed31_32 sharp_base, sharp_calc, sharp_level;
@@ -594,8 +667,9 @@ void spl_build_isharp_1dlut_from_reference_curve(struct spl_fixed31_32 ratio, en
        uint32_t filter_pregen_store[ISHARP_LUT_TABLE_SIZE];
 
        /* Custom sharpnessX1000 value */
-       unsigned int sharpnessX1000 = spl_calculate_sharpness_level(sharpness.sharpness_level,
-                       setup, sharpness.sharpness_range);
+       unsigned int sharpnessX1000 = spl_calculate_sharpness_level(ratio,
+                       sharpness.sharpness_level, setup,
+                       sharpness.sharpness_range, scale_to_sharpness_policy);
        sharp_level = spl_fixpt_from_fraction(sharpnessX1000, 1000);
 
        /*
@@ -606,7 +680,6 @@ void spl_build_isharp_1dlut_from_reference_curve(struct spl_fixed31_32 ratio, en
                (filter_isharp_1D_lut_pregen[setup].sharpness_denom == 1000))
                return;
 
-
        /*
         * Calculate LUT_128_gained with this equation:
         *
index fe0b12571f2c50b38764c31272904c2438e42023..afcc66206ca2a799fd0186bc8d93294584057a96 100644 (file)
@@ -20,11 +20,11 @@ uint16_t *spl_get_filter_isharp_bs_3tap_64p(void);
 const uint16_t *spl_get_filter_isharp_wide_6tap_64p(void);
 uint16_t *spl_dscl_get_blur_scale_coeffs_64p(int taps);
 
-struct scale_ratio_to_sharpness_level_lookup {
+#define NUM_SHARPNESS_ADJ_LEVELS 6
+struct scale_ratio_to_sharpness_level_adj {
        unsigned int ratio_numer;
        unsigned int ratio_denom;
-       unsigned int sharpness_numer;
-       unsigned int sharpness_denom;
+       unsigned int level_down_adj; /* adjust sharpness level down */
 };
 
 struct isharp_1D_lut_pregen {
@@ -45,6 +45,7 @@ void spl_init_blur_scale_coeffs(void);
 void spl_set_blur_scale_data(struct dscl_prog_data *dscl_prog_data,
        const struct spl_scaler_data *data);
 
-void spl_build_isharp_1dlut_from_reference_curve(struct spl_fixed31_32 ratio, enum system_setup setup, struct adaptive_sharpness sharpness);
+void spl_build_isharp_1dlut_from_reference_curve(struct spl_fixed31_32 ratio, enum system_setup setup,
+       struct adaptive_sharpness sharpness, enum scale_to_sharpness_policy scale_to_sharpness_policy);
 uint32_t *spl_get_pregen_filter_isharp_1D_lut(enum system_setup setup);
 #endif /* __DC_SPL_ISHARP_FILTERS_H__ */
index 74f2a8c42f4f88ffba933d886745b9ea7ce5cc76..425d4a282c7a7d05f9565cf36b9a6b00f8ca92d1 100644 (file)
@@ -487,6 +487,16 @@ enum linear_light_scaling  {       // convert it in translation logic
        LLS_PREF_YES,
        LLS_PREF_NO
 };
+enum sharpen_policy {
+       SHARPEN_ALWAYS = 0,
+       SHARPEN_YUV = 1,
+       SHARPEN_RGB_FULLSCREEN_YUV = 2
+};
+enum scale_to_sharpness_policy {
+       NO_SCALE_TO_SHARPNESS_ADJ = 0,
+       SCALE_TO_SHARPNESS_ADJ_YUV = 1,
+       SCALE_TO_SHARPNESS_ADJ_ALL = 2
+};
 struct spl_funcs       {
        void (*spl_calc_lb_num_partitions)
                (bool alpha_en,
@@ -499,6 +509,8 @@ struct spl_funcs    {
 struct spl_debug {
        int visual_confirm_base_offset;
        int visual_confirm_dpp_offset;
+       enum sharpen_policy sharpen_policy;
+       enum scale_to_sharpness_policy scale_to_sharpness_policy;
 };
 
 struct spl_in  {