[PATCH 2/2] Make alignment functions match the documentation

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


Alex Deucher gave me documentation for tiling alignment requirements; this
brings the DDX into line with the documentation for Evergreen and R600.

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 Mesa
to avoid misrendering, at which point I see CP lockups instead.

I'm therefore sending this, the kernel patch, and the Mesa 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/drmmode_display.c |   61 ++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 48 insertions(+), 13 deletions(-)

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index fcea59e..cb220fb 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -1099,13 +1099,21 @@ int drmmode_get_height_align(ScrnInfoPtr scrn, uint32_t tiling)
 	RADEONInfoPtr info = RADEONPTR(scrn);
 	int height_align = 1;
 
-	if (info->ChipFamily >= CHIP_FAMILY_R600) {
+	if (info->ChipFamily >= CHIP_FAMILY_CEDAR) {
+		/* Kernel uses bank height of 8, macro_tile_aspect of 1 */
 		if (tiling & RADEON_TILING_MACRO)
-			height_align =  info->num_channels * 8;
+			height_align = info->num_banks * 8 / 1 * 8;
 		else if (tiling & RADEON_TILING_MICRO)
 			height_align = 8;
 		else
+			height_align = 1;
+	} else if (info->ChipFamily >= CHIP_FAMILY_R600) {
+		if (tiling & RADEON_TILING_MACRO)
+			height_align =  info->num_channels * 8;
+		else if (tiling & RADEON_TILING_MICRO)
 			height_align = 8;
+		else
+			height_align = 1;
 	} else {
 		if (tiling)
 			height_align = 16;
@@ -1121,18 +1129,30 @@ int drmmode_get_pitch_align(ScrnInfoPtr scrn, int bpe, uint32_t tiling)
 	RADEONInfoPtr info = RADEONPTR(scrn);
 	int pitch_align = 1;
 
-	if (info->ChipFamily >= CHIP_FAMILY_R600) {
+	if (info->ChipFamily >= CHIP_FAMILY_CEDAR) {
+		/* Kernel uses bank_width of 8, macro_tile_aspect of 1 */
+		if (tiling & RADEON_TILING_MACRO)
+			pitch_align = info->num_channels * 8 * 1 * 8;
+		else if (tiling & RADEON_TILING_MICRO)
+			pitch_align = MAX(8, info->group_bytes / (8 * bpe));
+		else {
+			if (info->have_tiling_info)
+				/* linear aligned requirements */
+				pitch_align = MAX(64, info->group_bytes / bpe);
+			else
+				/* default to 512 elements if we don't know the real
+				 * group size otherwise the kernel may reject the CS
+				 * if the group sizes don't match as the pitch won't
+				 * be aligned properly.
+				 */
+				pitch_align = 512;
+		}
+	} else if (info->ChipFamily >= CHIP_FAMILY_R600) {
 		if (tiling & RADEON_TILING_MACRO) {
-			/* general surface requirements */
-			pitch_align = MAX(info->num_banks,
-					  (((info->group_bytes / 8) / bpe) * info->num_banks)) * 8;
-			/* further restrictions for scanout */
-			pitch_align = MAX(info->num_banks * 8, pitch_align);
+			pitch_align = MAX(info->num_banks * 8,
+					  ((info->group_bytes / 8) / bpe) * info->num_banks);
 		} else if (tiling & RADEON_TILING_MICRO) {
-			/* general surface requirements */
-			pitch_align = MAX(8, (info->group_bytes / (8 * bpe)));
-			/* further restrictions for scanout */
-			pitch_align = MAX(info->group_bytes / bpe, pitch_align);
+			pitch_align = MAX(8, info->group_bytes / (8 * bpe));
 		} else {
 			if (info->have_tiling_info)
 				/* linear aligned requirements */
@@ -1163,7 +1183,22 @@ int drmmode_get_base_align(ScrnInfoPtr scrn, int bpe, uint32_t tiling)
 	int height_align = drmmode_get_height_align(scrn, tiling);
 	int base_align = RADEON_GPU_PAGE_SIZE;
 
-	if (info->ChipFamily >= CHIP_FAMILY_R600) {
+	if (info->ChipFamily >= CHIP_FAMILY_CEDAR) {
+                /* Kernel always uses bank_width and bank_height of 8.
+		   Tile split size is between 1024 and 4096 - as it's used in a
+		   MIN expression, 4096 is safe */
+		if (tiling & RADEON_TILING_MACRO)
+			base_align = info->num_channels * info->num_banks * 8 * 8 * MIN(4096, 8 * 8 * bpe);
+		else if (info->have_tiling_info)
+			base_align = info->group_bytes;
+		else
+			/* default to 512 if we don't know the real
+			 * group size otherwise the kernel may reject the CS
+			 * if the group sizes don't match as the base won't
+			 * be aligned properly.
+			 */
+			base_align = 512;
+	} else if (info->ChipFamily >= CHIP_FAMILY_R600) {
 		if (tiling & RADEON_TILING_MACRO)
 			base_align = MAX(info->num_banks * info->num_channels * 8 * 8 * bpe,
 					 pixel_align * bpe * height_align);
-- 
1.7.6.4



More information about the xorg-driver-ati mailing list