[PATCH v2] drm/amd/display: Use oriented source size when checking cursor scaling

Vlad Zahorodnii vlad.zahorodnii at kde.org
Thu Dec 2 17:47:34 UTC 2021


On 12/2/21 16:54, Kazlauskas, Nicholas wrote:
> On 2021-12-02 7:52 a.m., Vlad Zahorodnii wrote:
>> dm_check_crtc_cursor() doesn't take into account plane transforms when
>> calculating plane scaling, this can result in false positives.
>>
>> For example, if there's an output with resolution 3840x2160 and the
>> output is rotated 90 degrees, CRTC_W and CRTC_H will be 3840 and 2160,
>> respectively, but SRC_W and SRC_H will be 2160 and 3840, respectively.
>>
>> Since the cursor plane usually has a square buffer attached to it, the
>> dm_check_crtc_cursor() will think that there's a scale factor mismatch
>> even though there isn't really.
>>
>> This fixes an issue where kwin fails to use hardware plane transforms.
>>
>> Changes since version 1:
>> - s/orientated/oriented/g
>>
>> Signed-off-by: Vlad Zahorodnii <vlad.zahorodnii at kde.org>
> 
> This looks correct to me. I guess it's also not modifying the actual 
> programming position, just the check to ensure that the cursor is going 
> to be unscaled in the correct orientation.
> 
> Would be good to have some IGT tests for these scaled cases to verify 
> atomic check pass/fail assumptions, but for now:

I'd be glad to add the tests, but I would need some assistance. Can we 
continue this conversation in the radeon irc channel (I'm zzag)?

> Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas at amd.com>
> 
> Regards,
> Nicholas Kazlauskas
> 
>> ---
>>   .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 35 ++++++++++++++-----
>>   1 file changed, 27 insertions(+), 8 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
>> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>> index a3c0f2e4f4c1..c009c668fbe2 100644
>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>> @@ -10736,6 +10736,24 @@ static int dm_update_plane_state(struct dc *dc,
>>       return ret;
>>   }
>> +static void dm_get_oriented_plane_size(struct drm_plane_state 
>> *plane_state,
>> +                       int *src_w, int *src_h)
>> +{
>> +    switch (plane_state->rotation & DRM_MODE_ROTATE_MASK) {
>> +    case DRM_MODE_ROTATE_90:
>> +    case DRM_MODE_ROTATE_270:
>> +        *src_w = plane_state->src_h >> 16;
>> +        *src_h = plane_state->src_w >> 16;
>> +        break;
>> +    case DRM_MODE_ROTATE_0:
>> +    case DRM_MODE_ROTATE_180:
>> +    default:
>> +        *src_w = plane_state->src_w >> 16;
>> +        *src_h = plane_state->src_h >> 16;
>> +        break;
>> +    }
>> +}
>> +
>>   static int dm_check_crtc_cursor(struct drm_atomic_state *state,
>>                   struct drm_crtc *crtc,
>>                   struct drm_crtc_state *new_crtc_state)
>> @@ -10744,6 +10762,8 @@ static int dm_check_crtc_cursor(struct 
>> drm_atomic_state *state,
>>       struct drm_plane_state *new_cursor_state, *new_underlying_state;
>>       int i;
>>       int cursor_scale_w, cursor_scale_h, underlying_scale_w, 
>> underlying_scale_h;
>> +    int cursor_src_w, cursor_src_h;
>> +    int underlying_src_w, underlying_src_h;
>>       /* On DCE and DCN there is no dedicated hardware cursor plane. 
>> We get a
>>        * cursor per pipe but it's going to inherit the scaling and
>> @@ -10755,10 +10775,9 @@ static int dm_check_crtc_cursor(struct 
>> drm_atomic_state *state,
>>           return 0;
>>       }
>> -    cursor_scale_w = new_cursor_state->crtc_w * 1000 /
>> -             (new_cursor_state->src_w >> 16);
>> -    cursor_scale_h = new_cursor_state->crtc_h * 1000 /
>> -             (new_cursor_state->src_h >> 16);
>> +    dm_get_oriented_plane_size(new_cursor_state, &cursor_src_w, 
>> &cursor_src_h);
>> +    cursor_scale_w = new_cursor_state->crtc_w * 1000 / cursor_src_w;
>> +    cursor_scale_h = new_cursor_state->crtc_h * 1000 / cursor_src_h;
>>       for_each_new_plane_in_state_reverse(state, underlying, 
>> new_underlying_state, i) {
>>           /* Narrow down to non-cursor planes on the same CRTC as the 
>> cursor */
>> @@ -10769,10 +10788,10 @@ static int dm_check_crtc_cursor(struct 
>> drm_atomic_state *state,
>>           if (!new_underlying_state->fb)
>>               continue;
>> -        underlying_scale_w = new_underlying_state->crtc_w * 1000 /
>> -                     (new_underlying_state->src_w >> 16);
>> -        underlying_scale_h = new_underlying_state->crtc_h * 1000 /
>> -                     (new_underlying_state->src_h >> 16);
>> +        dm_get_oriented_plane_size(new_underlying_state,
>> +                       &underlying_src_w, &underlying_src_h);
>> +        underlying_scale_w = new_underlying_state->crtc_w * 1000 / 
>> underlying_src_w;
>> +        underlying_scale_h = new_underlying_state->crtc_h * 1000 / 
>> underlying_src_h;
>>           if (cursor_scale_w != underlying_scale_w ||
>>               cursor_scale_h != underlying_scale_h) {
>>
> 



More information about the amd-gfx mailing list