diff options
author | Alex Deucher <alexdeucher@gmail.com> | 2010-10-27 12:37:42 -0400 |
---|---|---|
committer | Alex Deucher <alexdeucher@gmail.com> | 2010-10-27 12:40:48 -0400 |
commit | f07f9b7b61c05f2de1d61bb0e2f71bd017c8d36a (patch) | |
tree | f7091c76b5e6e7e08d9dcfffafa109847776a86c | |
parent | d31046ba6c8eee9b7decc3875697d37c38bc38f3 (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.c | 59 | ||||
-rw-r--r-- | src/drmmode_display.h | 3 | ||||
-rw-r--r-- | src/radeon_exa.c | 28 | ||||
-rw-r--r-- | src/radeon_kms.c | 18 |
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: |