drm/amd/display: DGAM enabled for HDR

[Why]
On HW that doesn't have input LUT, we may combine degamma with OS ramp
Problem here is that it assumes DGAM is inverse of PQ or SRGB. It doesn't
handle linear case, it would default to sRGB and always enable DGAM..

[How] Add handling for linear case. Also check for null ramp and instead of
blowing up, assume it's identity.

Signed-off-by: Krunoslav Kovac <Krunoslav.Kovac@amd.com>
Reviewed-by: Anthony Koo <Anthony.Koo@amd.com>
Acked-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Krunoslav Kovac 2019-01-17 17:56:51 -05:00 committed by Alex Deucher
parent a057ec460a
commit 8f01591227
1 changed files with 52 additions and 37 deletions

View File

@ -1765,68 +1765,85 @@ bool mod_color_calculate_degamma_params(struct dc_transfer_func *input_tf,
{
struct dc_transfer_func_distributed_points *tf_pts = &input_tf->tf_pts;
struct dividers dividers;
struct pwl_float_data *rgb_user = NULL;
struct pwl_float_data_ex *curve = NULL;
struct gamma_pixel *axis_x = NULL;
struct pixel_gamma_point *coeff = NULL;
enum dc_transfer_func_predefined tf = TRANSFER_FUNCTION_SRGB;
uint32_t i;
bool ret = false;
if (input_tf->type == TF_TYPE_BYPASS)
return false;
/* we can use hardcoded curve for plain SRGB TF */
/* we can use hardcoded curve for plain SRGB TF
* If linear, it's bypass if on user ramp
*/
if (input_tf->type == TF_TYPE_PREDEFINED &&
input_tf->tf == TRANSFER_FUNCTION_SRGB &&
!mapUserRamp)
(input_tf->tf == TRANSFER_FUNCTION_SRGB ||
input_tf->tf == TRANSFER_FUNCTION_LINEAR) &&
!mapUserRamp)
return true;
input_tf->type = TF_TYPE_DISTRIBUTED_POINTS;
rgb_user = kvcalloc(ramp->num_entries + _EXTRA_POINTS,
sizeof(*rgb_user),
GFP_KERNEL);
if (!rgb_user)
goto rgb_user_alloc_fail;
if (mapUserRamp && ramp && ramp->type == GAMMA_RGB_256) {
rgb_user = kvcalloc(ramp->num_entries + _EXTRA_POINTS,
sizeof(*rgb_user),
GFP_KERNEL);
if (!rgb_user)
goto rgb_user_alloc_fail;
axis_x = kvcalloc(ramp->num_entries + _EXTRA_POINTS, sizeof(*axis_x),
GFP_KERNEL);
if (!axis_x)
goto axis_x_alloc_fail;
dividers.divider1 = dc_fixpt_from_fraction(3, 2);
dividers.divider2 = dc_fixpt_from_int(2);
dividers.divider3 = dc_fixpt_from_fraction(5, 2);
build_evenly_distributed_points(
axis_x,
ramp->num_entries,
dividers);
scale_gamma(rgb_user, ramp, dividers);
}
curve = kvcalloc(MAX_HW_POINTS + _EXTRA_POINTS, sizeof(*curve),
GFP_KERNEL);
GFP_KERNEL);
if (!curve)
goto curve_alloc_fail;
axis_x = kvcalloc(ramp->num_entries + _EXTRA_POINTS, sizeof(*axis_x),
GFP_KERNEL);
if (!axis_x)
goto axis_x_alloc_fail;
coeff = kvcalloc(MAX_HW_POINTS + _EXTRA_POINTS, sizeof(*coeff),
GFP_KERNEL);
GFP_KERNEL);
if (!coeff)
goto coeff_alloc_fail;
dividers.divider1 = dc_fixpt_from_fraction(3, 2);
dividers.divider2 = dc_fixpt_from_int(2);
dividers.divider3 = dc_fixpt_from_fraction(5, 2);
tf = input_tf->tf;
build_evenly_distributed_points(
axis_x,
ramp->num_entries,
dividers);
if (ramp->type == GAMMA_RGB_256 && mapUserRamp)
scale_gamma(rgb_user, ramp, dividers);
else if (ramp->type == GAMMA_RGB_FLOAT_1024)
scale_gamma_dx(rgb_user, ramp, dividers);
if (tf == TRANSFER_FUNCTION_PQ)
build_de_pq(curve,
MAX_HW_POINTS,
coordinates_x);
else
else if (tf == TRANSFER_FUNCTION_SRGB ||
tf == TRANSFER_FUNCTION_BT709)
build_degamma(curve,
MAX_HW_POINTS,
coordinates_x,
tf == TRANSFER_FUNCTION_SRGB ? true:false);
tf == TRANSFER_FUNCTION_SRGB ? true : false);
else if (tf == TRANSFER_FUNCTION_LINEAR) {
// just copy coordinates_x into curve
i = 0;
while (i != MAX_HW_POINTS + 1) {
curve[i].r = coordinates_x[i].x;
curve[i].g = curve[i].r;
curve[i].b = curve[i].r;
i++;
}
} else
goto invalid_tf_fail;
tf_pts->end_exponent = 0;
tf_pts->x_point_at_y1_red = 1;
@ -1836,23 +1853,21 @@ bool mod_color_calculate_degamma_params(struct dc_transfer_func *input_tf,
map_regamma_hw_to_x_user(ramp, coeff, rgb_user,
coordinates_x, axis_x, curve,
MAX_HW_POINTS, tf_pts,
mapUserRamp && ramp->type != GAMMA_CUSTOM);
if (ramp->type == GAMMA_CUSTOM)
apply_lut_1d(ramp, MAX_HW_POINTS, tf_pts);
mapUserRamp && ramp && ramp->type == GAMMA_RGB_256);
ret = true;
invalid_tf_fail:
kvfree(coeff);
coeff_alloc_fail:
kvfree(axis_x);
axis_x_alloc_fail:
kvfree(curve);
curve_alloc_fail:
kvfree(axis_x);
axis_x_alloc_fail:
kvfree(rgb_user);
rgb_user_alloc_fail:
return ret;
}