[Intel-gfx] [PATCH v3 04/21] drm/i915: Support for extra alignment for tiled surfaces

Daniel Vetter daniel at ffwll.ch
Tue Feb 16 16:26:53 UTC 2016


On Mon, Feb 15, 2016 at 10:54:42PM +0200, ville.syrjala at linux.intel.com wrote:
> From: Ville Syrjälä <ville.syrjala at linux.intel.com>
> 
> SKL+ needs >4K alignment for tiled surfaces, so make
> intel_compute_page_offset() handle it.
> 
> The way we do it is first we compute the closest tile boundary
> as before, and then figure out how many tiles we need to go
> to reach the desired alignment. The difference in the offset
> is then added into the x/y offsets.
> 
> v2: Be less confusing wrt. units (pixels vs. bytes) (Daniel)
> v3: Use u32 for offsets
>     Have intel_adjust_tile_offset() return the new offset (will be
>     useful later)
>     Add an offset_aligned variable (Daniel)
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>

Reviewed-by: Daniel Vetter <daniel.vetter at ffwll.ch>

> ---
>  drivers/gpu/drm/i915/intel_display.c | 50 ++++++++++++++++++++++++++++++++----
>  1 file changed, 45 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index dcf379c29523..fe8d534a3334 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -2461,6 +2461,35 @@ static void intel_unpin_fb_obj(struct drm_framebuffer *fb,
>  }
>  
>  /*
> + * Adjust the tile offset by moving the difference into
> + * the x/y offsets.
> + *
> + * Input tile dimensions and pitch must already be
> + * rotated to match x and y, and in pixel units.
> + */
> +static u32 intel_adjust_tile_offset(int *x, int *y,
> +				    unsigned int tile_width,
> +				    unsigned int tile_height,
> +				    unsigned int tile_size,
> +				    unsigned int pitch_tiles,
> +				    u32 old_offset,
> +				    u32 new_offset)
> +{
> +	unsigned int tiles;
> +
> +	WARN_ON(old_offset & (tile_size - 1));
> +	WARN_ON(new_offset & (tile_size - 1));
> +	WARN_ON(new_offset > old_offset);
> +
> +	tiles = (old_offset - new_offset) / tile_size;
> +
> +	*y += tiles / pitch_tiles * tile_height;
> +	*x += tiles % pitch_tiles * tile_width;
> +
> +	return new_offset;
> +}
> +
> +/*
>   * Computes the linear offset to the base tile and adjusts
>   * x, y. bytes per pixel is assumed to be a power-of-two.
>   *
> @@ -2475,6 +2504,12 @@ u32 intel_compute_tile_offset(struct drm_i915_private *dev_priv,
>  			      unsigned int pitch,
>  			      unsigned int rotation)
>  {
> +	u32 offset, offset_aligned, alignment;
> +
> +	alignment = intel_surf_alignment(dev_priv, fb_modifier);
> +	if (alignment)
> +		alignment--;
> +
>  	if (fb_modifier != DRM_FORMAT_MOD_NONE) {
>  		unsigned int tile_size, tile_width, tile_height;
>  		unsigned int tile_rows, tiles, pitch_tiles;
> @@ -2496,16 +2531,21 @@ u32 intel_compute_tile_offset(struct drm_i915_private *dev_priv,
>  		tiles = *x / tile_width;
>  		*x %= tile_width;
>  
> -		return (tile_rows * pitch_tiles + tiles) * tile_size;
> -	} else {
> -		unsigned int alignment = intel_linear_alignment(dev_priv) - 1;
> -		unsigned int offset;
> +		offset = (tile_rows * pitch_tiles + tiles) * tile_size;
> +		offset_aligned = offset & ~alignment;
>  
> +		intel_adjust_tile_offset(x, y, tile_width, tile_height,
> +					 tile_size, pitch_tiles,
> +					 offset, offset_aligned);
> +	} else {
>  		offset = *y * pitch + *x * cpp;
> +		offset_aligned = offset & ~alignment;
> +
>  		*y = (offset & alignment) / pitch;
>  		*x = ((offset & alignment) - *y * pitch) / cpp;
> -		return offset & ~alignment;
>  	}
> +
> +	return offset_aligned;
>  }
>  
>  static int i9xx_format_to_fourcc(int format)
> -- 
> 2.4.10
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


More information about the Intel-gfx mailing list