When ColorTiling is enabled, macrotiled small pixmaps cannot be used as textures because of MACRO_SWITCH. The attached patch fixes that and this issue is well described in the commit message. Please review.
This also fixes some piglit tests for r300g with ColorTiling enabled, e.g. glean/readPixSanity and shaders/fp-fog among others. (The texturing/texredefine test fails due to a flush missing somewhere, but the driver now passes more tests than without ColorTiling.) This fix is only for r300. I am not sure whether there is the same issue on non-r300 GPUs too. Also can ColorTiling be enabled by default on KMS now? -Marek
From 1672d8bccd03449148733bcad45f247f63615261 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= <[email protected]> Date: Mon, 3 May 2010 22:56:27 +0200 Subject: [PATCH] r3xx-r5xx: fix texturing with small macrotiled pixmaps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pixmaps smaller than a macrotile cannot be used as textures because hardware automatically switches to macro-linear and therefore sampled pixels are messed up. This behavior is known as MACRO_SWITCH. The only sane workaround seems to be not using macrotiling for small pixmaps. The function RADEONMacroSwitch has been ported from r300g and implements MACRO_SWITCH the same way it's implemented in hardware. It's been well tested in r300g. This commit also fixes blit-based framebuffer reads, which are used for tiled surfaces in r300g, when ColorTiling is enabled. Signed-off-by: Marek Olšák <[email protected]> --- src/radeon_exa.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 files changed, 41 insertions(+), 0 deletions(-) diff --git a/src/radeon_exa.c b/src/radeon_exa.c index 217a0fe..b285f65 100644 --- a/src/radeon_exa.c +++ b/src/radeon_exa.c @@ -391,6 +391,37 @@ void *RADEONEXACreatePixmap(ScreenPtr pScreen, int size, int align) } +static const unsigned MicroBlockTable[5][3][2] = { + /*linear tiled square-tiled */ + {{32, 1}, {8, 4}, {0, 0}}, /* 8 bits per pixel */ + {{16, 1}, {8, 2}, {4, 4}}, /* 16 bits per pixel */ + {{ 8, 1}, {4, 2}, {0, 0}}, /* 32 bits per pixel */ + {{ 4, 1}, {0, 0}, {2, 2}}, /* 64 bits per pixel */ + {{ 2, 1}, {0, 0}, {0, 0}} /* 128 bits per pixel */ +}; + +/* Return true if macrotiling can be enabled */ +static Bool RADEONMacroSwitch(int width, int height, int bpp, + uint32_t flags, Bool rv350_mode) +{ + unsigned tilew, tileh, microtiled, logbpp; + + logbpp = RADEONLog2(bpp / 8); + if (logbpp > 4) + return 0; + + microtiled = !!(flags & RADEON_TILING_MICRO); + tilew = MicroBlockTable[logbpp][microtiled][0] * 8; + tileh = MicroBlockTable[logbpp][microtiled][1] * 8; + + /* See TX_FILTER1_n.MACRO_SWITCH. */ + if (rv350_mode) { + return width >= tilew && height >= tileh; + } else { + return width > tilew && height > tileh; + } +} + void *RADEONEXACreatePixmap2(ScreenPtr pScreen, int width, int height, int depth, int usage_hint, int bitsPerPixel, int *new_pitch) @@ -420,6 +451,16 @@ void *RADEONEXACreatePixmap2(ScreenPtr pScreen, int width, int height, } } + /* Small pixmaps must not be macrotiled on R300, hw cannot sample them + * correctly because samplers automatically switch to macrolinear. */ + if (info->ChipFamily >= CHIP_FAMILY_R300 && + info->ChipFamily <= CHIP_FAMILY_RS690 && + (tiling & RADEON_TILING_MACRO) && + !RADEONMacroSwitch(width, height, bitsPerPixel, tiling, + info->ChipFamily >= CHIP_FAMILY_RV350)) { + tiling &= ~RADEON_TILING_MACRO; + } + if (tiling) { height = RADEON_ALIGN(height, 16); pixmap_align = 256; -- 1.7.0.4
_______________________________________________ xorg-driver-ati mailing list [email protected] http://lists.x.org/mailman/listinfo/xorg-driver-ati
