drm/amd/display: Use the correct input TF for video formats
authorNicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Tue, 31 Mar 2020 20:50:12 +0000 (16:50 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 22 Apr 2020 22:11:47 +0000 (18:11 -0400)
[Why]
Color blending for NV12 formats is incorrect because we're using the
predefined SRGB degamma.

[How]
Calculate the correct input transfer function for degamma from the color
module depending on what the actual surface format is.

Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Reviewed-by: Zhan Liu <Zhan.Liu@amd.com>
Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c

index 6b58761e4b04d4f388bc16b0db1d593621851164..d0554082f0dc52079d7e9afc70be10d2e04e659d 100644 (file)
@@ -420,9 +420,21 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
 {
        const struct drm_color_lut *degamma_lut;
        struct dc_plane_state *dc_plane_state = plane->dc_state;
+       enum dc_transfer_func_predefined tf = TRANSFER_FUNCTION_SRGB;
        uint32_t degamma_size;
        int r;
 
+       /* Get the correct base transfer function for implicit degamma. */
+       switch (dc_plane_state->format) {
+       case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
+       case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
+               /* DC doesn't have a transfer function for BT601 specifically. */
+               tf = TRANSFER_FUNCTION_BT709;
+               break;
+       default:
+               break;
+       }
+
        if (crtc->cm_has_degamma) {
                degamma_lut = __extract_blob_lut(crtc->base.degamma_lut,
                                                 &degamma_size);
@@ -456,8 +468,7 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
                 * map these to the atomic one instead.
                 */
                if (crtc->cm_is_degamma_srgb)
-                       dc_plane_state->in_transfer_func->tf =
-                               TRANSFER_FUNCTION_SRGB;
+                       dc_plane_state->in_transfer_func->tf = tf;
                else
                        dc_plane_state->in_transfer_func->tf =
                                TRANSFER_FUNCTION_LINEAR;
@@ -472,7 +483,12 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
                 * in linear space. Assume that the input is sRGB.
                 */
                dc_plane_state->in_transfer_func->type = TF_TYPE_PREDEFINED;
-               dc_plane_state->in_transfer_func->tf = TRANSFER_FUNCTION_SRGB;
+               dc_plane_state->in_transfer_func->tf = tf;
+
+               if (tf != TRANSFER_FUNCTION_SRGB &&
+                   !mod_color_calculate_degamma_params(
+                           dc_plane_state->in_transfer_func, NULL, false))
+                       return -ENOMEM;
        } else {
                /* ...Otherwise we can just bypass the DGM block. */
                dc_plane_state->in_transfer_func->type = TF_TYPE_BYPASS;