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 /src/drmmode_display.c | |
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.
Diffstat (limited to 'src/drmmode_display.c')
-rw-r--r-- | src/drmmode_display.c | 59 |
1 files changed, 52 insertions, 7 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: |