On 16/04/2026 16:22, Kovac, Krunoslav wrote:
Thanks Melissa for following up.
I like the changes themselves, just some clarifications.
We do have a LUT with predefined HW curve, but it has some limitations: it cannot be used with subsampled 4:2:0/4:2:2 formats and it affects the linearity of color space in which HW scaler operates. In your case, we use the LUT after tone mapping in 3D LUT; that LUT doesn't have predefined curve. So it's not uncommon that we need to program our own degamma.

Hi Kruno,

Right, I reviewed this part in the cover letter after checking my notes that there is a hw curve for degamma, but not for shaper, blend and post-blend re-gamma, right? I forgot to correct this info here.
I wasn't aware about the subsampled limitation.


The motivation for the new segment distribution is best explained with an 8-bit sRGB case. Input has 256 possible values and HW LUTs have 256 points. Ideally in this case we'd use the LUT as basically plain indexing with no interpolation. The new distribution accomplishes this, it aligns 256 HW points with 256 possible inputs. Due to float representations of input, it's not aligned perfectly, but LERP-ing between two HW entries where input is always within small epsilon from one of entries doesn't materially change things.
I'll rewrite commit messages to include this explanation too.
Thanks for sharing these details.

Melissa

On 4/14/2026 17:55, Melissa Wen wrote:
In newer DCN families, there is no hw predefined curves. So, when
setting predefined TFs to gamm_corr, shaper, blend and regamma, the
driver resorts to the color modules and program those predefined curves
using LUTs. The driver is using the same LUT segmentation when
translating EOTF and inverse EOTF to hw points by using the same color
management helper to translate curve to hw points, however, LUT
representing EOTF may not follow the same region/segment distributions
of inverse EOTF. This is causing banding on blend when PQ predefined
curve is set. Use different helpers when linearizing and delinearizing.
This is the first step to fix banding but already mitigates the issue by
increase the number of points per segment from 8 to 16.

Signed-off-by: Melissa Wen <[email protected]>
---
  .../gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c    | 10 ++++------
  1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c
index b45ceb570a5c..17d54aadb5e1 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c
@@ -493,9 +493,8 @@ bool dcn32_set_mcm_luts(
      if (plane_state->blend_tf.type == TF_TYPE_HWPWL)
          lut_params = &plane_state->blend_tf.pwl;
      else if (plane_state->blend_tf.type == TF_TYPE_DISTRIBUTED_POINTS) { -        result = cm3_helper_translate_curve_to_hw_format(plane_state->ctx,
-                                 &plane_state->blend_tf,
- &dpp_base->regamma_params, false);
+        result = cm3_helper_translate_curve_to_degamma_hw_format(&plane_state->blend_tf,
+ &dpp_base->regamma_params);
          if (!result)
              return result;
  @@ -551,9 +550,8 @@ bool dcn32_set_input_transfer_func(struct dc *dc,
      if (plane_state->in_transfer_func.type == TF_TYPE_HWPWL)
          params = &plane_state->in_transfer_func.pwl;
      else if (plane_state->in_transfer_func.type == TF_TYPE_DISTRIBUTED_POINTS &&
- cm3_helper_translate_curve_to_hw_format(plane_state->ctx,
- &plane_state->in_transfer_func,
-                            &dpp_base->degamma_params, false))
+ cm3_helper_translate_curve_to_degamma_hw_format(&plane_state->in_transfer_func,
+ &dpp_base->degamma_params))
          params = &dpp_base->degamma_params;
        dpp_base->funcs->dpp_program_gamcor_lut(dpp_base, params);


Reply via email to