summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Deucher <alexdeucher@gmail.com>2010-10-27 12:37:42 -0400
committerAlex Deucher <alexdeucher@gmail.com>2010-10-27 12:40:48 -0400
commitf07f9b7b61c05f2de1d61bb0e2f71bd017c8d36a (patch)
treef7091c76b5e6e7e08d9dcfffafa109847776a86c
parentd31046ba6c8eee9b7decc3875697d37c38bc38f3 (diff)
kms/radeon: unify fb bo alignment handling
Previously there were 3 different paths with what should have had duplicated code: - EXACreatePixmap2 - Initial front buffer creation - Randr resize This patch attempts to unify the alignment across all 3. This may fix tiling issues in some cases and should make buffer pitches match for pageflipping.
-rw-r--r--src/drmmode_display.c59
-rw-r--r--src/drmmode_display.h3
-rw-r--r--src/radeon_exa.c28
-rw-r--r--src/radeon_kms.c18
4 files changed, 68 insertions, 40 deletions
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index cbbfa50c..9644e734 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -1055,6 +1055,49 @@ drmmode_clones_init(ScrnInfoPtr scrn, drmmode_ptr drmmode)
}
}
+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 (tiling & RADEON_TILING_MACRO)
+ height_align = info->num_channels * 8;
+ else if (tiling & RADEON_TILING_MICRO)
+ height_align = 8;
+ else
+ height_align = 8;
+ } else {
+ if (tiling)
+ height_align = 16;
+ else
+ height_align = 1;
+ }
+ return height_align;
+}
+
+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 (tiling & RADEON_TILING_MACRO)
+ pitch_align = MAX(info->num_banks,
+ (((info->group_bytes / 8) / bpe) * info->num_banks)) * 8 * bpe;
+ else if (tiling & RADEON_TILING_MICRO)
+ pitch_align = MAX(8, (info->group_bytes / (8 * bpe))) * bpe;
+ else
+ pitch_align = 256; /* 8 * bpe */
+ } else {
+ if (tiling)
+ pitch_align = 256;
+ else
+ pitch_align = 64;
+ }
+ return pitch_align;
+}
+
static Bool
drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
{
@@ -1084,10 +1127,17 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
if (front_bo)
radeon_bo_wait(front_bo);
- pitch = RADEON_ALIGN(width, 64);
- height = RADEON_ALIGN(height, 16);
+ /* no tiled scanout on r6xx+ yet */
+ if (info->allowColorTiling) {
+ if (info->ChipFamily < CHIP_FAMILY_R600)
+ tiling_flags |= RADEON_TILING_MACRO;
+ }
+
+ 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 = pitch * height * cpp;
+ screen_size = RADEON_ALIGN(screen_size, RADEON_GPU_PAGE_SIZE);
xf86DrvMsg(scrn->scrnIndex, X_INFO,
"Allocate new frame buffer %dx%d stride %d\n",
@@ -1107,11 +1157,6 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
if (!info->front_bo)
goto fail;
- /* no tiled scanout on r6xx+ yet */
- if (info->allowColorTiling) {
- if (info->ChipFamily < CHIP_FAMILY_R600)
- tiling_flags |= RADEON_TILING_MACRO;
- }
#if X_BYTE_ORDER == X_BIG_ENDIAN
switch (cpp) {
case 4:
diff --git a/src/drmmode_display.h b/src/drmmode_display.h
index a9891b2d..b972354d 100644
--- a/src/drmmode_display.h
+++ b/src/drmmode_display.h
@@ -95,6 +95,9 @@ extern Bool drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn);
extern void drmmode_uevent_init(ScrnInfoPtr scrn, drmmode_ptr drmmode);
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);
+
#endif
#endif
diff --git a/src/radeon_exa.c b/src/radeon_exa.c
index d9301d8a..99ad8437 100644
--- a/src/radeon_exa.c
+++ b/src/radeon_exa.c
@@ -432,7 +432,7 @@ void *RADEONEXACreatePixmap2(ScreenPtr pScreen, int width, int height,
int padded_width;
uint32_t size;
uint32_t tiling = 0;
- int pixmap_align;
+ int cpp = bitsPerPixel / 8;
#ifdef EXA_MIXED_PIXMAPS
if (info->accel_state->exa->flags & EXA_MIXED_PIXMAPS) {
@@ -461,31 +461,11 @@ void *RADEONEXACreatePixmap2(ScreenPtr pScreen, int width, int height,
tiling &= ~RADEON_TILING_MACRO;
}
- if (info->ChipFamily >= CHIP_FAMILY_R600) {
- int bpe = bitsPerPixel / 8;
-
- if (tiling & RADEON_TILING_MACRO) {
- height = RADEON_ALIGN(height, info->num_channels * 8);
- pixmap_align = MAX(info->num_banks,
- (((info->group_bytes / 8) / bpe) * info->num_banks)) * 8 * bpe;
- } else if (tiling & RADEON_TILING_MICRO) {
- height = RADEON_ALIGN(height, 8);
- pixmap_align = MAX(8, (info->group_bytes / (8 * bpe))) * bpe;
- } else {
- height = RADEON_ALIGN(height, 8);
- pixmap_align = 256; /* 8 * bpe */
- }
- } else {
- if (tiling) {
- height = RADEON_ALIGN(height, 16);
- pixmap_align = 256;
- } else
- pixmap_align = 64;
- }
-
+ height = RADEON_ALIGN(height, drmmode_get_height_align(pScrn, tiling));
padded_width = ((width * bitsPerPixel + FB_MASK) >> FB_SHIFT) * sizeof(FbBits);
- padded_width = RADEON_ALIGN(padded_width, pixmap_align);
+ padded_width = RADEON_ALIGN(padded_width, drmmode_get_pitch_align(pScrn, cpp, tiling));
size = height * padded_width;
+ size = RADEON_ALIGN(size, RADEON_GPU_PAGE_SIZE);
new_priv = calloc(1, sizeof(struct radeon_exa_pixmap_priv));
if (!new_priv)
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
index b94544e8..e2406075 100644
--- a/src/radeon_kms.c
+++ b/src/radeon_kms.c
@@ -1088,8 +1088,9 @@ 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 stride = pScrn->displayWidth * cpp;
+ int stride;
int total_size_bytes = 0, remain_size_bytes;
+ uint32_t tiling_flags = 0;
if (info->accel_state->exa != NULL) {
xf86DrvMsg(pScreen->myNum, X_ERROR, "Memory map already initialized\n");
@@ -1101,7 +1102,13 @@ static Bool radeon_setup_kernel_mem(ScreenPtr pScreen)
return FALSE;
}
- screen_size = RADEON_ALIGN(pScrn->virtualY, 16) * stride;
+ /* no tiled scanout on r6xx+ yet */
+ if (info->allowColorTiling) {
+ if (info->ChipFamily < CHIP_FAMILY_R600)
+ tiling_flags |= RADEON_TILING_MACRO;
+ }
+ stride = RADEON_ALIGN(pScrn->displayWidth * cpp, drmmode_get_pitch_align(pScrn, cpp, tiling_flags));
+ screen_size = RADEON_ALIGN(pScrn->virtualY, drmmode_get_height_align(pScrn, tiling_flags)) * stride;
{
int cursor_size = 64 * 4 * 64;
int c;
@@ -1142,8 +1149,6 @@ static Bool radeon_setup_kernel_mem(ScreenPtr pScreen)
info->dri->textureSize = 0;
if (info->front_bo == NULL) {
- uint32_t tiling_flags = 0;
-
info->front_bo = radeon_bo_open(info->bufmgr, 0, screen_size,
0, RADEON_GEM_DOMAIN_VRAM, 0);
if (info->r600_shadow_fb == TRUE) {
@@ -1151,11 +1156,6 @@ static Bool radeon_setup_kernel_mem(ScreenPtr pScreen)
ErrorF("Failed to map cursor buffer memory\n");
}
}
- /* no tiled scanout on r6xx+ yet */
- if (info->allowColorTiling) {
- if (info->ChipFamily < CHIP_FAMILY_R600)
- tiling_flags |= RADEON_TILING_MACRO;
- }
#if X_BYTE_ORDER == X_BIG_ENDIAN
switch (cpp) {
case 4: