drm/amd/display: use a separate helper to translate degamma curves

In newer DCN families, there is no hw predefined curves for shaper,
blend and regamma. When userspace sets pre-defined curves for these
blocks, the driver uses AMD color module to program predefined curve as
LUT. However, it was using the same LUT segmentation for EOTF and
inverse EOTF by using the same color management helper. This is causing
banding on blend when PQ predefined curve is set. Besides that, degamma
predefined HW curve cannot be used with subsampled 4:2:0/4:2:2 formats
as it affects the linearity of color space in which HW scaler operates.

To mitigate banding when using the blend block and better support
subsampled format on degamma, use different translation helpers when
linearizing and delinearizing.

Tested-by: Matthew Schwartz <matthew.schwartz@linux.dev>
Reviewed-by: Harry Wentland <harry.wentland@amd.com>
Signed-off-by: Melissa Wen <mwen@igalia.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Melissa Wen 2026-06-23 17:58:59 +02:00 committed by Alex Deucher
parent e0378c21fc
commit 222e63bdda

View File

@ -493,11 +493,9 @@ bool dcn32_set_mcm_luts(
if (plane_state->cm.blend_func.type == TF_TYPE_HWPWL)
lut_params = &plane_state->cm.blend_func.pwl;
else if (plane_state->cm.blend_func.type == TF_TYPE_DISTRIBUTED_POINTS) {
result = cm3_helper_translate_curve_to_hw_format(
plane_state->ctx,
result = cm3_helper_translate_curve_to_degamma_hw_format(
&plane_state->cm.blend_func,
&dpp_base->regamma_params,
false);
&dpp_base->regamma_params);
if (!result)
return result;
@ -554,9 +552,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);