[Intel-gfx] [PATCH 10/22] drm/i915: Support for extra alignment for tiled surfaces

ville.syrjala at linux.intel.com ville.syrjala at linux.intel.com
Wed Oct 14 09:29:02 PDT 2015


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.

Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
---
 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;
+
+	*y += tiles / pitch * tile_height;
+	*x += tiles % pitch * tile_width;
+}
+
+/*
  * 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);
+	} else {
 		offset = *y * pitch + *x * cpp;
 		*y = (offset & alignment) / pitch;
 		*x = ((offset & alignment) - *y * pitch) / cpp;
-		return offset & ~alignment;
 	}
+
+	return offset & ~alignment;
 }
 
 static int i9xx_format_to_fourcc(int format)
-- 
2.4.9



More information about the Intel-gfx mailing list