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

Reply via email to