On Wed, Oct 21, 2015 at 01:22:43PM +0200, Daniel Vetter wrote: > On Wed, Oct 14, 2015 at 07:29:02PM +0300, ville.syrjala@xxxxxxxxxxxxxxx wrote: > > From: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> > > > > 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. > > > > Signed-off-by: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> > > --- > > drivers/gpu/drm/i915/intel_display.c | 51 ++++++++++++++++++++++++++++++++---- > > 1 file changed, 46 insertions(+), 5 deletions(-) > > > > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c > > index 5f3abce..85e1473 100644 > > --- a/drivers/gpu/drm/i915/intel_display.c > > +++ b/drivers/gpu/drm/i915/intel_display.c > > @@ -2479,6 +2479,39 @@ static void intel_rotate_tile_dims(unsigned int *tile_width, > > } > > > > /* > > + * Adjust the page 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. > > + * intel_rotate_tile_dims() gives exactly that. > > + */ > > +static void intel_adjust_page_offset(int *x, int *y, > > + unsigned int tile_width, > > + unsigned int tile_height, > > + unsigned int tile_size, > > + unsigned int pitch, > > + unsigned int old_offset, > > + unsigned int 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; > > + if (tiles == 0) > > + return; > > + > > + /* pitch in tiles */ > > + pitch /= tile_width; > > Isn't tile_width here now in pixels and no longer in bytes? And we need > bytes here I think, i.e. tile_pitch. > > > + > > + *y += tiles / pitch * tile_height; > > + *x += tiles % pitch * tile_width; > > But here we need tile_width in pixels. I'm confused. Looking harder I realized that you also adjust the pitch in the rotation patch. Imo that's pulling a few too many tricks, we really need to clear up tile_width (imo pixels) vs. tile_pitch (imo bytes) vs. pitch (always in pixels). But that can be done later on. > > +} > > + > > +/* > > * Computes the linear offset to the base tile and adjusts > > * x, y. bytes per pixel is assumed to be a power-of-two. > > * > > @@ -2493,6 +2526,12 @@ unsigned long intel_compute_page_offset(struct drm_i915_private *dev_priv, > > unsigned int pitch, > > unsigned int rotation) > > { > > + unsigned int offset, 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; > > @@ -2510,16 +2549,18 @@ unsigned long intel_compute_page_offset(struct drm_i915_private *dev_priv, > > tiles = *x / tile_width; > > *x %= tile_width; > > > > - return (tile_rows * (pitch / tile_width) + tiles) * tile_size; > > - } else { > > - unsigned int alignment = intel_linear_alignment(dev_priv) - 1; > > - unsigned int offset; > > + offset = (tile_rows * (pitch / tile_width) + tiles) * tile_size; > > > > + intel_adjust_page_offset(x, y, tile_width, tile_height, > > + tile_size, pitch, > > + offset, offset & ~alignment); > > offset_aligned = ALIGN(offset, alignment); instead of open-coding it. So with myself unconfused, if you apply the ALIGN: Reviewed-by: Daniel Vetter <daniel.vetter@xxxxxxxx> -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx