From e74f54793e45dd2e36474f6fc527456647f32efd Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 1 Jul 2008 15:09:24 -0700 Subject: [PATCH] intel-gem: Move bit 6 x tiling swizzle to a driconf option, and add new mode. It turns out that it's not just deviceID dependent, and there's some additional undefined factor that determines the bit 6 swizzling. It's now controllable with swizzle_mode=[012] until we get a response on how to automatically detect. --- src/mesa/drivers/dri/intel/intel_context.c | 3 ++ src/mesa/drivers/dri/intel/intel_context.h | 1 + src/mesa/drivers/dri/intel/intel_screen.c | 9 +++- src/mesa/drivers/dri/intel/intel_span.c | 51 ++++++++++++++-------- 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 46acf797217..33b8843e33e 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 f1116d27479..6ed9a377e49 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 8fd503ee8b7..6597dbffed8 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 c6778b16ff3..8d7d913ca9a 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 -- 2.30.2