OSDN Git Service

drm/amd/display: w/a for ycbcr output pre-multiplied alpha corruption
authorDmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>
Mon, 5 Jun 2017 19:08:10 +0000 (15:08 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 26 Sep 2017 22:07:58 +0000 (18:07 -0400)
Signed-off-by: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>
Reviewed-by: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>
Acked-by: Harry Wentland <Harry.Wentland@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c
drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h

index f509dfd..f412300 100644 (file)
@@ -1658,6 +1658,28 @@ static bool is_pipe_tree_visible(struct pipe_ctx *pipe_ctx)
        return false;
 }
 
+static bool is_rgb_cspace(enum dc_color_space output_color_space)
+{
+       switch (output_color_space) {
+       case COLOR_SPACE_SRGB:
+       case COLOR_SPACE_SRGB_LIMITED:
+       case COLOR_SPACE_2020_RGB_FULLRANGE:
+       case COLOR_SPACE_2020_RGB_LIMITEDRANGE:
+       case COLOR_SPACE_ADOBERGB:
+               return true;
+       case COLOR_SPACE_YCBCR601:
+       case COLOR_SPACE_YCBCR709:
+       case COLOR_SPACE_YCBCR601_LIMITED:
+       case COLOR_SPACE_YCBCR709_LIMITED:
+       case COLOR_SPACE_2020_YCBCR:
+               return false;
+       default:
+               /* Add a case to switch */
+               BREAK_TO_DEBUGGER();
+               return false;
+       }
+}
+
 static void update_dchubp_dpp(
        struct core_dc *dc,
        struct pipe_ctx *pipe_ctx,
@@ -1719,6 +1741,12 @@ static void update_dchubp_dpp(
                mpcc_cfg.bot_mpcc_id = 0xf;
        mpcc_cfg.top_of_tree = !pipe_ctx->top_pipe;
        mpcc_cfg.per_pixel_alpha = per_pixel_alpha;
+       /* DCN1.0 has output CM before MPC which seems to screw with
+        * pre-multiplied alpha.
+        */
+       mpcc_cfg.pre_multiplied_alpha = is_rgb_cspace(
+                       pipe_ctx->stream->public.output_color_space)
+                                       && per_pixel_alpha;
        if (!dc->current_context->res_ctx.pipe_ctx[pipe_ctx->pipe_idx].surface)
                pipe_ctx->mpcc->funcs->wait_for_idle(pipe_ctx->mpcc);
        pipe_ctx->mpcc->funcs->set(pipe_ctx->mpcc, &mpcc_cfg);
index 19af0ee..b1c590d 100644 (file)
@@ -98,7 +98,7 @@ static void dcn10_mpcc_set(struct mpcc *mpcc, struct mpcc_cfg *cfg)
        REG_SET_4(MPCC_CONTROL, 0xffffffff,
                MPCC_MODE, mpcc_mode,
                MPCC_ALPHA_BLND_MODE, alpha_blnd_mode,
-               MPCC_ALPHA_MULTIPLIED_MODE, 0/*TODO: cfg->per_pixel_alpha*/,
+               MPCC_ALPHA_MULTIPLIED_MODE, cfg->pre_multiplied_alpha,
                MPCC_BLND_ACTIVE_OVERLAP_ONLY, cfg->top_of_tree);
 
        if (cfg->top_of_tree) {
index 38d1587..51bc8ef 100644 (file)
@@ -32,6 +32,7 @@ struct mpcc_cfg {
        int bot_mpcc_id;
        int opp_id;
        bool per_pixel_alpha;
+       bool pre_multiplied_alpha;
        bool top_of_tree;
 };