[Mesa-dev] [PATCH] r600g: Fix tiling alignment to match docs

Simon Farnsworth simon.farnsworth at onelan.co.uk
Tue Dec 13 07:51:26 PST 2011


R600 and Evergreen have different tiling requirements. Fix Mesa to match the
documented requirements.

Signed-off-by: Simon Farnsworth <simon.farnsworth at onelan.co.uk>
---

This doesn't fix my problems with enabling macro tiling, but it does help
somewhat. I also need to fix tile shape in the kernel and alignment in the
DDX to avoid misrendering, at which point I see CP lockups instead.

I'm therefore sending this, the DDX patch, and the kernel patch out in order
to avoid getting stuck in a world where I have an 80% fix, someone else has
an 80% fix, and if only we talked, we'd have a 100% fix.

 src/gallium/drivers/r600/evergreen_state.c |    2 +-
 src/gallium/drivers/r600/r600_texture.c    |  140 ++++++++++++++++++++--------
 2 files changed, 103 insertions(+), 39 deletions(-)

diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c
index d0c02d5..d6b97da 100644
--- a/src/gallium/drivers/r600/evergreen_state.c
+++ b/src/gallium/drivers/r600/evergreen_state.c
@@ -1447,7 +1447,7 @@ static void evergreen_cb(struct r600_pipe_context *rctx, struct r600_pipe_state
 				offset >> 8, 0xFFFFFFFF, &rtex->resource, RADEON_USAGE_READWRITE);
 	r600_pipe_state_add_reg(rstate,
 				R_028C78_CB_COLOR0_DIM + cb * 0x3C,
-				0x0, 0xFFFFFFFF, NULL, 0);
+				S_028C78_WIDTH_MAX(surf->base.width) | S_028C78_HEIGHT_MAX(surf->base.height), 0xFFFFFFFF, NULL, 0);
 	r600_pipe_state_add_reg(rstate,
 				R_028C70_CB_COLOR0_INFO + cb * 0x3C,
 				color_info, 0xFFFFFFFF, &rtex->resource, RADEON_USAGE_READWRITE);
diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c
index 6143133..16ffe23 100644
--- a/src/gallium/drivers/r600/r600_texture.c
+++ b/src/gallium/drivers/r600/r600_texture.c
@@ -88,23 +88,42 @@ static unsigned r600_get_block_alignment(struct pipe_screen *screen,
 	unsigned pixsize = util_format_get_blocksize(format);
 	int p_align;
 
-	switch(array_mode) {
-	case V_038000_ARRAY_2D_TILED_THIN1:
-		p_align = MAX2(rscreen->tiling_info.num_banks,
-			       (((rscreen->tiling_info.group_bytes / 8) / pixsize) * rscreen->tiling_info.num_banks)) * 8;
-		/* further restrictions for scanout */
-		p_align = MAX2(rscreen->tiling_info.num_banks * 8, p_align);
-		break;
-	case V_038000_ARRAY_1D_TILED_THIN1:
-		p_align = MAX2(8, (rscreen->tiling_info.group_bytes / (8 * pixsize)));
-		/* further restrictions for scanout */
-		p_align = MAX2((rscreen->tiling_info.group_bytes / pixsize), p_align);
-		break;
-	case V_038000_ARRAY_LINEAR_ALIGNED:
-	case V_038000_ARRAY_LINEAR_GENERAL:
-	default:
-		p_align = MAX2(64, rscreen->tiling_info.group_bytes / pixsize);
-		break;
+	if (rscreen->chip_class >= EVERGREEN)
+	{
+		switch(array_mode) {
+		case V_038000_ARRAY_2D_TILED_THIN1:
+			/* Kernel uses bank width of 8, macro tile aspect of 1 */
+			p_align = rscreen->tiling_info.num_channels * 8 * 1 * 8;
+			break;
+		case V_038000_ARRAY_1D_TILED_THIN1:
+			p_align = MAX2(8, rscreen->tiling_info.group_bytes /
+				       (8 * 1 * pixsize * 1));
+			break;
+		case V_038000_ARRAY_LINEAR_ALIGNED:
+			p_align = MAX2(64, rscreen->tiling_info.group_bytes / pixsize);
+			break;
+		case V_038000_ARRAY_LINEAR_GENERAL:
+		default:
+			p_align = 8;
+		}
+	}
+	else
+	{
+		switch(array_mode) {
+		case V_038000_ARRAY_2D_TILED_THIN1:
+			p_align = MAX2(rscreen->tiling_info.num_banks * 8,
+				       ((rscreen->tiling_info.group_bytes / 8) / pixsize) * rscreen->tiling_info.num_banks);
+			break;
+		case V_038000_ARRAY_1D_TILED_THIN1:
+			p_align = MAX2(8, (rscreen->tiling_info.group_bytes / (8 * pixsize)));
+			break;
+		case V_038000_ARRAY_LINEAR_ALIGNED:
+			p_align = MAX2(64, rscreen->tiling_info.group_bytes / pixsize);
+			break;
+		case V_038000_ARRAY_LINEAR_GENERAL:
+		default:
+			p_align = 1;
+		}
 	}
 	return p_align;
 }
@@ -115,16 +134,36 @@ static unsigned r600_get_height_alignment(struct pipe_screen *screen,
 	struct r600_screen* rscreen = (struct r600_screen *)screen;
 	int h_align;
 
-	switch (array_mode) {
-	case V_038000_ARRAY_2D_TILED_THIN1:
-		h_align = rscreen->tiling_info.num_channels * 8;
-		break;
-	case V_038000_ARRAY_1D_TILED_THIN1:
-	case V_038000_ARRAY_LINEAR_ALIGNED:
-	case V_038000_ARRAY_LINEAR_GENERAL:
-	default:
-		h_align = 8;
-		break;
+	if (rscreen->chip_class >= EVERGREEN)
+	{
+		switch(array_mode) {
+		case V_038000_ARRAY_2D_TILED_THIN1:
+			/* Kernel uses bank_height of 8, macro_tile_aspect of 1 */
+			h_align = rscreen->tiling_info.num_banks * 8 / 1 * 8;
+			break;
+		case V_038000_ARRAY_1D_TILED_THIN1:
+			h_align = 8;
+			break;
+		case V_038000_ARRAY_LINEAR_ALIGNED:
+		case V_038000_ARRAY_LINEAR_GENERAL:
+		default:
+			h_align = 1;
+		}
+	}
+	else
+	{
+		switch(array_mode) {
+		case V_038000_ARRAY_2D_TILED_THIN1:
+			h_align = rscreen->tiling_info.num_channels * 8;
+			break;
+		case V_038000_ARRAY_1D_TILED_THIN1:
+			h_align = 8;
+			break;
+		case V_038000_ARRAY_LINEAR_ALIGNED:
+		case V_038000_ARRAY_LINEAR_GENERAL:
+		default:
+			h_align = 1;
+		}
 	}
 	return h_align;
 }
@@ -139,17 +178,42 @@ static unsigned r600_get_base_alignment(struct pipe_screen *screen,
 	int h_align = r600_get_height_alignment(screen, array_mode);
 	int b_align;
 
-	switch (array_mode) {
-	case V_038000_ARRAY_2D_TILED_THIN1:
-		b_align = MAX2(rscreen->tiling_info.num_banks * rscreen->tiling_info.num_channels * 8 * 8 * pixsize,
-			       p_align * pixsize * h_align);
-		break;
-	case V_038000_ARRAY_1D_TILED_THIN1:
-	case V_038000_ARRAY_LINEAR_ALIGNED:
-	case V_038000_ARRAY_LINEAR_GENERAL:
-	default:
-		b_align = rscreen->tiling_info.group_bytes;
-		break;
+	if (rscreen->chip_class >= EVERGREEN)
+	{
+		switch(array_mode) {
+		case V_038000_ARRAY_2D_TILED_THIN1:
+			/* Kernel always uses bank_width and bank_height of 8.
+			   Tile split size is between 1024 and 4096 -
+			   assumption of 4096 is safe due to MIN */
+			b_align = rscreen->tiling_info.num_channels *
+				  rscreen->tiling_info.num_banks * 8 * 8 *
+				  MIN2(4096, 8 * 8 * pixsize * 1);
+			break;
+		case V_038000_ARRAY_1D_TILED_THIN1:
+		case V_038000_ARRAY_LINEAR_ALIGNED:
+			b_align = rscreen->tiling_info.group_bytes;
+		case V_038000_ARRAY_LINEAR_GENERAL:
+		default:
+			b_align = pixsize;
+			break;
+		}
+	}
+	else
+	{
+		switch(array_mode) {
+		case V_038000_ARRAY_2D_TILED_THIN1:
+			b_align = MAX2(rscreen->tiling_info.num_banks * rscreen->tiling_info.num_channels
+				       * 8 * 8 * pixsize,
+				       p_align * pixsize * h_align);
+			break;
+		case V_038000_ARRAY_1D_TILED_THIN1:
+			b_align = rscreen->tiling_info.group_bytes;
+			break;
+		case V_038000_ARRAY_LINEAR_ALIGNED:
+		case V_038000_ARRAY_LINEAR_GENERAL:
+		default:
+			b_align = 1;
+		}
 	}
 	return b_align;
 }
-- 
1.7.6.4



More information about the mesa-dev mailing list