From 44b697ff6c25884f21b4f57d6275baf3848fd37f Mon Sep 17 00:00:00 2001 From: Simon Farnsworth Date: Tue, 13 Dec 2011 15:16:04 +0000 Subject: [PATCH 2/2] Make alignment functions match the documentation 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 --- 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