summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mesa/drivers/dri/intel/intel_context.c3
-rw-r--r--src/mesa/drivers/dri/intel/intel_context.h1
-rw-r--r--src/mesa/drivers/dri/intel/intel_screen.c9
-rw-r--r--src/mesa/drivers/dri/intel/intel_span.c51
4 files changed, 46 insertions, 18 deletions
diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c
index 46acf79721..33b8843e33 100644
--- a/src/mesa/drivers/dri/intel/intel_context.c
+++ b/src/mesa/drivers/dri/intel/intel_context.c
@@ -697,6 +697,9 @@ intelInitContext(struct intel_context *intel,
intel->no_rast = 1;
}
+ intel->tiling_swizzle_mode = driQueryOptioni(&intel->optionCache,
+ "swizzle_mode");
+
/* Disable all hardware rendering (skip emitting batches and fences/waits
* to the kernel)
*/
diff --git a/src/mesa/drivers/dri/intel/intel_context.h b/src/mesa/drivers/dri/intel/intel_context.h
index f1116d2747..6ed9a377e4 100644
--- a/src/mesa/drivers/dri/intel/intel_context.h
+++ b/src/mesa/drivers/dri/intel/intel_context.h
@@ -266,6 +266,7 @@ struct intel_context
GLuint lastStamp;
GLboolean no_hw;
+ int tiling_swizzle_mode;
/**
* Configuration cache
diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c
index 8fd503ee8b..6597dbffed 100644
--- a/src/mesa/drivers/dri/intel/intel_screen.c
+++ b/src/mesa/drivers/dri/intel/intel_screen.c
@@ -69,13 +69,20 @@ PUBLIC const char __driConfigOptions[] =
DRI_CONF_SECTION_QUALITY
DRI_CONF_FORCE_S3TC_ENABLE(false)
DRI_CONF_ALLOW_LARGE_TEXTURES(2)
+ DRI_CONF_OPT_BEGIN_V(swizzle_mode, enum, 0, "0:2")
+ DRI_CONF_DESC_BEGIN(en, "Tiling swizzle mode for software fallbacks")
+ DRI_CONF_ENUM(0, "No swizzling")
+ DRI_CONF_ENUM(1, "addr[6] = addr[6] ^ addr[9]")
+ DRI_CONF_ENUM(2, "addr[6] = addr[6] ^ addr[9] ^ addr[10]")
+ DRI_CONF_DESC_END
+ DRI_CONF_OPT_END
DRI_CONF_SECTION_END
DRI_CONF_SECTION_DEBUG
DRI_CONF_NO_RAST(false)
DRI_CONF_SECTION_END
DRI_CONF_END;
-const GLuint __driNConfigOptions = 6;
+const GLuint __driNConfigOptions = 7;
#ifdef USE_NEW_INTERFACE
static PFNGLXCREATECONTEXTMODES create_context_modes = NULL;
diff --git a/src/mesa/drivers/dri/intel/intel_span.c b/src/mesa/drivers/dri/intel/intel_span.c
index c6778b16ff..8d7d913ca9 100644
--- a/src/mesa/drivers/dri/intel/intel_span.c
+++ b/src/mesa/drivers/dri/intel/intel_span.c
@@ -106,29 +106,46 @@ static GLubyte *x_tile_swizzle(struct intel_renderbuffer *irb, struct intel_cont
x_tile_off = xbyte & 0x1ff;
y_tile_off = y & 7;
-#ifndef I915
- /* The documentation says that X tile layout is arranged in 8 512-byte
- * lines of pixel data. However, that doesn't appear to be the case
- * on GM965, tested by drawing a 128x8 quad in no_rast mode. For lines
- * 1,2,4, and 7 of each tile, each consecutive pair of 64-byte spans
- * has the locations of those spans swapped.
+ x_tile_number = xbyte >> 9;
+ y_tile_number = y >> 3;
+
+ tile_off = (y_tile_off << 9) + x_tile_off;
+
+ /* bit swizzling tricks your parents never told you about:
+ *
+ * The specs say that the X tiling layout is just 8 512-byte rows
+ * packed into a page. It turns out that there's some additional
+ * swizzling of bit 6 to reduce cache aliasing issues. Experimental
+ * results below:
+ *
+ * line bit GM965 945G/Q965
+ * 9 10 11
+ * 0 0 0 0 0 0
+ * 1 0 1 0 1 1
+ * 2 1 0 0 1 1
+ * 3 1 1 0 0 0
+ * 4 0 0 1 1 0
+ * 5 0 1 1 0 1
+ * 6 1 0 1 0 1
+ * 7 1 1 1 1 0
+ *
+ * So we see that the GM965 is bit 6 ^ 9 ^ 10 ^ 11, while other
+ * parts were just 6 ^ 9 ^ 10. However, some systems, including a
+ * GM965 we've seen, don't perform the swizzling at all. Information
+ * on how to detect it through register reads is expected soon.
*/
- switch (y_tile_off) {
+ switch (intel->tiling_swizzle_mode) {
+ case 0:
+ break;
case 1:
+ tile_off ^= ((tile_off >> 3) & 64) ^ ((tile_off >> 4) & 64);
+ break;
case 2:
- case 4:
- case 7:
- x_tile_off ^= 64;
- break;
- default:
+ tile_off ^= ((tile_off >> 3) & 64) ^ ((tile_off >> 4) & 64) ^
+ ((tile_off >> 5) & 64);
break;
}
-#endif
-
- x_tile_number = xbyte >> 9;
- y_tile_number = y >> 3;
- tile_off = (y_tile_off << 9) + x_tile_off;
tile_base = (x_tile_number << 12) + y_tile_number * tile_stride;
#if 0