[AMD Official Use Only - AMD Internal Distribution Only]

Hi Melissa,

Thank you for letting me know, we saw that commit fix similar problems on our 
side, glad to hear it worked for you as well.

Best regards,
Dominik Kaszewski
Senior Software Engineer
SW - Display NPI

-----Original Message-----
From: Melissa Wen <[email protected]>
Sent: Friday, January 16, 2026 3:20 PM
To: Kaszewski, Dominik <[email protected]>; Chen, Chen-Yu 
<[email protected]>; [email protected]
Cc: Wentland, Harry <[email protected]>; Li, Sun peng (Leo) 
<[email protected]>; Pillai, Aurabindo <[email protected]>; Li, Roman 
<[email protected]>; Lin, Wayne <[email protected]>; Chung, ChiaHsuan (Tom) 
<[email protected]>; Zuo, Jerry <[email protected]>; Wheeler, Daniel 
<[email protected]>; Wu, Ray <[email protected]>; LIPSKI, IVAN 
<[email protected]>; Hung, Alex <[email protected]>; Kazlauskas, Nicholas 
<[email protected]>
Subject: Re: [PATCH 06/16] drm/amd/display: Fix and reenable 
UPDATE_V3_FLOW_NEW_CONTEXT_MINIMAL

Hey,

Just to let you know that I tested this commit:
https://gitlab.freedesktop.org/agd5f/linux/-/commit/85c4669b1834 and the 
regression is solved.

Thanks,

Melissa

On 12/01/2026 10:58, Kaszewski, Dominik wrote:
> [AMD Official Use Only - AMD Internal Distribution Only]
>
> Hi Melissa,
>
> Thank you for letting me know, I will look into this regression.
>
> Best regards,
> Dominik Kaszewski
> Senior Software Engineer
> SW - Display NPI
>
> -----Original Message-----
> From: Melissa Wen <[email protected]>
> Sent: Monday, January 12, 2026 12:44 PM
> To: Chen, Chen-Yu <[email protected]>;
> [email protected]
> Cc: Wentland, Harry <[email protected]>; Li, Sun peng (Leo)
> <[email protected]>; Pillai, Aurabindo <[email protected]>;
> Li, Roman <[email protected]>; Lin, Wayne <[email protected]>; Chung,
> ChiaHsuan (Tom) <[email protected]>; Zuo, Jerry
> <[email protected]>; Wheeler, Daniel <[email protected]>; Wu, Ray
> <[email protected]>; LIPSKI, IVAN <[email protected]>; Hung, Alex
> <[email protected]>; Kaszewski, Dominik <[email protected]>;
> Kazlauskas, Nicholas <[email protected]>
> Subject: Re: [PATCH 06/16] drm/amd/display: Fix and reenable
> UPDATE_V3_FLOW_NEW_CONTEXT_MINIMAL
>
>
>
> On 06/01/2026 09:18, Melissa Wen wrote:
>> Hi,
>>
>> This change reintroduce some glitches/screen corruption on DCN321
>> with gamescope and a 4k@120Hz display, when transitioning from
>> multiple planes (primary + overlay, and pipe split) to single plane
>> (no pipe split).
>> We see small white artifacts near the cursor in its first appearance
>> on the screen after boot, and eventually a corrupted,colorful strip
>> appears in "fast" transitions between single plane -> multi-plane ->
>> single plane, for example, when moving the cursor (single plane),
>> click on the Steam menu (multi planes) and moving the cursor just
>> after (single plane).
>>
>> The problem was previously solved by commit 24ddca9a3af1
>> ("drm/amd/display: Defer transitions from minimal state to final
>> state") [1] and reintroduced again by this patch here, i.e., I don't
>> see the issue if I revert this commit here in current asdn.
>> Also, the issue isn't reproducible if you disable SubVP.
> Just to reinforce that the situation I describe here affects this issue in a 
> similar way:
> - https://gitlab.freedesktop.org/drm/amd/-/issues/3614
> ("[DCN32/7900XTX] when VRR is active + an overlay plane is in use,
> using a hardware cursor in gamescope-session causes artifacts during
> transition out of scan-out")
>
> Melissa
>
>> [1] https://gitlab.freedesktop.org/agd5f/linux/-/commit/24ddca9a3af1
>>
>> Best Regards,
>>
>> Melissa
>>
>> On 16/12/2025 06:56, Chenyu Chen wrote:
>>> From: Dominik Kaszewski <[email protected]>
>>>
>>> [Why]
>>> Reenable new split implementation, previously partially reverted due
>>> to issues with ODM on high-bandwidth displays 4k144Hz, resulting in
>>> a corrupted gray screen.
>>>
>>> Minimal flows require two separate commits, with extra intermediate
>>> commit to enable seamless transitions, each followed by a swap.
>>> Since new design requires commit to be run in execute and swap in
>>> cleanup stage, an attempt was made to reorder them from CSCS
>>> (Commit-Swap-Commit-Swap)
>>> to CCSS (Commit-Commit-Swap-Swap). Not only is this not viable, but
>>> was implemented incorrectly as CCS, one swap missing.
>>>
>>> [How]
>>> * Change UPDATE_V3_FLOW_NEW_CONTEXT_MINIMAL_NEW/CURRENT to execute
>>> and cleanup one commit, then run
>>> UPDATE_V3_FLOW_NEW_CONTEXT_SEAMLESS,
>>> which closely matches old implementation where minimal flows fall
>>> back to seamless.
>>> * Fix uninitialized variable error.
>>>
>>> Reviewed-by: Nicholas Kazlauskas <[email protected]>
>>> Signed-off-by: Dominik Kaszewski <[email protected]>
>>> Signed-off-by: Chenyu Chen <[email protected]>
>>> ---
>>>    drivers/gpu/drm/amd/display/dc/core/dc.c | 80
>>> ++++++++++++------------
>>>    1 file changed, 39 insertions(+), 41 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c
>>> b/drivers/gpu/drm/amd/display/dc/core/dc.c
>>> index 1be5c1c15798..57f6a4c8afff 100644
>>> --- a/drivers/gpu/drm/amd/display/dc/core/dc.c
>>> +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
>>> @@ -784,7 +784,7 @@ bool dc_stream_get_crc(struct dc *dc, struct
>>> dc_stream_state *stream, uint8_t id
>>>                   uint32_t *r_cr, uint32_t *g_y, uint32_t *b_cb)
>>>    {
>>>        int i;
>>> -    struct pipe_ctx *pipe;
>>> +    struct pipe_ctx *pipe = NULL;
>>>        struct timing_generator *tg;
>>>          dc_exit_ips_for_hw_access(dc); @@ -5437,35 +5437,23 @@ bool
>>> dc_update_planes_and_stream(struct dc *dc,
>>>            struct dc_stream_state *stream,
>>>            struct dc_stream_update *stream_update)
>>>    {
>>> -    bool ret = false;
>>> +    struct dc_update_scratch_space *scratch =
>>> dc_update_planes_and_stream_init(
>>> +            dc,
>>> +            srf_updates,
>>> +            surface_count,
>>> +            stream,
>>> +            stream_update
>>> +    );
>>> +    bool more = true;
>>>    -    dc_exit_ips_for_hw_access(dc);
>>> -    /*
>>> -     * update planes and stream version 3 separates FULL and FAST
>>> updates
>>> -     * to their own sequences. It aims to clean up frequent checks
>>> for
>>> -     * update type resulting unnecessary branching in logic flow. It
>>> also
>>> -     * adds a new commit minimal transition sequence, which detects
>>> the need
>>> -     * for minimal transition based on the actual comparison of
>>> current and
>>> -     * new states instead of "predicting" it based on per feature
>>> software
>>> -     * policy.i.e could_mpcc_tree_change_for_active_pipes. The new
>>> commit
>>> -     * minimal transition sequence is made universal to any power
>>> saving
>>> -     * features that would use extra free pipes such as Dynamic
>>> ODM/MPC
>>> -     * Combine, MPO or SubVp. Therefore there is no longer a need to
>>> -     * specially handle compatibility problems with transitions
>>> among those
>>> -     * features as they are now transparent to the new sequence.
>>> -     */
>>> -    if (dc->ctx->dce_version >= DCN_VERSION_4_01 ||
>>> dc->ctx->dce_version == DCN_VERSION_3_2 ||
>>> -            dc->ctx->dce_version == DCN_VERSION_3_21)
>>> -        ret = update_planes_and_stream_v3(dc, srf_updates,
>>> -                surface_count, stream, stream_update);
>>> -    else
>>> -        ret = update_planes_and_stream_v2(dc, srf_updates,
>>> -            surface_count, stream, stream_update);
>>> -    if (ret && (dc->ctx->dce_version >= DCN_VERSION_3_2 ||
>>> -        dc->ctx->dce_version == DCN_VERSION_3_01))
>>> -        clear_update_flags(srf_updates, surface_count, stream);
>>> +    while (more) {
>>> +        if (!dc_update_planes_and_stream_prepare(scratch))
>>> +            return false;
>>>    -    return ret;
>>> +        dc_update_planes_and_stream_execute(scratch);
>>> +        more = dc_update_planes_and_stream_cleanup(scratch);
>>> +    }
>>> +    return true;
>>>    }
>>>      void dc_commit_updates_for_stream(struct dc *dc, @@ -7241,7
>>> +7229,7 @@ static bool update_planes_and_stream_cleanup_v2(
>>>        return false;
>>>    }
>>>    -static void update_planes_and_stream_cleanup_v3_intermediate(
>>> +static void update_planes_and_stream_cleanup_v3_release_minimal(
>>>            struct dc_update_scratch_space *scratch,
>>>            bool backup
>>>    );
>>> @@ -7262,6 +7250,10 @@ static bool
>>> update_planes_and_stream_prepare_v3(
>>>            struct dc_update_scratch_space *scratch
>>>    )
>>>    {
>>> +    if (scratch->flow == UPDATE_V3_FLOW_NEW_CONTEXT_SEAMLESS) {
>>> +        return true;
>>> +    }
>>> +    ASSERT(scratch->flow == UPDATE_V3_FLOW_INVALID);
>>>        dc_exit_ips_for_hw_access(scratch->dc);
>>>          if (!update_planes_and_stream_state( @@ -7327,11 +7319,11
>>> @@ static bool update_planes_and_stream_prepare_v3(
>>>                return true;
>>>            }
>>>    - update_planes_and_stream_cleanup_v3_intermediate(scratch,
>>> false);
>>> + update_planes_and_stream_cleanup_v3_release_minimal(scratch,
>>> + false);
>>>        }
>>>    -
>>> restore_planes_and_stream_state(&scratch->dc->scratch.current_state,
>>> scratch->stream);
>>>        scratch->backup_context = scratch->dc->current_state;
>>> +
>>> restore_planes_and_stream_state(&scratch->dc->scratch.current_state,
>>> scratch->stream);
>>>        dc_state_retain(scratch->backup_context);
>>>        scratch->intermediate_context =
>>> create_minimal_transition_state(
>>>                scratch->dc,
>>> @@ -7347,7 +7339,7 @@ static bool
>>> update_planes_and_stream_prepare_v3(
>>>                return true;
>>>            }
>>>    - update_planes_and_stream_cleanup_v3_intermediate(scratch,
>>> true);
>>> + update_planes_and_stream_cleanup_v3_release_minimal(scratch,
>>> + true);
>>>        }
>>>          scratch->flow = UPDATE_V3_FLOW_INVALID; @@ -7398,12
>>> +7390,10 @@ static void update_planes_and_stream_execute_v3(
>>>          case UPDATE_V3_FLOW_NEW_CONTEXT_MINIMAL_NEW:
>>>            update_planes_and_stream_execute_v3_commit(scratch,
>>> false, true);
>>> -        update_planes_and_stream_execute_v3_commit(scratch, false,
>>> false);
>>>            break;
>>>          case UPDATE_V3_FLOW_NEW_CONTEXT_MINIMAL_CURRENT:
>>>            update_planes_and_stream_execute_v3_commit(scratch, true,
>>> true);
>>> -        update_planes_and_stream_execute_v3_commit(scratch, false,
>>> false);
>>>            break;
>>>          case UPDATE_V3_FLOW_INVALID:
>>> @@ -7419,7 +7409,7 @@ static void
>>> update_planes_and_stream_cleanup_v3_new_context(
>>>        swap_and_release_current_context(scratch->dc,
>>> scratch->new_context, scratch->stream);
>>>    }
>>>    -static void update_planes_and_stream_cleanup_v3_intermediate(
>>> +static void update_planes_and_stream_cleanup_v3_release_minimal(
>>>            struct dc_update_scratch_space *scratch,
>>>            bool backup
>>>    )
>>> @@ -7432,6 +7422,16 @@ static void
>>> update_planes_and_stream_cleanup_v3_intermediate(
>>>        );
>>>    }
>>>    +static void update_planes_and_stream_cleanup_v3_intermediate(
>>> +        struct dc_update_scratch_space *scratch,
>>> +        bool backup
>>> +)
>>> +{
>>> +    swap_and_release_current_context(scratch->dc,
>>> scratch->intermediate_context, scratch->stream);
>>> +    dc_state_retain(scratch->dc->current_state);
>>> + update_planes_and_stream_cleanup_v3_release_minimal(scratch,
>>> +backup); }
>>> +
>>>    static bool update_planes_and_stream_cleanup_v3(
>>>            struct dc_update_scratch_space *scratch
>>>    )
>>> @@ -7448,17 +7448,15 @@ static bool
>>> update_planes_and_stream_cleanup_v3(
>>>          case UPDATE_V3_FLOW_NEW_CONTEXT_MINIMAL_NEW:
>>> update_planes_and_stream_cleanup_v3_intermediate(scratch, false);
>>> - update_planes_and_stream_cleanup_v3_new_context(scratch);
>>> -        break;
>>> +        scratch->flow = UPDATE_V3_FLOW_NEW_CONTEXT_SEAMLESS;
>>> +        return true;
>>>          case UPDATE_V3_FLOW_NEW_CONTEXT_MINIMAL_CURRENT:
>>> -        swap_and_release_current_context(scratch->dc,
>>> scratch->intermediate_context, scratch->stream);
>>> -        dc_state_retain(scratch->dc->current_state);
>>> update_planes_and_stream_cleanup_v3_intermediate(scratch, true);
>>>            dc_state_release(scratch->backup_context);
>>> restore_planes_and_stream_state(&scratch->dc->scratch.new_state,
>>> scratch->stream);
>>> - update_planes_and_stream_cleanup_v3_new_context(scratch);
>>> -        break;
>>> +        scratch->flow = UPDATE_V3_FLOW_NEW_CONTEXT_SEAMLESS;
>>> +        return true;
>>>          case UPDATE_V3_FLOW_INVALID:
>>>        default:

Reply via email to