[Intel-gfx] [PATCH v2 08/15] drm/i915: Skip rotated offset adjustment for unsupported modifiers

Kahola, Mika mika.kahola at intel.com
Thu Dec 19 13:31:49 UTC 2019


On Thu, 2019-12-19 at 01:34 +0200, Imre Deak wrote:
> From: Dhinakaran Pandiyan <dhinakaran.pandiyan at intel.com>
> 
> 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 at intel.com>
> Cc: Ville Syrjälä <ville.syrjala at linux.intel.com>
> Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandiyan at intel.com>
> Signed-off-by: Imre Deak <imre.deak at intel.com>

Reviewed-by: Mika Kahola <mika.kahola at intel.com>

> ---
>  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);


More information about the Intel-gfx mailing list