drm/amd/display: Enable MPO with pre-blend color processing (RGB)
[Why] DCN10 performs color processing before MPC combination, causes color shift in RGB colorspaces when positive brightness offset is applied However, YCbCr is still unfixed and remains disabled [How] Add layerIndex to dc_plane_state and dc_plane_info structs Re-enable MPO when brightness is adjusted and colorspace is not YCbCr Set rear plane's brightness offset to 0 when front plane visible Signed-off-by: Michael Strauss <michael.strauss@amd.com> Reviewed-by: Anthony Koo <Anthony.Koo@amd.com> Acked-by: Leo Li <sunpeng.li@amd.com> Acked-by: Nicholas Kazlauskas <Nicholas.Kazlauskas@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
committed by
Alex Deucher
parent
30b7200c12
commit
6d83a32d0b
@@ -3006,6 +3006,8 @@ fill_dc_plane_info_and_addr(struct amdgpu_device *adev,
|
|||||||
plane_info->visible = true;
|
plane_info->visible = true;
|
||||||
plane_info->stereo_format = PLANE_STEREO_FORMAT_NONE;
|
plane_info->stereo_format = PLANE_STEREO_FORMAT_NONE;
|
||||||
|
|
||||||
|
plane_info->layer_index = 0;
|
||||||
|
|
||||||
ret = fill_plane_color_attributes(plane_state, plane_info->format,
|
ret = fill_plane_color_attributes(plane_state, plane_info->format,
|
||||||
&plane_info->color_space);
|
&plane_info->color_space);
|
||||||
if (ret)
|
if (ret)
|
||||||
@@ -3071,6 +3073,7 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev,
|
|||||||
dc_plane_state->global_alpha = plane_info.global_alpha;
|
dc_plane_state->global_alpha = plane_info.global_alpha;
|
||||||
dc_plane_state->global_alpha_value = plane_info.global_alpha_value;
|
dc_plane_state->global_alpha_value = plane_info.global_alpha_value;
|
||||||
dc_plane_state->dcc = plane_info.dcc;
|
dc_plane_state->dcc = plane_info.dcc;
|
||||||
|
dc_plane_state->layer_index = plane_info.layer_index; // Always returns 0
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Always set input transfer function, since plane state is refreshed
|
* Always set input transfer function, since plane state is refreshed
|
||||||
|
|||||||
@@ -1692,6 +1692,8 @@ static void copy_surface_update_to_plane(
|
|||||||
srf_update->plane_info->dcc;
|
srf_update->plane_info->dcc;
|
||||||
surface->sdr_white_level =
|
surface->sdr_white_level =
|
||||||
srf_update->plane_info->sdr_white_level;
|
srf_update->plane_info->sdr_white_level;
|
||||||
|
surface->layer_index =
|
||||||
|
srf_update->plane_info->layer_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (srf_update->gamma &&
|
if (srf_update->gamma &&
|
||||||
|
|||||||
@@ -750,6 +750,7 @@ struct dc_plane_state {
|
|||||||
bool visible;
|
bool visible;
|
||||||
bool flip_immediate;
|
bool flip_immediate;
|
||||||
bool horizontal_mirror;
|
bool horizontal_mirror;
|
||||||
|
int layer_index;
|
||||||
|
|
||||||
union surface_update_flags update_flags;
|
union surface_update_flags update_flags;
|
||||||
/* private to DC core */
|
/* private to DC core */
|
||||||
@@ -779,6 +780,7 @@ struct dc_plane_info {
|
|||||||
bool global_alpha;
|
bool global_alpha;
|
||||||
int global_alpha_value;
|
int global_alpha_value;
|
||||||
bool input_csc_enabled;
|
bool input_csc_enabled;
|
||||||
|
int layer_index;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dc_scaling_info {
|
struct dc_scaling_info {
|
||||||
|
|||||||
@@ -1905,6 +1905,36 @@ static void dcn10_program_gamut_remap(struct pipe_ctx *pipe_ctx)
|
|||||||
pipe_ctx->plane_res.dpp->funcs->dpp_set_gamut_remap(pipe_ctx->plane_res.dpp, &adjust);
|
pipe_ctx->plane_res.dpp->funcs->dpp_set_gamut_remap(pipe_ctx->plane_res.dpp, &adjust);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool dcn10_is_rear_mpo_fix_required(struct pipe_ctx *pipe_ctx, enum dc_color_space colorspace)
|
||||||
|
{
|
||||||
|
if (pipe_ctx->plane_state && pipe_ctx->plane_state->layer_index > 0 && is_rgb_cspace(colorspace)) {
|
||||||
|
if (pipe_ctx->top_pipe) {
|
||||||
|
struct pipe_ctx *top = pipe_ctx->top_pipe;
|
||||||
|
|
||||||
|
while (top->top_pipe)
|
||||||
|
top = top->top_pipe; // Traverse to top pipe_ctx
|
||||||
|
if (top->plane_state && top->plane_state->layer_index == 0)
|
||||||
|
return true; // Front MPO plane not hidden
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dcn10_set_csc_adjustment_rgb_mpo_fix(struct pipe_ctx *pipe_ctx, uint16_t *matrix)
|
||||||
|
{
|
||||||
|
// Override rear plane RGB bias to fix MPO brightness
|
||||||
|
uint16_t rgb_bias = matrix[3];
|
||||||
|
|
||||||
|
matrix[3] = 0;
|
||||||
|
matrix[7] = 0;
|
||||||
|
matrix[11] = 0;
|
||||||
|
pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_adjustment(pipe_ctx->plane_res.dpp, matrix);
|
||||||
|
matrix[3] = rgb_bias;
|
||||||
|
matrix[7] = rgb_bias;
|
||||||
|
matrix[11] = rgb_bias;
|
||||||
|
}
|
||||||
|
|
||||||
static void dcn10_program_output_csc(struct dc *dc,
|
static void dcn10_program_output_csc(struct dc *dc,
|
||||||
struct pipe_ctx *pipe_ctx,
|
struct pipe_ctx *pipe_ctx,
|
||||||
enum dc_color_space colorspace,
|
enum dc_color_space colorspace,
|
||||||
@@ -1912,8 +1942,25 @@ static void dcn10_program_output_csc(struct dc *dc,
|
|||||||
int opp_id)
|
int opp_id)
|
||||||
{
|
{
|
||||||
if (pipe_ctx->stream->csc_color_matrix.enable_adjustment == true) {
|
if (pipe_ctx->stream->csc_color_matrix.enable_adjustment == true) {
|
||||||
if (pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_adjustment != NULL)
|
if (pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_adjustment != NULL) {
|
||||||
|
|
||||||
|
/* MPO is broken with RGB colorspaces when OCSC matrix
|
||||||
|
* brightness offset >= 0 on DCN1 due to OCSC before MPC
|
||||||
|
* Blending adds offsets from front + rear to rear plane
|
||||||
|
*
|
||||||
|
* Fix is to set RGB bias to 0 on rear plane, top plane
|
||||||
|
* black value pixels add offset instead of rear + front
|
||||||
|
*/
|
||||||
|
|
||||||
|
int16_t rgb_bias = matrix[3];
|
||||||
|
// matrix[3/7/11] are all the same offset value
|
||||||
|
|
||||||
|
if (rgb_bias > 0 && dcn10_is_rear_mpo_fix_required(pipe_ctx, colorspace)) {
|
||||||
|
dcn10_set_csc_adjustment_rgb_mpo_fix(pipe_ctx, matrix);
|
||||||
|
} else {
|
||||||
pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_adjustment(pipe_ctx->plane_res.dpp, matrix);
|
pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_adjustment(pipe_ctx->plane_res.dpp, matrix);
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_default != NULL)
|
if (pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_default != NULL)
|
||||||
pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_default(pipe_ctx->plane_res.dpp, colorspace);
|
pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_default(pipe_ctx->plane_res.dpp, colorspace);
|
||||||
|
|||||||
Reference in New Issue
Block a user