xf86-video-ati: Branch 'master'

Alex Deucher agd5f at kemper.freedesktop.org
Tue May 4 14:36:35 PDT 2010


 src/radeon_exa.c |   41 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

New commits:
commit 766024dcc61c83490540910ce752f9bfe6dddba4
Author: Marek Olšák <maraeo at gmail.com>
Date:   Mon May 3 22:56:27 2010 +0200

    r3xx-r5xx: fix texturing with small macrotiled pixmaps
    
    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 <maraeo at gmail.com>

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;


More information about the xorg-commit mailing list