From d1c88dc5f9991c2efff735c1cd91720f3e2434a6 Mon Sep 17 00:00:00 2001 From: Simon Farnsworth Date: Tue, 13 Dec 2011 15:45:52 +0000 Subject: [PATCH] r600g: Fix tiling alignment to match docs R600 and Evergreen have different tiling requirements. Fix Mesa to match the documented requirements. 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 the DDX to avoid misrendering, at which point I see CP lockups instead. I'm therefore sending this, the DDX patch, and the kernel 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/gallium/drivers/r600/evergreen_state.c | 2 +- src/gallium/drivers/r600/r600_texture.c | 140 ++++++++++++++++++++-------- 2 files changed, 103 insertions(+), 39 deletions(-) diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index d0c02d5..d6b97da 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -1447,7 +1447,7 @@ static void evergreen_cb(struct r600_pipe_context *rctx, struct r600_pipe_state offset >> 8, 0xFFFFFFFF, &rtex->resource, RADEON_USAGE_READWRITE); r600_pipe_state_add_reg(rstate, R_028C78_CB_COLOR0_DIM + cb * 0x3C, - 0x0, 0xFFFFFFFF, NULL, 0); + S_028C78_WIDTH_MAX(surf->base.width) | S_028C78_HEIGHT_MAX(surf->base.height), 0xFFFFFFFF, NULL, 0); r600_pipe_state_add_reg(rstate, R_028C70_CB_COLOR0_INFO + cb * 0x3C, color_info, 0xFFFFFFFF, &rtex->resource, RADEON_USAGE_READWRITE); diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c index 6143133..16ffe23 100644 --- a/src/gallium/drivers/r600/r600_texture.c +++ b/src/gallium/drivers/r600/r600_texture.c @@ -88,23 +88,42 @@ static unsigned r600_get_block_alignment(struct pipe_screen *screen, unsigned pixsize = util_format_get_blocksize(format); int p_align; - switch(array_mode) { - case V_038000_ARRAY_2D_TILED_THIN1: - p_align = MAX2(rscreen->tiling_info.num_banks, - (((rscreen->tiling_info.group_bytes / 8) / pixsize) * rscreen->tiling_info.num_banks)) * 8; - /* further restrictions for scanout */ - p_align = MAX2(rscreen->tiling_info.num_banks * 8, p_align); - break; - case V_038000_ARRAY_1D_TILED_THIN1: - p_align = MAX2(8, (rscreen->tiling_info.group_bytes / (8 * pixsize))); - /* further restrictions for scanout */ - p_align = MAX2((rscreen->tiling_info.group_bytes / pixsize), p_align); - break; - case V_038000_ARRAY_LINEAR_ALIGNED: - case V_038000_ARRAY_LINEAR_GENERAL: - default: - p_align = MAX2(64, rscreen->tiling_info.group_bytes / pixsize); - break; + if (rscreen->chip_class >= EVERGREEN) + { + switch(array_mode) { + case V_038000_ARRAY_2D_TILED_THIN1: + /* Kernel uses bank width of 8, macro tile aspect of 1 */ + p_align = rscreen->tiling_info.num_channels * 8 * 1 * 8; + break; + case V_038000_ARRAY_1D_TILED_THIN1: + p_align = MAX2(8, rscreen->tiling_info.group_bytes / + (8 * 1 * pixsize * 1)); + break; + case V_038000_ARRAY_LINEAR_ALIGNED: + p_align = MAX2(64, rscreen->tiling_info.group_bytes / pixsize); + break; + case V_038000_ARRAY_LINEAR_GENERAL: + default: + p_align = 8; + } + } + else + { + switch(array_mode) { + case V_038000_ARRAY_2D_TILED_THIN1: + p_align = MAX2(rscreen->tiling_info.num_banks * 8, + ((rscreen->tiling_info.group_bytes / 8) / pixsize) * rscreen->tiling_info.num_banks); + break; + case V_038000_ARRAY_1D_TILED_THIN1: + p_align = MAX2(8, (rscreen->tiling_info.group_bytes / (8 * pixsize))); + break; + case V_038000_ARRAY_LINEAR_ALIGNED: + p_align = MAX2(64, rscreen->tiling_info.group_bytes / pixsize); + break; + case V_038000_ARRAY_LINEAR_GENERAL: + default: + p_align = 1; + } } return p_align; } @@ -115,16 +134,36 @@ static unsigned r600_get_height_alignment(struct pipe_screen *screen, struct r600_screen* rscreen = (struct r600_screen *)screen; int h_align; - switch (array_mode) { - case V_038000_ARRAY_2D_TILED_THIN1: - h_align = rscreen->tiling_info.num_channels * 8; - break; - case V_038000_ARRAY_1D_TILED_THIN1: - case V_038000_ARRAY_LINEAR_ALIGNED: - case V_038000_ARRAY_LINEAR_GENERAL: - default: - h_align = 8; - break; + if (rscreen->chip_class >= EVERGREEN) + { + switch(array_mode) { + case V_038000_ARRAY_2D_TILED_THIN1: + /* Kernel uses bank_height of 8, macro_tile_aspect of 1 */ + h_align = rscreen->tiling_info.num_banks * 8 / 1 * 8; + break; + case V_038000_ARRAY_1D_TILED_THIN1: + h_align = 8; + break; + case V_038000_ARRAY_LINEAR_ALIGNED: + case V_038000_ARRAY_LINEAR_GENERAL: + default: + h_align = 1; + } + } + else + { + switch(array_mode) { + case V_038000_ARRAY_2D_TILED_THIN1: + h_align = rscreen->tiling_info.num_channels * 8; + break; + case V_038000_ARRAY_1D_TILED_THIN1: + h_align = 8; + break; + case V_038000_ARRAY_LINEAR_ALIGNED: + case V_038000_ARRAY_LINEAR_GENERAL: + default: + h_align = 1; + } } return h_align; } @@ -139,17 +178,42 @@ static unsigned r600_get_base_alignment(struct pipe_screen *screen, int h_align = r600_get_height_alignment(screen, array_mode); int b_align; - switch (array_mode) { - case V_038000_ARRAY_2D_TILED_THIN1: - b_align = MAX2(rscreen->tiling_info.num_banks * rscreen->tiling_info.num_channels * 8 * 8 * pixsize, - p_align * pixsize * h_align); - break; - case V_038000_ARRAY_1D_TILED_THIN1: - case V_038000_ARRAY_LINEAR_ALIGNED: - case V_038000_ARRAY_LINEAR_GENERAL: - default: - b_align = rscreen->tiling_info.group_bytes; - break; + if (rscreen->chip_class >= EVERGREEN) + { + switch(array_mode) { + case V_038000_ARRAY_2D_TILED_THIN1: + /* Kernel always uses bank_width and bank_height of 8. + Tile split size is between 1024 and 4096 - + assumption of 4096 is safe due to MIN */ + b_align = rscreen->tiling_info.num_channels * + rscreen->tiling_info.num_banks * 8 * 8 * + MIN2(4096, 8 * 8 * pixsize * 1); + break; + case V_038000_ARRAY_1D_TILED_THIN1: + case V_038000_ARRAY_LINEAR_ALIGNED: + b_align = rscreen->tiling_info.group_bytes; + case V_038000_ARRAY_LINEAR_GENERAL: + default: + b_align = pixsize; + break; + } + } + else + { + switch(array_mode) { + case V_038000_ARRAY_2D_TILED_THIN1: + b_align = MAX2(rscreen->tiling_info.num_banks * rscreen->tiling_info.num_channels + * 8 * 8 * pixsize, + p_align * pixsize * h_align); + break; + case V_038000_ARRAY_1D_TILED_THIN1: + b_align = rscreen->tiling_info.group_bytes; + break; + case V_038000_ARRAY_LINEAR_ALIGNED: + case V_038000_ARRAY_LINEAR_GENERAL: + default: + b_align = 1; + } } return b_align; } -- 1.7.6.4