Commit 8f015912 authored by Krunoslav Kovac's avatar Krunoslav Kovac Committed by Alex Deucher

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: default avatarKrunoslav Kovac <Krunoslav.Kovac@amd.com>
Reviewed-by: default avatarAnthony Koo <Anthony.Koo@amd.com>
Acked-by: default avatarBhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent a057ec46
...@@ -1765,68 +1765,85 @@ bool mod_color_calculate_degamma_params(struct dc_transfer_func *input_tf, ...@@ -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 dc_transfer_func_distributed_points *tf_pts = &input_tf->tf_pts;
struct dividers dividers; struct dividers dividers;
struct pwl_float_data *rgb_user = NULL; struct pwl_float_data *rgb_user = NULL;
struct pwl_float_data_ex *curve = NULL; struct pwl_float_data_ex *curve = NULL;
struct gamma_pixel *axis_x = NULL; struct gamma_pixel *axis_x = NULL;
struct pixel_gamma_point *coeff = NULL; struct pixel_gamma_point *coeff = NULL;
enum dc_transfer_func_predefined tf = TRANSFER_FUNCTION_SRGB; enum dc_transfer_func_predefined tf = TRANSFER_FUNCTION_SRGB;
uint32_t i;
bool ret = false; bool ret = false;
if (input_tf->type == TF_TYPE_BYPASS) if (input_tf->type == TF_TYPE_BYPASS)
return false; 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 && if (input_tf->type == TF_TYPE_PREDEFINED &&
input_tf->tf == TRANSFER_FUNCTION_SRGB && (input_tf->tf == TRANSFER_FUNCTION_SRGB ||
input_tf->tf == TRANSFER_FUNCTION_LINEAR) &&
!mapUserRamp) !mapUserRamp)
return true; return true;
input_tf->type = TF_TYPE_DISTRIBUTED_POINTS; input_tf->type = TF_TYPE_DISTRIBUTED_POINTS;
if (mapUserRamp && ramp && ramp->type == GAMMA_RGB_256) {
rgb_user = kvcalloc(ramp->num_entries + _EXTRA_POINTS, rgb_user = kvcalloc(ramp->num_entries + _EXTRA_POINTS,
sizeof(*rgb_user), sizeof(*rgb_user),
GFP_KERNEL); GFP_KERNEL);
if (!rgb_user) if (!rgb_user)
goto rgb_user_alloc_fail; goto rgb_user_alloc_fail;
curve = kvcalloc(MAX_HW_POINTS + _EXTRA_POINTS, sizeof(*curve),
GFP_KERNEL);
if (!curve)
goto curve_alloc_fail;
axis_x = kvcalloc(ramp->num_entries + _EXTRA_POINTS, sizeof(*axis_x), axis_x = kvcalloc(ramp->num_entries + _EXTRA_POINTS, sizeof(*axis_x),
GFP_KERNEL); GFP_KERNEL);
if (!axis_x) if (!axis_x)
goto axis_x_alloc_fail; goto axis_x_alloc_fail;
coeff = kvcalloc(MAX_HW_POINTS + _EXTRA_POINTS, sizeof(*coeff),
GFP_KERNEL);
if (!coeff)
goto coeff_alloc_fail;
dividers.divider1 = dc_fixpt_from_fraction(3, 2); dividers.divider1 = dc_fixpt_from_fraction(3, 2);
dividers.divider2 = dc_fixpt_from_int(2); dividers.divider2 = dc_fixpt_from_int(2);
dividers.divider3 = dc_fixpt_from_fraction(5, 2); dividers.divider3 = dc_fixpt_from_fraction(5, 2);
tf = input_tf->tf;
build_evenly_distributed_points( build_evenly_distributed_points(
axis_x, axis_x,
ramp->num_entries, ramp->num_entries,
dividers); dividers);
if (ramp->type == GAMMA_RGB_256 && mapUserRamp)
scale_gamma(rgb_user, ramp, dividers); scale_gamma(rgb_user, ramp, dividers);
else if (ramp->type == GAMMA_RGB_FLOAT_1024) }
scale_gamma_dx(rgb_user, ramp, dividers);
curve = kvcalloc(MAX_HW_POINTS + _EXTRA_POINTS, sizeof(*curve),
GFP_KERNEL);
if (!curve)
goto curve_alloc_fail;
coeff = kvcalloc(MAX_HW_POINTS + _EXTRA_POINTS, sizeof(*coeff),
GFP_KERNEL);
if (!coeff)
goto coeff_alloc_fail;
tf = input_tf->tf;
if (tf == TRANSFER_FUNCTION_PQ) if (tf == TRANSFER_FUNCTION_PQ)
build_de_pq(curve, build_de_pq(curve,
MAX_HW_POINTS, MAX_HW_POINTS,
coordinates_x); coordinates_x);
else else if (tf == TRANSFER_FUNCTION_SRGB ||
tf == TRANSFER_FUNCTION_BT709)
build_degamma(curve, build_degamma(curve,
MAX_HW_POINTS, MAX_HW_POINTS,
coordinates_x, 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->end_exponent = 0;
tf_pts->x_point_at_y1_red = 1; tf_pts->x_point_at_y1_red = 1;
...@@ -1836,23 +1853,21 @@ bool mod_color_calculate_degamma_params(struct dc_transfer_func *input_tf, ...@@ -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, map_regamma_hw_to_x_user(ramp, coeff, rgb_user,
coordinates_x, axis_x, curve, coordinates_x, axis_x, curve,
MAX_HW_POINTS, tf_pts, MAX_HW_POINTS, tf_pts,
mapUserRamp && ramp->type != GAMMA_CUSTOM); mapUserRamp && ramp && ramp->type == GAMMA_RGB_256);
if (ramp->type == GAMMA_CUSTOM)
apply_lut_1d(ramp, MAX_HW_POINTS, tf_pts);
ret = true; ret = true;
invalid_tf_fail:
kvfree(coeff); kvfree(coeff);
coeff_alloc_fail: coeff_alloc_fail:
kvfree(axis_x);
axis_x_alloc_fail:
kvfree(curve); kvfree(curve);
curve_alloc_fail: curve_alloc_fail:
kvfree(axis_x);
axis_x_alloc_fail:
kvfree(rgb_user); kvfree(rgb_user);
rgb_user_alloc_fail: rgb_user_alloc_fail:
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment