Merge commit 'origin/master' into gallium-0.2
[mesa.git] / src / mesa / drivers / dri / intel / intel_span.c
index 7b079afa7363ad4eb4b8fca7dfbc9c57b1da8640..d9315043e6e21af4c0aa7aceb29530550f30315a 100644 (file)
  * 
  **************************************************************************/
 
-#include "glheader.h"
-#include "macros.h"
-#include "mtypes.h"
-#include "colormac.h"
+#include "main/glheader.h"
+#include "main/macros.h"
+#include "main/mtypes.h"
+#include "main/colormac.h"
 
+#include "intel_buffers.h"
 #include "intel_fbo.h"
 #include "intel_screen.h"
 #include "intel_span.h"
 #include "intel_regions.h"
-#include "intel_ioctl.h"
 #include "intel_tex.h"
 
 #include "swrast/swrast.h"
 
-/*
- * Deal with tiled surfaces
- */
+static void
+intel_set_span_functions(struct intel_context *intel,
+                        struct gl_renderbuffer *rb);
 
-#if 0
-/* These are pre-965 tile swizzling functions -- power of two widths */
-static uintptr_t x_tile_swizzle_pow2 (uintptr_t addr, int n)
+#define SPAN_CACHE_SIZE                4096
+
+static void
+get_span_cache(struct intel_renderbuffer *irb, uint32_t offset)
+{
+   if (irb->span_cache == NULL) {
+      irb->span_cache = _mesa_malloc(SPAN_CACHE_SIZE);
+      irb->span_cache_offset = -1;
+   }
+
+   if ((offset & ~(SPAN_CACHE_SIZE - 1)) != irb->span_cache_offset) {
+      irb->span_cache_offset = offset & ~(SPAN_CACHE_SIZE - 1);
+      dri_bo_get_subdata(irb->region->buffer, irb->span_cache_offset,
+                        SPAN_CACHE_SIZE, irb->span_cache);
+   }
+}
+
+static void
+clear_span_cache(struct intel_renderbuffer *irb)
+{
+   irb->span_cache_offset = -1;
+}
+
+static uint32_t
+pread_32(struct intel_renderbuffer *irb, uint32_t offset)
 {
-       uintptr_t       a = addr;
-       uintptr_t       base_mask = (((~0) << (n + 4)) | 0xff);
-       uintptr_t       x_mask = ((~0) << 12) & ~base_mask;
-
-       a = ((a & base_mask) | 
-            ((a >> (n-8)) & 0x7) |
-            ((a << 3) & x_mask));
-       _mesa_printf ("x_swizzle %08x (base %x yrow %x tile#x %x xsword %x byte %x) %08x\n",
-                     addr,
-                     addr >> (n + 4),
-                     (addr >> (n + 1)) & 0x7,
-                     (addr >> 9) & ((1 << (n-8)) - 1),
-                     (addr >> 5) & 0xf,
-                     (addr & 0x1f),
-                     a);
-       return a;
+   get_span_cache(irb, offset);
+
+   return *(uint32_t *)(irb->span_cache + (offset & (SPAN_CACHE_SIZE - 1)));
 }
 
-static uintptr_t y_tile_swizzle_pow2 (uintptr_t addr, int n)
+static uint32_t
+pread_xrgb8888(struct intel_renderbuffer *irb, uint32_t offset)
 {
-       uintptr_t       a = (uintptr_t) addr;
-       uintptr_t       base_mask = (((~0) << (n + 6)) | 0xf);
-       uintptr_t       x_mask = ((~0) << 9) & ~base_mask;
-
-       a = ((a & base_mask) | 
-            ((a >> (n-3)) & 0x1f) |
-            ((a << 5) & x_mask));
-       _mesa_printf ("y_swizzle %08x (base %x yrow %x tile#x %x xoword %x byte %x) %08x\n",
-                     addr,
-                     addr >> (n + 6),
-                     (addr >> (n + 1)) & 0x01f,
-                     (addr >> 7) & ((1 << (n-6)) - 1),
-                     (addr >> 4) & 0x7,
-                     (addr & 0xf),
-                     a);
-       return a;
+   get_span_cache(irb, offset);
+
+   return *(uint32_t *)(irb->span_cache + (offset & (SPAN_CACHE_SIZE - 1))) |
+      0xff000000;
 }
-#endif
 
-static GLubyte *x_tile_swizzle(struct intel_renderbuffer *irb, struct intel_context *intel,
+static uint16_t
+pread_16(struct intel_renderbuffer *irb, uint32_t offset)
+{
+   get_span_cache(irb, offset);
+
+   return *(uint16_t *)(irb->span_cache + (offset & (SPAN_CACHE_SIZE - 1)));
+}
+
+static uint8_t
+pread_8(struct intel_renderbuffer *irb, uint32_t offset)
+{
+   get_span_cache(irb, offset);
+
+   return *(uint8_t *)(irb->span_cache + (offset & (SPAN_CACHE_SIZE - 1)));
+}
+
+static void
+pwrite_32(struct intel_renderbuffer *irb, uint32_t offset, uint32_t val)
+{
+   clear_span_cache(irb);
+
+   dri_bo_subdata(irb->region->buffer, offset, 4, &val);
+}
+
+static void
+pwrite_xrgb8888(struct intel_renderbuffer *irb, uint32_t offset, uint32_t val)
+{
+   clear_span_cache(irb);
+
+   dri_bo_subdata(irb->region->buffer, offset, 3, &val);
+}
+
+static void
+pwrite_16(struct intel_renderbuffer *irb, uint32_t offset, uint16_t val)
+{
+   clear_span_cache(irb);
+
+   dri_bo_subdata(irb->region->buffer, offset, 2, &val);
+}
+
+static void
+pwrite_8(struct intel_renderbuffer *irb, uint32_t offset, uint8_t val)
+{
+   clear_span_cache(irb);
+
+   dri_bo_subdata(irb->region->buffer, offset, 1, &val);
+}
+
+static uint32_t no_tile_swizzle(struct intel_renderbuffer *irb,
+                               int x, int y)
+{
+       return (y * irb->region->pitch + x) * irb->region->cpp;
+}
+
+/*
+ * Deal with tiled surfaces
+ */
+
+static uint32_t x_tile_swizzle(struct intel_renderbuffer *irb,
                               int x, int y)
 {
-       GLubyte *buf = (GLubyte *) irb->pfMap;
        int     tile_stride;
        int     xbyte;
        int     x_tile_off, y_tile_off;
@@ -97,9 +151,6 @@ static GLubyte *x_tile_swizzle(struct intel_renderbuffer *irb, struct intel_cont
        int     tile_off, tile_base;
        
        tile_stride = (irb->pfPitch * irb->region->cpp) << 3;
-       
-       x += intel->drawX;
-       y += intel->drawY;
 
        xbyte = x * irb->region->cpp;
 
@@ -111,39 +162,26 @@ static GLubyte *x_tile_swizzle(struct intel_renderbuffer *irb, struct intel_cont
 
        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 (intel->tiling_swizzle_mode) {
-       case 0:
+       switch (irb->region->bit_6_swizzle) {
+       case I915_BIT_6_SWIZZLE_NONE:
+          break;
+       case I915_BIT_6_SWIZZLE_9:
+          tile_off ^= ((tile_off >> 3) & 64);
           break;
-       case 1:
+       case I915_BIT_6_SWIZZLE_9_10:
           tile_off ^= ((tile_off >> 3) & 64) ^ ((tile_off >> 4) & 64);
           break;
-       case 2:
+       case I915_BIT_6_SWIZZLE_9_11:
+          tile_off ^= ((tile_off >> 3) & 64) ^ ((tile_off >> 5) & 64);
+          break;
+       case I915_BIT_6_SWIZZLE_9_10_11:
           tile_off ^= ((tile_off >> 3) & 64) ^ ((tile_off >> 4) & 64) ^
              ((tile_off >> 5) & 64);
           break;
+       default:
+          fprintf(stderr, "Unknown tile swizzling mode %d\n",
+                  irb->region->bit_6_swizzle);
+          exit(1);
        }
 
        tile_base = (x_tile_number << 12) + y_tile_number * tile_stride;
@@ -155,13 +193,12 @@ static GLubyte *x_tile_swizzle(struct intel_renderbuffer *irb, struct intel_cont
               irb->pfPitch, tile_stride);
 #endif
 
-       return buf + tile_base + tile_off;
+       return tile_base + tile_off;
 }
 
-static GLubyte *y_tile_swizzle(struct intel_renderbuffer *irb, struct intel_context *intel,
+static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb,
                               int x, int y)
 {
-       GLubyte *buf = (GLubyte *) irb->pfMap;
        int     tile_stride;
        int     xbyte;
        int     x_tile_off, y_tile_off;
@@ -169,9 +206,6 @@ static GLubyte *y_tile_swizzle(struct intel_renderbuffer *irb, struct intel_cont
        int     tile_off, tile_base;
        
        tile_stride = (irb->pfPitch * irb->region->cpp) << 5;
-       
-       x += intel->drawX;
-       y += intel->drawY;
 
        xbyte = x * irb->region->cpp;
 
@@ -184,18 +218,31 @@ static GLubyte *y_tile_swizzle(struct intel_renderbuffer *irb, struct intel_cont
        tile_off = ((x_tile_off & ~0xf) << 5) + (y_tile_off << 4) +
           (x_tile_off & 0xf);
 
-       switch (intel->tiling_swizzle_mode) {
-       case 0:
+       switch (irb->region->bit_6_swizzle) {
+       case I915_BIT_6_SWIZZLE_NONE:
           break;
-       case 1:
-          tile_off ^= (tile_off >> 3) & 64;
+       case I915_BIT_6_SWIZZLE_9:
+          tile_off ^= ((tile_off >> 3) & 64);
           break;
-       case 2:
+       case I915_BIT_6_SWIZZLE_9_10:
+          tile_off ^= ((tile_off >> 3) & 64) ^ ((tile_off >> 4) & 64);
           break;
+       case I915_BIT_6_SWIZZLE_9_11:
+          tile_off ^= ((tile_off >> 3) & 64) ^ ((tile_off >> 5) & 64);
+          break;
+       case I915_BIT_6_SWIZZLE_9_10_11:
+          tile_off ^= ((tile_off >> 3) & 64) ^ ((tile_off >> 4) & 64) ^
+             ((tile_off >> 5) & 64);
+          break;
+       default:
+          fprintf(stderr, "Unknown tile swizzling mode %d\n",
+                  irb->region->bit_6_swizzle);
+          exit(1);
        }
+
        tile_base = (x_tile_number << 12) + y_tile_number * tile_stride;
 
-       return buf + tile_base + tile_off;
+       return tile_base + tile_off;
 }
 
 /*
@@ -210,11 +257,12 @@ static GLubyte *y_tile_swizzle(struct intel_renderbuffer *irb, struct intel_cont
    struct intel_renderbuffer *irb = intel_renderbuffer(rb);            \
    const GLint yScale = irb->RenderToTexture ? 1 : -1;                 \
    const GLint yBias = irb->RenderToTexture ? 0 : irb->Base.Height - 1;        \
-   GLubyte *buf = (GLubyte *) irb->pfMap                               \
-      + (intel->drawY * irb->pfPitch + intel->drawX) * irb->region->cpp;\
+   unsigned int num_cliprects;                                         \
+   struct drm_clip_rect *cliprects;                                    \
+   int x_off, y_off;                                                   \
    GLuint p;                                                           \
-   assert(irb->pfMap);\
-   (void) p; (void) buf;
+   (void) p;                                                           \
+   intel_get_cliprects(intel, &cliprects, &num_cliprects, &x_off, &y_off);
 
 /* XXX FBO: this is identical to the macro in spantmp2.h except we get
  * the cliprect info from the context, not the driDrawable.
@@ -222,12 +270,12 @@ static GLubyte *y_tile_swizzle(struct intel_renderbuffer *irb, struct intel_cont
  */
 #define HW_CLIPLOOP()                                                  \
    do {                                                                        \
-      int _nc = intel->numClipRects;                                   \
+      int _nc = num_cliprects;                                         \
       while ( _nc-- ) {                                                        \
-        int minx = intel->pClipRects[_nc].x1 - intel->drawX;           \
-        int miny = intel->pClipRects[_nc].y1 - intel->drawY;           \
-        int maxx = intel->pClipRects[_nc].x2 - intel->drawX;           \
-        int maxy = intel->pClipRects[_nc].y2 - intel->drawY;
+        int minx = cliprects[_nc].x1 - x_off;                          \
+        int miny = cliprects[_nc].y1 - y_off;                          \
+        int maxx = cliprects[_nc].x2 - x_off;                          \
+        int maxy = cliprects[_nc].y2 - y_off;
        
 #if 0
       }}
@@ -240,6 +288,11 @@ static GLubyte *y_tile_swizzle(struct intel_renderbuffer *irb, struct intel_cont
 
 #define HW_UNLOCK()
 
+/* Convenience macros to avoid typing the swizzle argument over and over */
+#define NO_TILE(_X, _Y) no_tile_swizzle(irb, (_X) + x_off, (_Y) + y_off)
+#define X_TILE(_X, _Y) x_tile_swizzle(irb, (_X) + x_off, (_Y) + y_off)
+#define Y_TILE(_X, _Y) y_tile_swizzle(irb, (_X) + x_off, (_Y) + y_off)
+
 /* 16 bit, RGB565 color spanline and pixel functions
  */
 #define SPANTMP_PIXEL_FMT GL_RGB
@@ -247,7 +300,8 @@ static GLubyte *y_tile_swizzle(struct intel_renderbuffer *irb, struct intel_cont
 
 #define TAG(x)    intel##x##_RGB565
 #define TAG2(x,y) intel##x##_RGB565##y
-#define GET_PTR(X,Y) (buf + ((Y) * irb->pfPitch + (X)) * 2)
+#define GET_VALUE(X, Y) pread_16(irb, NO_TILE(X, Y))
+#define PUT_VALUE(X, Y, V) pwrite_16(irb, NO_TILE(X, Y), V)
 #include "spantmp2.h"
 
 /* 32 bit, ARGB8888 color spanline and pixel functions
@@ -257,7 +311,19 @@ static GLubyte *y_tile_swizzle(struct intel_renderbuffer *irb, struct intel_cont
 
 #define TAG(x)    intel##x##_ARGB8888
 #define TAG2(x,y) intel##x##_ARGB8888##y
-#define GET_PTR(X,Y) (buf + ((Y) * irb->pfPitch + (X)) * 4)
+#define GET_VALUE(X, Y) pread_32(irb, NO_TILE(X, Y))
+#define PUT_VALUE(X, Y, V) pwrite_32(irb, NO_TILE(X, Y), V)
+#include "spantmp2.h"
+
+/* 32 bit, xRGB8888 color spanline and pixel functions
+ */
+#define SPANTMP_PIXEL_FMT GL_BGRA
+#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
+
+#define TAG(x)    intel##x##_xRGB8888
+#define TAG2(x,y) intel##x##_xRGB8888##y
+#define GET_VALUE(X, Y) pread_xrgb8888(irb, NO_TILE(X, Y))
+#define PUT_VALUE(X, Y, V) pwrite_xrgb8888(irb, NO_TILE(X, Y), V)
 #include "spantmp2.h"
 
 /* 16 bit RGB565 color tile spanline and pixel functions
@@ -268,7 +334,8 @@ static GLubyte *y_tile_swizzle(struct intel_renderbuffer *irb, struct intel_cont
 
 #define TAG(x)    intel_XTile_##x##_RGB565
 #define TAG2(x,y) intel_XTile_##x##_RGB565##y
-#define GET_PTR(X,Y) x_tile_swizzle(irb, intel, X, Y)
+#define GET_VALUE(X, Y) pread_16(irb, X_TILE(X, Y))
+#define PUT_VALUE(X, Y, V) pwrite_16(irb, X_TILE(X, Y), V)
 #include "spantmp2.h"
 
 #define SPANTMP_PIXEL_FMT GL_RGB
@@ -276,7 +343,8 @@ static GLubyte *y_tile_swizzle(struct intel_renderbuffer *irb, struct intel_cont
 
 #define TAG(x)    intel_YTile_##x##_RGB565
 #define TAG2(x,y) intel_YTile_##x##_RGB565##y
-#define GET_PTR(X,Y) y_tile_swizzle(irb, intel, X, Y)
+#define GET_VALUE(X, Y) pread_16(irb, Y_TILE(X, Y))
+#define PUT_VALUE(X, Y, V) pwrite_16(irb, Y_TILE(X, Y), V)
 #include "spantmp2.h"
 
 /* 32 bit ARGB888 color tile spanline and pixel functions
@@ -287,7 +355,8 @@ static GLubyte *y_tile_swizzle(struct intel_renderbuffer *irb, struct intel_cont
 
 #define TAG(x)    intel_XTile_##x##_ARGB8888
 #define TAG2(x,y) intel_XTile_##x##_ARGB8888##y
-#define GET_PTR(X,Y) x_tile_swizzle(irb, intel, X, Y)
+#define GET_VALUE(X, Y) pread_32(irb, X_TILE(X, Y))
+#define PUT_VALUE(X, Y, V) pwrite_32(irb, X_TILE(X, Y), V)
 #include "spantmp2.h"
 
 #define SPANTMP_PIXEL_FMT GL_BGRA
@@ -295,17 +364,40 @@ static GLubyte *y_tile_swizzle(struct intel_renderbuffer *irb, struct intel_cont
 
 #define TAG(x)    intel_YTile_##x##_ARGB8888
 #define TAG2(x,y) intel_YTile_##x##_ARGB8888##y
-#define GET_PTR(X,Y) y_tile_swizzle(irb, intel, X, Y)
+#define GET_VALUE(X, Y) pread_32(irb, Y_TILE(X, Y))
+#define PUT_VALUE(X, Y, V) pwrite_32(irb, Y_TILE(X, Y), V)
+#include "spantmp2.h"
+
+/* 32 bit xRGB888 color tile spanline and pixel functions
+ */
+
+#define SPANTMP_PIXEL_FMT GL_BGRA
+#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
+
+#define TAG(x)    intel_XTile_##x##_xRGB8888
+#define TAG2(x,y) intel_XTile_##x##_xRGB8888##y
+#define GET_VALUE(X, Y) pread_xrgb8888(irb, X_TILE(X, Y))
+#define PUT_VALUE(X, Y, V) pwrite_xrgb8888(irb, X_TILE(X, Y), V)
+#include "spantmp2.h"
+
+#define SPANTMP_PIXEL_FMT GL_BGRA
+#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
+
+#define TAG(x)    intel_YTile_##x##_xRGB8888
+#define TAG2(x,y) intel_YTile_##x##_xRGB8888##y
+#define GET_VALUE(X, Y) pread_xrgb8888(irb, Y_TILE(X, Y))
+#define PUT_VALUE(X, Y, V) pwrite_xrgb8888(irb, Y_TILE(X, Y), V)
 #include "spantmp2.h"
 
 #define LOCAL_DEPTH_VARS                                               \
    struct intel_context *intel = intel_context(ctx);                   \
    struct intel_renderbuffer *irb = intel_renderbuffer(rb);            \
-   const GLuint pitch = irb->pfPitch/***XXX region->pitch*/; /* in pixels */ \
    const GLint yScale = irb->RenderToTexture ? 1 : -1;                 \
-   const GLint yBias = irb->RenderToTexture ? 0 : irb->Base.Height - 1;        \
-   char *buf = (char *) irb->pfMap/*XXX use region->map*/ +             \
-      (intel->drawY * pitch + intel->drawX) * irb->region->cpp; (void) buf;
+   const GLint yBias = irb->RenderToTexture ? 0 : irb->Base.Height - 1; \
+   unsigned int num_cliprects;                                         \
+   struct drm_clip_rect *cliprects;                                    \
+   int x_off, y_off;                                                   \
+   intel_get_cliprects(intel, &cliprects, &num_cliprects, &x_off, &y_off);
 
 
 #define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS
@@ -313,13 +405,9 @@ static GLubyte *y_tile_swizzle(struct intel_renderbuffer *irb, struct intel_cont
 /**
  ** 16-bit depthbuffer functions.
  **/
-#define WRITE_DEPTH( _x, _y, d ) \
-   ((GLushort *)buf)[(_x) + (_y) * pitch] = d;
-
-#define READ_DEPTH( d, _x, _y )        \
-   d = ((GLushort *)buf)[(_x) + (_y) * pitch];
-
-
+#define VALUE_TYPE GLushort
+#define WRITE_DEPTH(_x, _y, d) pwrite_16(irb, NO_TILE(_x, _y), d)
+#define READ_DEPTH(d, _x, _y) d = pread_16(irb, NO_TILE(_x, _y))
 #define TAG(x) intel##x##_z16
 #include "depthtmp.h"
 
@@ -327,26 +415,18 @@ static GLubyte *y_tile_swizzle(struct intel_renderbuffer *irb, struct intel_cont
 /**
  ** 16-bit x tile depthbuffer functions.
  **/
-#define WRITE_DEPTH( _x, _y, d ) \
-   (*((GLushort *)x_tile_swizzle (irb, intel, _x, _y)) = d)
-
-#define READ_DEPTH( d, _x, _y )        \
-   d = *((GLushort *)x_tile_swizzle (irb, intel, _x, _y))
-
-
+#define VALUE_TYPE GLushort
+#define WRITE_DEPTH(_x, _y, d) pwrite_16(irb, X_TILE(_x, _y), d)
+#define READ_DEPTH(d, _x, _y) d = pread_16(irb, X_TILE(_x, _y))
 #define TAG(x) intel_XTile_##x##_z16
 #include "depthtmp.h"
 
 /**
  ** 16-bit y tile depthbuffer functions.
  **/
-#define WRITE_DEPTH( _x, _y, d ) \
-   (*((GLushort *)y_tile_swizzle (irb, intel, _x, _y)) = d)
-
-#define READ_DEPTH( d, _x, _y )        \
-   (d = *((GLushort *)y_tile_swizzle (irb, intel, _x, _y)))
-
-
+#define VALUE_TYPE GLushort
+#define WRITE_DEPTH(_x, _y, d) pwrite_16(irb, Y_TILE(_x, _y), d)
+#define READ_DEPTH(d, _x, _y) d = pread_16(irb, Y_TILE(_x, _y))
 #define TAG(x) intel_YTile_##x##_z16
 #include "depthtmp.h"
 
@@ -357,15 +437,15 @@ static GLubyte *y_tile_swizzle(struct intel_renderbuffer *irb, struct intel_cont
  ** The wrappers in main/depthstencil.c are used to extract the depth
  ** and stencil values.
  **/
+#define VALUE_TYPE GLuint
+
 /* Change ZZZS -> SZZZ */
-#define WRITE_DEPTH( _x, _y, d ) {                             \
-   GLuint tmp = ((d) >> 8) | ((d) << 24);                      \
-   ((GLuint *)buf)[(_x) + (_y) * pitch] = tmp;                 \
-}
+#define WRITE_DEPTH(_x, _y, d)                                 \
+   pwrite_32(irb, NO_TILE(_x, _y), ((d) >> 8) | ((d) << 24))
 
 /* Change SZZZ -> ZZZS */
 #define READ_DEPTH( d, _x, _y ) {                              \
-   GLuint tmp = ((GLuint *)buf)[(_x) + (_y) * pitch];          \
+   GLuint tmp = pread_32(irb, NO_TILE(_x, _y));                        \
    d = (tmp << 8) | (tmp >> 24);                               \
 }
 
@@ -379,15 +459,15 @@ static GLubyte *y_tile_swizzle(struct intel_renderbuffer *irb, struct intel_cont
  ** The wrappers in main/depthstencil.c are used to extract the depth
  ** and stencil values.
  **/
+#define VALUE_TYPE GLuint
+
 /* Change ZZZS -> SZZZ */
-#define WRITE_DEPTH( _x, _y, d ) {                             \
-   GLuint tmp = ((d) >> 8) | ((d) << 24);                      \
-   *((GLuint *)x_tile_swizzle (irb, intel, _x, _y)) = tmp;                     \
-}
+#define WRITE_DEPTH(_x, _y, d)                                 \
+   pwrite_32(irb, X_TILE(_x, _y), ((d) >> 8) | ((d) << 24))
 
 /* Change SZZZ -> ZZZS */
 #define READ_DEPTH( d, _x, _y ) {                              \
-   GLuint tmp = *((GLuint *)x_tile_swizzle (irb, intel, _x, _y));              \
+   GLuint tmp = pread_32(irb, X_TILE(_x, _y));         \
    d = (tmp << 8) | (tmp >> 24);                               \
 }
 
@@ -400,15 +480,15 @@ static GLubyte *y_tile_swizzle(struct intel_renderbuffer *irb, struct intel_cont
  ** The wrappers in main/depthstencil.c are used to extract the depth
  ** and stencil values.
  **/
+#define VALUE_TYPE GLuint
+
 /* Change ZZZS -> SZZZ */
-#define WRITE_DEPTH( _x, _y, d ) {                             \
-   GLuint tmp = ((d) >> 8) | ((d) << 24);                      \
-   *((GLuint *)y_tile_swizzle (irb, intel, _x, _y)) = tmp;                     \
-}
+#define WRITE_DEPTH(_x, _y, d)                                 \
+   pwrite_32(irb, Y_TILE(_x, _y), ((d) >> 8) | ((d) << 24))
 
 /* Change SZZZ -> ZZZS */
 #define READ_DEPTH( d, _x, _y ) {                              \
-   GLuint tmp = *((GLuint *)y_tile_swizzle (irb, intel, _x, _y));              \
+   GLuint tmp = pread_32(irb, Y_TILE(_x, _y));                 \
    d = (tmp << 8) | (tmp >> 24);                               \
 }
 
@@ -419,54 +499,55 @@ static GLubyte *y_tile_swizzle(struct intel_renderbuffer *irb, struct intel_cont
 /**
  ** 8-bit stencil function (XXX FBO: This is obsolete)
  **/
-#define WRITE_STENCIL( _x, _y, d ) {                           \
-   GLuint tmp = ((GLuint *)buf)[(_x) + (_y) * pitch];          \
-   tmp &= 0xffffff;                                            \
-   tmp |= ((d) << 24);                                         \
-   ((GLuint *) buf)[(_x) + (_y) * pitch] = tmp;                        \
-}
-
-#define READ_STENCIL( d, _x, _y )                              \
-   d = ((GLuint *)buf)[(_x) + (_y) * pitch] >> 24;
-
+#define WRITE_STENCIL(_x, _y, d) pwrite_8(irb, NO_TILE(_x, _y) + 3, d)
+#define READ_STENCIL(d, _x, _y) d = pread_8(irb, NO_TILE(_x, _y) + 3);
 #define TAG(x) intel##x##_z24_s8
 #include "stenciltmp.h"
 
 /**
  ** 8-bit x-tile stencil function (XXX FBO: This is obsolete)
  **/
-#define WRITE_STENCIL( _x, _y, d ) {                           \
-   GLuint *a = (GLuint *) x_tile_swizzle (irb, intel, _x, _y);  \
-   GLuint tmp = *a;                                            \
-   tmp &= 0xffffff;                                            \
-   tmp |= ((d) << 24);                                         \
-   *a = tmp;                                                   \
-}
-
-#define READ_STENCIL( d, _x, _y )                              \
-   (d = *((GLuint*) x_tile_swizzle (irb, intel, _x, _y)) >> 24)
-
+#define WRITE_STENCIL(_x, _y, d) pwrite_8(irb, X_TILE(_x, _y) + 3, d)
+#define READ_STENCIL(d, _x, _y) d = pread_8(irb, X_TILE(_x, _y) + 3);
 #define TAG(x) intel_XTile_##x##_z24_s8
 #include "stenciltmp.h"
 
 /**
  ** 8-bit y-tile stencil function (XXX FBO: This is obsolete)
  **/
-#define WRITE_STENCIL( _x, _y, d ) {                           \
-   GLuint *a = (GLuint *) y_tile_swizzle (irb, intel, _x, _y);  \
-   GLuint tmp = *a;                                            \
-   tmp &= 0xffffff;                                            \
-   tmp |= ((d) << 24);                                         \
-   *a = tmp;                                                   \
+#define WRITE_STENCIL(_x, _y, d) pwrite_8(irb, Y_TILE(_x, _y) + 3, d)
+#define READ_STENCIL(d, _x, _y) d = pread_8(irb, Y_TILE(_x, _y) + 3)
+#define TAG(x) intel_YTile_##x##_z24_s8
+#include "stenciltmp.h"
+
+void
+intel_renderbuffer_map(struct intel_context *intel, struct gl_renderbuffer *rb)
+{
+   struct intel_renderbuffer *irb = intel_renderbuffer(rb);
+
+   if (irb == NULL || irb->region == NULL)
+      return;
+
+   irb->pfPitch = irb->region->pitch;
+
+   intel_set_span_functions(intel, rb);
 }
 
-#define READ_STENCIL( d, _x, _y )                              \
-   (d = *((GLuint*) y_tile_swizzle (irb, intel, _x, _y)) >> 24)
+void
+intel_renderbuffer_unmap(struct intel_context *intel,
+                        struct gl_renderbuffer *rb)
+{
+   struct intel_renderbuffer *irb = intel_renderbuffer(rb);
 
-#define TAG(x) intel_YTile_##x##_z24_s8
-#include "stenciltmp.h"
+   if (irb == NULL || irb->region == NULL)
+      return;
 
+   clear_span_cache(irb);
+   irb->pfPitch = 0;
 
+   rb->GetRow = NULL;
+   rb->PutRow = NULL;
+}
 
 /**
  * Map or unmap all the renderbuffers which we may need during
@@ -485,23 +566,13 @@ intel_map_unmap_buffers(struct intel_context *intel, GLboolean map)
 {
    GLcontext *ctx = &intel->ctx;
    GLuint i, j;
-   struct intel_renderbuffer *irb;
 
    /* color draw buffers */
    for (j = 0; j < ctx->DrawBuffer->_NumColorDrawBuffers; j++) {
-      struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[j];
-      irb = intel_renderbuffer(rb);
-      if (irb) {
-         /* this is a user-created intel_renderbuffer */
-         if (irb->region) {
-            if (map)
-               intel_region_map(intel, irb->region);
-            else
-               intel_region_unmap(intel, irb->region);
-            irb->pfMap = irb->region->map;
-            irb->pfPitch = irb->region->pitch;
-         }
-      }
+      if (map)
+        intel_renderbuffer_map(intel, ctx->DrawBuffer->_ColorDrawBuffers[j]);
+      else
+        intel_renderbuffer_unmap(intel, ctx->DrawBuffer->_ColorDrawBuffers[j]);
    }
 
    /* check for render to textures */
@@ -512,89 +583,36 @@ intel_map_unmap_buffers(struct intel_context *intel, GLboolean map)
       if (tex) {
          /* render to texture */
          ASSERT(att->Renderbuffer);
-         if (map) {
-            struct gl_texture_image *texImg;
-            texImg = tex->Image[att->CubeMapFace][att->TextureLevel];
+         if (map)
             intel_tex_map_images(intel, intel_texture_object(tex));
-         }
-         else {
+         else
             intel_tex_unmap_images(intel, intel_texture_object(tex));
-         }
       }
    }
 
    /* color read buffers */
-   irb = intel_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer);
-   if (irb && irb->region) {
-      if (map)
-         intel_region_map(intel, irb->region);
-      else
-         intel_region_unmap(intel, irb->region);
-      irb->pfMap = irb->region->map;
-      irb->pfPitch = irb->region->pitch;
-   }
-
-   /* Account for front/back color page flipping.
-    * The span routines use the pfMap and pfPitch fields which will
-    * swap the front/back region map/pitch if we're page flipped.
-    * Do this after mapping, above, so the map field is valid.
-    */
-#if 0
-   if (map && ctx->DrawBuffer->Name == 0) {
-      struct intel_renderbuffer *irbFront
-         = intel_get_renderbuffer(ctx->DrawBuffer, BUFFER_FRONT_LEFT);
-      struct intel_renderbuffer *irbBack
-         = intel_get_renderbuffer(ctx->DrawBuffer, BUFFER_BACK_LEFT);
-      if (irbBack) {
-         /* double buffered */
-         if (intel->sarea->pf_current_page == 0) {
-            irbFront->pfMap = irbFront->region->map;
-            irbFront->pfPitch = irbFront->region->pitch;
-            irbBack->pfMap = irbBack->region->map;
-            irbBack->pfPitch = irbBack->region->pitch;
-         }
-         else {
-            irbFront->pfMap = irbBack->region->map;
-            irbFront->pfPitch = irbBack->region->pitch;
-            irbBack->pfMap = irbFront->region->map;
-            irbBack->pfPitch = irbFront->region->pitch;
-         }
-      }
-   }
-#endif
+   if (map)
+      intel_renderbuffer_map(intel, ctx->ReadBuffer->_ColorReadBuffer);
+   else
+      intel_renderbuffer_unmap(intel, ctx->ReadBuffer->_ColorReadBuffer);
 
    /* depth buffer (Note wrapper!) */
    if (ctx->DrawBuffer->_DepthBuffer) {
-      irb = intel_renderbuffer(ctx->DrawBuffer->_DepthBuffer->Wrapped);
-      if (irb && irb->region) {
-         if (map) {
-            intel_region_map(intel, irb->region);
-            irb->pfMap = irb->region->map;
-            irb->pfPitch = irb->region->pitch;
-         }
-         else {
-            intel_region_unmap(intel, irb->region);
-            irb->pfMap = irb->region->map;
-            irb->pfPitch = irb->region->pitch;
-         }
-      }
+      if (map)
+        intel_renderbuffer_map(intel, ctx->DrawBuffer->_DepthBuffer->Wrapped);
+      else
+        intel_renderbuffer_unmap(intel,
+                                 ctx->DrawBuffer->_DepthBuffer->Wrapped);
    }
 
    /* stencil buffer (Note wrapper!) */
    if (ctx->DrawBuffer->_StencilBuffer) {
-      irb = intel_renderbuffer(ctx->DrawBuffer->_StencilBuffer->Wrapped);
-      if (irb && irb->region) {
-         if (map) {
-            intel_region_map(intel, irb->region);
-            irb->pfMap = irb->region->map;
-            irb->pfPitch = irb->region->pitch;
-         }
-         else {
-            intel_region_unmap(intel, irb->region);
-            irb->pfMap = irb->region->map;
-            irb->pfPitch = irb->region->pitch;
-         }
-      }
+      if (map)
+        intel_renderbuffer_map(intel,
+                               ctx->DrawBuffer->_StencilBuffer->Wrapped);
+      else
+        intel_renderbuffer_unmap(intel,
+                                 ctx->DrawBuffer->_StencilBuffer->Wrapped);
    }
 }
 
@@ -612,19 +630,10 @@ intelSpanRenderStart(GLcontext * ctx)
    struct intel_context *intel = intel_context(ctx);
    GLuint i;
 
-   intelFinish(&intel->ctx);
+   intelFlush(&intel->ctx);
    LOCK_HARDWARE(intel);
 
-#if 0
-   /* Just map the framebuffer and all textures.  Bufmgr code will
-    * take care of waiting on the necessary fences:
-    */
-   intel_region_map(intel, intel->front_region);
-   intel_region_map(intel, intel->back_region);
-   intel_region_map(intel, intel->depth_region);
-#endif
-
-   for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
+   for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
       if (ctx->Texture.Unit[i]._ReallyEnabled) {
          struct gl_texture_object *texObj = ctx->Texture.Unit[i]._Current;
          intel_tex_map_images(intel, intel_texture_object(texObj));
@@ -646,15 +655,7 @@ intelSpanRenderFinish(GLcontext * ctx)
 
    _swrast_flush(ctx);
 
-   /* Now unmap the framebuffer:
-    */
-#if 0
-   intel_region_unmap(intel, intel->front_region);
-   intel_region_unmap(intel, intel->back_region);
-   intel_region_unmap(intel, intel->depth_region);
-#endif
-
-   for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
+   for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
       if (ctx->Texture.Unit[i]._ReallyEnabled) {
          struct gl_texture_object *texObj = ctx->Texture.Unit[i]._Current;
          intel_tex_unmap_images(intel, intel_texture_object(texObj));
@@ -680,49 +681,76 @@ intelInitSpanFuncs(GLcontext * ctx)
  * Plug in appropriate span read/write functions for the given renderbuffer.
  * These are used for the software fallbacks.
  */
-void
-intel_set_span_functions(struct gl_renderbuffer *rb, enum tiling_mode tiling)
+static void
+intel_set_span_functions(struct intel_context *intel,
+                        struct gl_renderbuffer *rb)
 {
+   struct intel_renderbuffer *irb = (struct intel_renderbuffer *) rb;
+   uint32_t tiling;
+
+   /* If in GEM mode, we need to do the tile address swizzling ourselves,
+    * instead of the fence registers handling it.
+    */
+   if (intel->ttm)
+      tiling = irb->region->tiling;
+   else
+      tiling = I915_TILING_NONE;
+
    if (rb->_ActualFormat == GL_RGB5) {
       /* 565 RGB */
       switch (tiling) {
-      case INTEL_TILE_NONE:
+      case I915_TILING_NONE:
       default:
         intelInitPointers_RGB565(rb);
         break;
-      case INTEL_TILE_X:
+      case I915_TILING_X:
         intel_XTile_InitPointers_RGB565(rb);
         break;
-      case INTEL_TILE_Y:
+      case I915_TILING_Y:
         intel_YTile_InitPointers_RGB565(rb);
         break;
       }
    }
+   else if (rb->_ActualFormat == GL_RGB8) {
+      /* 8888 RGBx */
+      switch (tiling) {
+      case I915_TILING_NONE:
+      default:
+        intelInitPointers_xRGB8888(rb);
+        break;
+      case I915_TILING_X:
+        intel_XTile_InitPointers_xRGB8888(rb);
+        break;
+      case I915_TILING_Y:
+        intel_YTile_InitPointers_xRGB8888(rb);
+        break;
+      }
+   }
    else if (rb->_ActualFormat == GL_RGBA8) {
       /* 8888 RGBA */
       switch (tiling) {
-      case INTEL_TILE_NONE:
+      case I915_TILING_NONE:
       default:
         intelInitPointers_ARGB8888(rb);
         break;
-      case INTEL_TILE_X:
+      case I915_TILING_X:
         intel_XTile_InitPointers_ARGB8888(rb);
         break;
-      case INTEL_TILE_Y:
+      case I915_TILING_Y:
         intel_YTile_InitPointers_ARGB8888(rb);
         break;
       }
    }
    else if (rb->_ActualFormat == GL_DEPTH_COMPONENT16) {
       switch (tiling) {
-      case INTEL_TILE_NONE:
+      case I915_TILING_NONE:
       default:
         intelInitDepthPointers_z16(rb);
         break;
-      case INTEL_TILE_X:
+      case I915_TILING_X:
         intel_XTile_InitDepthPointers_z16(rb);
         break;
-      case INTEL_TILE_Y:
+      case I915_TILING_Y:
         intel_YTile_InitDepthPointers_z16(rb);
         break;
       }
@@ -730,28 +758,28 @@ intel_set_span_functions(struct gl_renderbuffer *rb, enum tiling_mode tiling)
    else if (rb->_ActualFormat == GL_DEPTH_COMPONENT24 ||        /* XXX FBO remove */
             rb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT) {
       switch (tiling) {
-      case INTEL_TILE_NONE:
+      case I915_TILING_NONE:
       default:
         intelInitDepthPointers_z24_s8(rb);
         break;
-      case INTEL_TILE_X:
+      case I915_TILING_X:
         intel_XTile_InitDepthPointers_z24_s8(rb);
         break;
-      case INTEL_TILE_Y:
+      case I915_TILING_Y:
         intel_YTile_InitDepthPointers_z24_s8(rb);
         break;
       }
    }
    else if (rb->_ActualFormat == GL_STENCIL_INDEX8_EXT) {
       switch (tiling) {
-      case INTEL_TILE_NONE:
+      case I915_TILING_NONE:
       default:
         intelInitStencilPointers_z24_s8(rb);
         break;
-      case INTEL_TILE_X:
+      case I915_TILING_X:
         intel_XTile_InitStencilPointers_z24_s8(rb);
         break;
-      case INTEL_TILE_Y:
+      case I915_TILING_Y:
         intel_YTile_InitStencilPointers_z24_s8(rb);
         break;
       }