xf86-video-ati: Branch 'master'

Alex Deucher agd5f at kemper.freedesktop.org
Wed Nov 17 14:34:12 PST 2010


 src/drmmode_display.c |   43 +++++++++++++++++++++++++++++++++----------
 src/drmmode_display.h |    1 +
 src/radeon_exa.c      |    7 ++++---
 src/radeon_kms.c      |   14 ++++++++++----
 4 files changed, 48 insertions(+), 17 deletions(-)

New commits:
commit 3455a3b58532ea3ad901a317126968ab6cbb21b7
Author: Alex Deucher <alexdeucher at gmail.com>
Date:   Wed Nov 17 17:32:41 2010 -0500

    radeon/kms: fix buffer base alignment for tiling
    
    On r6xx+, 2D tiling can require larger than 4k base alignment.

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 050dadd..3332472 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -262,7 +262,7 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
 	int i;
 	int fb_id;
 	drmModeModeInfo kmode;
-	int pitch = pScrn->displayWidth * info->CurrentLayout.pixel_bytes;
+	int pitch;
 	uint32_t tiling_flags = 0;
 	int height;
 
@@ -272,7 +272,8 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
 			tiling_flags |= RADEON_TILING_MACRO;
 	}
 
-	pitch = RADEON_ALIGN(pitch, drmmode_get_pitch_align(pScrn, info->CurrentLayout.pixel_bytes, tiling_flags));
+	pitch = RADEON_ALIGN(pScrn->displayWidth, drmmode_get_pitch_align(pScrn, info->CurrentLayout.pixel_bytes, tiling_flags)) *
+		info->CurrentLayout.pixel_bytes;
 	height = RADEON_ALIGN(pScrn->virtualY, drmmode_get_height_align(pScrn, tiling_flags));
 
 	if (drmmode->fb_id == 0) {
@@ -436,13 +437,15 @@ drmmode_crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height)
 	struct radeon_bo *rotate_bo;
 	int ret;
 	unsigned long rotate_pitch;
+	int base_align;
 
 	rotate_pitch =
-		RADEON_ALIGN(width * drmmode->cpp, drmmode_get_pitch_align(crtc->scrn, drmmode->cpp, 0));
+		RADEON_ALIGN(width, drmmode_get_pitch_align(crtc->scrn, drmmode->cpp, 0)) * drmmode->cpp;
 	height = RADEON_ALIGN(height, drmmode_get_height_align(crtc->scrn, 0));
+	base_align = drmmode_get_base_align(crtc->scrn, drmmode->cpp, 0);
 	size = RADEON_ALIGN(rotate_pitch * height, RADEON_GPU_PAGE_SIZE);
 
-	rotate_bo = radeon_bo_open(drmmode->bufmgr, 0, size, 0, RADEON_GEM_DOMAIN_VRAM, 0);
+	rotate_bo = radeon_bo_open(drmmode->bufmgr, 0, size, base_align, RADEON_GEM_DOMAIN_VRAM, 0);
 	if (rotate_bo == NULL)
 		return NULL;
 
@@ -1066,6 +1069,7 @@ drmmode_clones_init(ScrnInfoPtr scrn, drmmode_ptr drmmode)
 	}
 }
 
+/* returns height alignment in pixels */
 int drmmode_get_height_align(ScrnInfoPtr scrn, uint32_t tiling)
 {
 	RADEONInfoPtr info = RADEONPTR(scrn);
@@ -1087,6 +1091,7 @@ int drmmode_get_height_align(ScrnInfoPtr scrn, uint32_t tiling)
 	return height_align;
 }
 
+/* returns pitch alignment in pixels */
 int drmmode_get_pitch_align(ScrnInfoPtr scrn, int bpe, uint32_t tiling)
 {
 	RADEONInfoPtr info = RADEONPTR(scrn);
@@ -1094,21 +1099,39 @@ int drmmode_get_pitch_align(ScrnInfoPtr scrn, int bpe, uint32_t tiling)
 
 	if (info->ChipFamily >= CHIP_FAMILY_R600) {
 		if (tiling & RADEON_TILING_MACRO)
-		pitch_align = MAX(info->num_banks,
-				  (((info->group_bytes / 8) / bpe) * info->num_banks)) * 8 * bpe;
+			pitch_align = MAX(info->num_banks,
+					  (((info->group_bytes / 8) / bpe) * info->num_banks)) * 8;
 		else if (tiling & RADEON_TILING_MICRO)
-			pitch_align = MAX(8, (info->group_bytes / (8 * bpe))) * bpe;
+			pitch_align = MAX(8, (info->group_bytes / (8 * bpe)));
 		else
-			pitch_align = 256; /* 8 * bpe */
+			pitch_align = info->group_bytes / bpe;
 	} else {
 		if (tiling)
-			pitch_align = 256;
+			pitch_align = 256 / bpe;
 		else
 			pitch_align = 64;
 	}
 	return pitch_align;
 }
 
+/* returns base alignment in bytes */
+int drmmode_get_base_align(ScrnInfoPtr scrn, int bpe, uint32_t tiling)
+{
+	RADEONInfoPtr info = RADEONPTR(scrn);
+	int pixel_align = drmmode_get_pitch_align(scrn, bpe, tiling);
+	int height_align = drmmode_get_height_align(scrn, tiling);
+	int base_align = RADEON_GPU_PAGE_SIZE;
+
+	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);
+		else
+			base_align = info->group_bytes;
+	}
+	return base_align;
+}
+
 static Bool
 drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
 {
@@ -1144,7 +1167,7 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
 			tiling_flags |= RADEON_TILING_MACRO;
 	}
 
-	pitch = RADEON_ALIGN(width * cpp, drmmode_get_pitch_align(scrn, cpp, tiling_flags));
+	pitch = RADEON_ALIGN(width, drmmode_get_pitch_align(scrn, cpp, tiling_flags)) * cpp;
 	height = RADEON_ALIGN(height, drmmode_get_height_align(scrn, tiling_flags));
 	screen_size = RADEON_ALIGN(pitch * height, RADEON_GPU_PAGE_SIZE);
 
diff --git a/src/drmmode_display.h b/src/drmmode_display.h
index b972354..e6bfd50 100644
--- a/src/drmmode_display.h
+++ b/src/drmmode_display.h
@@ -97,6 +97,7 @@ extern void drmmode_uevent_fini(ScrnInfoPtr scrn, drmmode_ptr drmmode);
 
 extern int drmmode_get_height_align(ScrnInfoPtr scrn, uint32_t tiling);
 extern int drmmode_get_pitch_align(ScrnInfoPtr scrn, int bpe, uint32_t tiling);
+extern int drmmode_get_base_align(ScrnInfoPtr scrn, int bpe, uint32_t tiling);
 
 #endif
 
diff --git a/src/radeon_exa.c b/src/radeon_exa.c
index b62ff59..503d569 100644
--- a/src/radeon_exa.c
+++ b/src/radeon_exa.c
@@ -429,7 +429,7 @@ void *RADEONEXACreatePixmap2(ScreenPtr pScreen, int width, int height,
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
     RADEONInfoPtr info = RADEONPTR(pScrn);
     struct radeon_exa_pixmap_priv *new_priv;
-    int pitch;
+    int pitch, base_align;
     uint32_t size;
     uint32_t tiling = 0;
     int cpp = bitsPerPixel / 8;
@@ -462,7 +462,8 @@ void *RADEONEXACreatePixmap2(ScreenPtr pScreen, int width, int height,
     }
 
     height = RADEON_ALIGN(height, drmmode_get_height_align(pScrn, tiling));
-    pitch = RADEON_ALIGN(width * cpp, drmmode_get_pitch_align(pScrn, cpp, tiling));
+    pitch = RADEON_ALIGN(width, drmmode_get_pitch_align(pScrn, cpp, tiling)) * cpp;
+    base_align = drmmode_get_base_align(pScrn, cpp, tiling);
     size = RADEON_ALIGN(height * pitch, RADEON_GPU_PAGE_SIZE);
 
     new_priv = calloc(1, sizeof(struct radeon_exa_pixmap_priv));
@@ -474,7 +475,7 @@ void *RADEONEXACreatePixmap2(ScreenPtr pScreen, int width, int height,
 
     *new_pitch = pitch;
 
-    new_priv->bo = radeon_bo_open(info->bufmgr, 0, size, 0,
+    new_priv->bo = radeon_bo_open(info->bufmgr, 0, size, base_align,
 				  RADEON_GEM_DOMAIN_VRAM, 0);
     if (!new_priv->bo) {
 	free(new_priv);
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
index 642e491..0cd419f 100644
--- a/src/radeon_kms.c
+++ b/src/radeon_kms.c
@@ -603,6 +603,11 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags)
                          info->ChipFamily <= CHIP_FAMILY_RS740;
 
     if (info->ChipFamily >= CHIP_FAMILY_R600) {
+	/* set default group bytes, overriden by kernel info below */
+	if (info->ChipFamily >= CHIP_FAMILY_CEDAR)
+	    info->group_bytes = 512;
+	else
+	    info->group_bytes = 256;
 	if (info->dri->pKernelDRMVersion->version_minor >= 6) {
 	    info->allowColorTiling = xf86ReturnOptValBool(info->Options,
 							  OPTION_COLOR_TILING, colorTilingDefault);
@@ -681,7 +686,7 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags)
     }
     cpp = pScrn->bitsPerPixel / 8;
     pScrn->displayWidth =
-	RADEON_ALIGN(pScrn->virtualX * cpp, drmmode_get_pitch_align(pScrn, cpp, tiling)) / cpp;
+	RADEON_ALIGN(pScrn->virtualX, drmmode_get_pitch_align(pScrn, cpp, tiling));
     info->CurrentLayout.displayWidth = pScrn->displayWidth;
 
     /* Set display resolution */
@@ -1099,7 +1104,7 @@ static Bool radeon_setup_kernel_mem(ScreenPtr pScreen)
     xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
     int cpp = info->CurrentLayout.pixel_bytes;
     int screen_size;
-    int pitch;
+    int pitch, base_align;
     int total_size_bytes = 0, remain_size_bytes;
     uint32_t tiling_flags = 0;
 
@@ -1118,8 +1123,9 @@ static Bool radeon_setup_kernel_mem(ScreenPtr pScreen)
 	if (info->ChipFamily < CHIP_FAMILY_R600)
 	    tiling_flags |= RADEON_TILING_MACRO;
     }
-    pitch = RADEON_ALIGN(pScrn->displayWidth * cpp, drmmode_get_pitch_align(pScrn, cpp, tiling_flags));
+    pitch = RADEON_ALIGN(pScrn->displayWidth, drmmode_get_pitch_align(pScrn, cpp, tiling_flags)) * cpp;
     screen_size = RADEON_ALIGN(pScrn->virtualY, drmmode_get_height_align(pScrn, tiling_flags)) * pitch;
+    base_align = drmmode_get_base_align(pScrn, cpp, tiling_flags);
     {
 	int cursor_size = 64 * 4 * 64;
 	int c;
@@ -1161,7 +1167,7 @@ static Bool radeon_setup_kernel_mem(ScreenPtr pScreen)
 
     if (info->front_bo == NULL) {
         info->front_bo = radeon_bo_open(info->bufmgr, 0, screen_size,
-                                        0, RADEON_GEM_DOMAIN_VRAM, 0);
+                                        base_align, RADEON_GEM_DOMAIN_VRAM, 0);
         if (info->r600_shadow_fb == TRUE) {
             if (radeon_bo_map(info->front_bo, 1)) {
                 ErrorF("Failed to map cursor buffer memory\n");


More information about the xorg-commit mailing list