From 56e4cec67390e79ce7b20c34e0f8e32fd0d0bcfe Mon Sep 17 00:00:00 2001 From: "Leo (Sunpeng) Li" Date: Tue, 23 Jan 2018 17:43:37 -0500 Subject: [PATCH 3563/4131] drm/amd/display: When enabling CRC, disable dither & enable truncation When user-mode is using 8bpc, the hardware represents it internally using a higher bit depth. This causes problems when comparing CRCs for color managment tests. We need to disable dithering as well, since it makes CRC values non-deterministic. It's easy to see why dithering needs to be disabled, The reason why truncation also needs to be enabled is better described with an example. Consider the folowing which tests the color transform matrix (CTM): Expected CRC = FB_A -> Degamma (Bypassed) -> CTM (Bypassed) | v Obtain CRC <- Regamma(Bypassed) Actual CRC = FB_B -> Degamma (Bypassed) -> CTM (0.5*Identity) | v Obtain CRC <- Regamma(Bypassed) FB_A contains a solid red color at half intensity (127 @ 8bpc) FB_B contains a solid red color at full intensity (255 @ 8bpc) We expect that Expected CRC = Actual CRC, but that's not the case. When the CTM is applied, the output is at half intensity, but also at a higher bit depth within hardware. i.e. 255/2 = 127.5: not representable in 8bpc, but can be at 10bpc. This causes the two CRC's to be different. The solution is to truncate the output bit depth to the same as input when enabling CRC capture. Since Linux only supports 8bpc, hard code that for now. Signed-off-by: Leo (Sunpeng) Li Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c | 11 +++++++++-- drivers/gpu/drm/amd/display/dc/core/dc.c | 14 +++++++++++--- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c index dd4e015..45439752 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c @@ -60,18 +60,25 @@ int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name, return -EINVAL; } + /* When enabling CRC, we should also disable dithering. */ if (source == AMDGPU_DM_PIPE_CRC_SOURCE_AUTO) { if (dc_stream_configure_crc(stream_state->ctx->dc, stream_state, - true, true)) + true, true)) { crtc_state->crc_enabled = true; + dc_stream_set_dither_option(stream_state, + DITHER_OPTION_TRUN8); + } else return -EINVAL; } else { if (dc_stream_configure_crc(stream_state->ctx->dc, stream_state, - false, false)) + false, false)) { crtc_state->crc_enabled = false; + dc_stream_set_dither_option(stream_state, + DITHER_OPTION_DEFAULT); + } else return -EINVAL; } diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 3bb23a7..e28904e 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -316,7 +316,6 @@ void dc_stream_set_dither_option(struct dc_stream_state *stream, } } - memset(¶ms, 0, sizeof(params)); if (!pipes) return; if (option > DITHER_OPTION_MAX) @@ -324,9 +323,18 @@ void dc_stream_set_dither_option(struct dc_stream_state *stream, stream->dither_option = option; - resource_build_bit_depth_reduction_params(stream, - ¶ms); + memset(¶ms, 0, sizeof(params)); + resource_build_bit_depth_reduction_params(stream, ¶ms); stream->bit_depth_params = params; + + if (pipes->plane_res.xfm && + pipes->plane_res.xfm->funcs->transform_set_pixel_storage_depth) { + pipes->plane_res.xfm->funcs->transform_set_pixel_storage_depth( + pipes->plane_res.xfm, + pipes->plane_res.scl_data.lb_params.depth, + &stream->bit_depth_params); + } + pipes->stream_res.opp->funcs-> opp_program_bit_depth_reduction(pipes->stream_res.opp, ¶ms); } -- 2.7.4