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

Alex Deucher alexdeucher at gmail.com
Thu Dec 2 17:11:19 UTC 2021


Applied.  thanks!

Alex

On Thu, Dec 2, 2021 at 10:09 AM Kazlauskas, Nicholas
<nicholas.kazlauskas at amd.com> 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:
>
> 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