On Thu, 2019-12-19 at 01:34 +0200, Imre Deak wrote: > From: Dhinakaran Pandiyan <dhinakaran.pandiyan@xxxxxxxxx> > > During framebuffer creation, we pre-compute offsets for 90/270 plane > rotation. However, only Y and Yf modifiers support 90/270 rotation. > So, > skip the calculations for other modifiers. > > To keep the gem buffer size check still working for tiled planes, > factor > out the logic needed for rotation setup and skip only this part for > tiled planes other than Y/Yf. > > v2: Add a bounds check WARN for the rotation info array. > v3: Keep the gem buffer size check working for tiled planes. > > Cc: Matt Roper <matthew.d.roper@xxxxxxxxx> > Cc: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> > Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandiyan@xxxxxxxxx> > Signed-off-by: Imre Deak <imre.deak@xxxxxxxxx> Reviewed-by: Mika Kahola <mika.kahola@xxxxxxxxx> > --- > drivers/gpu/drm/i915/display/intel_display.c | 117 ++++++++++++----- > -- > 1 file changed, 76 insertions(+), 41 deletions(-) > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c > b/drivers/gpu/drm/i915/display/intel_display.c > index 3180c1817b60..9c0f22410c4a 100644 > --- a/drivers/gpu/drm/i915/display/intel_display.c > +++ b/drivers/gpu/drm/i915/display/intel_display.c > @@ -2863,12 +2863,71 @@ intel_fb_check_ccs_xy(struct drm_framebuffer > *fb, int x, int y) > return 0; > } > > +/* > + * Setup the rotated view for an FB plane and return the size the > GTT mapping > + * requires for this view. > + */ > +static u32 > +setup_fb_rotation(int plane, const struct intel_remapped_plane_info > *plane_info, > + u32 gtt_offset_rotated, int x, int y, > + unsigned int width, unsigned int height, > + unsigned int tile_size, > + unsigned int tile_width, unsigned int tile_height, > + struct drm_framebuffer *fb) > +{ > + struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); > + struct intel_rotation_info *rot_info = &intel_fb->rot_info; > + unsigned int pitch_tiles; > + struct drm_rect r; > + > + if (fb->modifier != I915_FORMAT_MOD_Y_TILED && > + fb->modifier != I915_FORMAT_MOD_Yf_TILED) > + return 0; > + > + if (WARN_ON(plane >= ARRAY_SIZE(rot_info->plane))) > + return 0; > + > + rot_info->plane[plane] = *plane_info; > + > + intel_fb->rotated[plane].pitch = plane_info->height * > tile_height; > + > + /* rotate the x/y offsets to match the GTT view */ > + drm_rect_init(&r, x, y, width, height); > + drm_rect_rotate(&r, > + plane_info->width * tile_width, > + plane_info->height * tile_height, > + DRM_MODE_ROTATE_270); > + x = r.x1; > + y = r.y1; > + > + /* rotate the tile dimensions to match the GTT view */ > + pitch_tiles = intel_fb->rotated[plane].pitch / tile_height; > + swap(tile_width, tile_height); > + > + /* > + * We only keep the x/y offsets, so push all of the > + * gtt offset into the x/y offsets. > + */ > + intel_adjust_tile_offset(&x, &y, > + tile_width, tile_height, > + tile_size, pitch_tiles, > + gtt_offset_rotated * tile_size, 0); > + > + /* > + * First pixel of the framebuffer from > + * the start of the rotated gtt mapping. > + */ > + intel_fb->rotated[plane].x = x; > + intel_fb->rotated[plane].y = y; > + > + return plane_info->width * plane_info->height; > +} > + > static int > intel_fill_fb_info(struct drm_i915_private *dev_priv, > struct drm_framebuffer *fb) > { > struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); > - struct intel_rotation_info *rot_info = &intel_fb->rot_info; > struct drm_i915_gem_object *obj = intel_fb_obj(fb); > u32 gtt_offset_rotated = 0; > unsigned int max_size = 0; > @@ -2926,23 +2985,21 @@ intel_fill_fb_info(struct drm_i915_private > *dev_priv, > tile_size); > offset /= tile_size; > > + /* Y or Yf modifiers required for 90/270 rotation */ > if (!is_surface_linear(fb, i)) { > + struct intel_remapped_plane_info plane_info; > unsigned int tile_width, tile_height; > - unsigned int pitch_tiles; > - struct drm_rect r; > > intel_tile_dims(fb, i, &tile_width, > &tile_height); > > - rot_info->plane[i].offset = offset; > - rot_info->plane[i].stride = DIV_ROUND_UP(fb- > >pitches[i], tile_width * cpp); > - rot_info->plane[i].width = DIV_ROUND_UP(x + > width, tile_width); > - rot_info->plane[i].height = DIV_ROUND_UP(y + > height, tile_height); > - > - intel_fb->rotated[i].pitch = > - rot_info->plane[i].height * > tile_height; > + plane_info.offset = offset; > + plane_info.stride = DIV_ROUND_UP(fb- > >pitches[i], > + tile_width * > cpp); > + plane_info.width = DIV_ROUND_UP(x + width, > tile_width); > + plane_info.height = DIV_ROUND_UP(y + height, > tile_height); > > /* how many tiles does this plane need */ > - size = rot_info->plane[i].stride * rot_info- > >plane[i].height; > + size = plane_info.stride * plane_info.height; > /* > * If the plane isn't horizontally tile > aligned, > * we need one more tile. > @@ -2950,36 +3007,13 @@ intel_fill_fb_info(struct drm_i915_private > *dev_priv, > if (x != 0) > size++; > > - /* rotate the x/y offsets to match the GTT view > */ > - drm_rect_init(&r, x, y, width, height); > - drm_rect_rotate(&r, > - rot_info->plane[i].width * > tile_width, > - rot_info->plane[i].height * > tile_height, > - DRM_MODE_ROTATE_270); > - x = r.x1; > - y = r.y1; > - > - /* rotate the tile dimensions to match the GTT > view */ > - pitch_tiles = intel_fb->rotated[i].pitch / > tile_height; > - swap(tile_width, tile_height); > - > - /* > - * We only keep the x/y offsets, so push all of > the > - * gtt offset into the x/y offsets. > - */ > - intel_adjust_tile_offset(&x, &y, > - tile_width, > tile_height, > - tile_size, > pitch_tiles, > - gtt_offset_rotated * > tile_size, 0); > - > - gtt_offset_rotated += rot_info->plane[i].width > * rot_info->plane[i].height; > - > - /* > - * First pixel of the framebuffer from > - * the start of the rotated gtt mapping. > - */ > - intel_fb->rotated[i].x = x; > - intel_fb->rotated[i].y = y; > + gtt_offset_rotated += > + setup_fb_rotation(i, &plane_info, > + gtt_offset_rotated, > + x, y, width, height, > + tile_size, > + tile_width, > tile_height, > + fb); > } else { > size = DIV_ROUND_UP((y + height) * fb- > >pitches[i] + > x * cpp, tile_size); > @@ -3063,6 +3097,7 @@ intel_plane_remap_gtt(struct intel_plane_state > *plane_state) > DRM_MODE_ROTATE_0 > , tile_size); > offset /= tile_size; > > + WARN_ON(i >= ARRAY_SIZE(info->plane)); > info->plane[i].offset = offset; > info->plane[i].stride = DIV_ROUND_UP(fb->pitches[i], > tile_width * cpp); _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx