Merge commit 'origin/master' into gallium-0.2
[mesa.git] / src / mesa / drivers / dri / intel / intel_span.c
index 44e2eff680f1579e546490f32af7c5d274fd5f6b..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"
@@ -43,61 +43,97 @@ static void
 intel_set_span_functions(struct intel_context *intel,
                         struct gl_renderbuffer *rb);
 
+#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)
 {
-   uint32_t val;
+   get_span_cache(irb, offset);
+
+   return *(uint32_t *)(irb->span_cache + (offset & (SPAN_CACHE_SIZE - 1)));
+}
 
-   dri_bo_get_subdata(irb->region->buffer, offset, 4, &val);
+static uint32_t
+pread_xrgb8888(struct intel_renderbuffer *irb, uint32_t offset)
+{
+   get_span_cache(irb, offset);
 
-   return val;
+   return *(uint32_t *)(irb->span_cache + (offset & (SPAN_CACHE_SIZE - 1))) |
+      0xff000000;
 }
 
 static uint16_t
 pread_16(struct intel_renderbuffer *irb, uint32_t offset)
 {
-   uint16_t val;
-
-   dri_bo_get_subdata(irb->region->buffer, offset, 2, &val);
+   get_span_cache(irb, offset);
 
-   return val;
+   return *(uint16_t *)(irb->span_cache + (offset & (SPAN_CACHE_SIZE - 1)));
 }
 
 static uint8_t
 pread_8(struct intel_renderbuffer *irb, uint32_t offset)
 {
-   uint8_t val;
+   get_span_cache(irb, offset);
 
-   dri_bo_get_subdata(irb->region->buffer, offset, 1, &val);
-
-   return val;
+   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,
-                               struct intel_context *intel,
                                int x, int y)
 {
-       x += intel->drawX;
-       y += intel->drawY;
-
        return (y * irb->region->pitch + x) * irb->region->cpp;
 }
 
@@ -106,7 +142,6 @@ static uint32_t no_tile_swizzle(struct intel_renderbuffer *irb,
  */
 
 static uint32_t x_tile_swizzle(struct intel_renderbuffer *irb,
-                              struct intel_context *intel,
                               int x, int y)
 {
        int     tile_stride;
@@ -116,9 +151,6 @@ static uint32_t x_tile_swizzle(struct intel_renderbuffer *irb,
        int     tile_off, tile_base;
        
        tile_stride = (irb->pfPitch * irb->region->cpp) << 3;
-       
-       x += intel->drawX;
-       y += intel->drawY;
 
        xbyte = x * irb->region->cpp;
 
@@ -165,7 +197,6 @@ static uint32_t x_tile_swizzle(struct intel_renderbuffer *irb,
 }
 
 static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb,
-                              struct intel_context *intel,
                               int x, int y)
 {
        int     tile_stride;
@@ -175,9 +206,6 @@ static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb,
        int     tile_off, tile_base;
        
        tile_stride = (irb->pfPitch * irb->region->cpp) << 5;
-       
-       x += intel->drawX;
-       y += intel->drawY;
 
        xbyte = x * irb->region->cpp;
 
@@ -229,8 +257,12 @@ static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb,
    struct intel_renderbuffer *irb = intel_renderbuffer(rb);            \
    const GLint yScale = irb->RenderToTexture ? 1 : -1;                 \
    const GLint yBias = irb->RenderToTexture ? 0 : irb->Base.Height - 1;        \
+   unsigned int num_cliprects;                                         \
+   struct drm_clip_rect *cliprects;                                    \
+   int x_off, y_off;                                                   \
    GLuint p;                                                           \
-   (void) p;
+   (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.
@@ -238,12 +270,12 @@ static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb,
  */
 #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
       }}
@@ -256,6 +288,11 @@ static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb,
 
 #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
@@ -263,8 +300,8 @@ static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb,
 
 #define TAG(x)    intel##x##_RGB565
 #define TAG2(x,y) intel##x##_RGB565##y
-#define GET_VALUE(X, Y) pread_16(irb, no_tile_swizzle(irb, intel, X, Y))
-#define PUT_VALUE(X, Y, V) pwrite_16(irb, no_tile_swizzle(irb, intel, X, Y), V)
+#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
@@ -274,8 +311,19 @@ static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb,
 
 #define TAG(x)    intel##x##_ARGB8888
 #define TAG2(x,y) intel##x##_ARGB8888##y
-#define GET_VALUE(X, Y) pread_32(irb, no_tile_swizzle(irb, intel, X, Y))
-#define PUT_VALUE(X, Y, V) pwrite_32(irb, no_tile_swizzle(irb, intel, X, Y), V)
+#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
@@ -286,8 +334,8 @@ static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb,
 
 #define TAG(x)    intel_XTile_##x##_RGB565
 #define TAG2(x,y) intel_XTile_##x##_RGB565##y
-#define GET_VALUE(X, Y) pread_16(irb, x_tile_swizzle(irb, intel, X, Y))
-#define PUT_VALUE(X, Y, V) pwrite_16(irb, x_tile_swizzle(irb, intel, X, Y), V)
+#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
@@ -295,8 +343,8 @@ static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb,
 
 #define TAG(x)    intel_YTile_##x##_RGB565
 #define TAG2(x,y) intel_YTile_##x##_RGB565##y
-#define GET_VALUE(X, Y) pread_16(irb, y_tile_swizzle(irb, intel, X, Y))
-#define PUT_VALUE(X, Y, V) pwrite_16(irb, y_tile_swizzle(irb, intel, X, Y), V)
+#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
@@ -307,8 +355,8 @@ static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb,
 
 #define TAG(x)    intel_XTile_##x##_ARGB8888
 #define TAG2(x,y) intel_XTile_##x##_ARGB8888##y
-#define GET_VALUE(X, Y) pread_32(irb, x_tile_swizzle(irb, intel, X, Y))
-#define PUT_VALUE(X, Y, V) pwrite_32(irb, x_tile_swizzle(irb, intel, X, Y), V)
+#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
@@ -316,15 +364,40 @@ static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb,
 
 #define TAG(x)    intel_YTile_##x##_ARGB8888
 #define TAG2(x,y) intel_YTile_##x##_ARGB8888##y
-#define GET_VALUE(X, Y) pread_32(irb, y_tile_swizzle(irb, intel, X, Y))
-#define PUT_VALUE(X, Y, V) pwrite_32(irb, y_tile_swizzle(irb, intel, X, Y), V)
+#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 GLint yScale = irb->RenderToTexture ? 1 : -1;                 \
-   const GLint yBias = irb->RenderToTexture ? 0 : irb->Base.Height - 1;
+   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
@@ -332,10 +405,9 @@ static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb,
 /**
  ** 16-bit depthbuffer functions.
  **/
-#define WRITE_DEPTH(_x, _y, d) \
-   pwrite_16(irb, no_tile_swizzle(irb, intel, _x, _y), d)
-#define READ_DEPTH(d, _x, _y) \
-   d = pread_16(irb, no_tile_swizzle(irb, intel, _x, _y))
+#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"
 
@@ -343,20 +415,18 @@ static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb,
 /**
  ** 16-bit x tile depthbuffer functions.
  **/
-#define WRITE_DEPTH(_x, _y, d) \
-   pwrite_16(irb, x_tile_swizzle(irb, intel, _x, _y), d)
-#define READ_DEPTH(d, _x, _y) \
-   d = pread_16(irb, 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) \
-   pwrite_16(irb, y_tile_swizzle(irb, intel, _x, _y), d)
-#define READ_DEPTH(d, _x, _y) \
-   d = pread_16(irb, 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"
 
@@ -367,14 +437,15 @@ static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb,
  ** 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)                                 \
-   pwrite_32(irb, no_tile_swizzle(irb, intel, _x, _y),         \
-            ((d) >> 8) | ((d) << 24))
+   pwrite_32(irb, NO_TILE(_x, _y), ((d) >> 8) | ((d) << 24))
 
 /* Change SZZZ -> ZZZS */
 #define READ_DEPTH( d, _x, _y ) {                              \
-   GLuint tmp = pread_32(irb, no_tile_swizzle(irb, intel, _x, _y));    \
+   GLuint tmp = pread_32(irb, NO_TILE(_x, _y));                        \
    d = (tmp << 8) | (tmp >> 24);                               \
 }
 
@@ -388,14 +459,15 @@ static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb,
  ** 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)                                 \
-   pwrite_32(irb, x_tile_swizzle(irb, intel, _x, _y),          \
-            ((d) >> 8) | ((d) << 24))                          \
+   pwrite_32(irb, X_TILE(_x, _y), ((d) >> 8) | ((d) << 24))
 
 /* Change SZZZ -> ZZZS */
 #define READ_DEPTH( d, _x, _y ) {                              \
-   GLuint tmp = pread_32(irb, x_tile_swizzle(irb, intel, _x, _y));     \
+   GLuint tmp = pread_32(irb, X_TILE(_x, _y));         \
    d = (tmp << 8) | (tmp >> 24);                               \
 }
 
@@ -408,14 +480,15 @@ static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb,
  ** 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)                                 \
-   pwrite_32(irb, y_tile_swizzle(irb, intel, _x, _y),          \
-            ((d) >> 8) | ((d) << 24))
+   pwrite_32(irb, Y_TILE(_x, _y), ((d) >> 8) | ((d) << 24))
 
 /* Change SZZZ -> ZZZS */
 #define READ_DEPTH( d, _x, _y ) {                              \
-   GLuint tmp = pread_32(irb, y_tile_swizzle(irb, intel, _x, _y));     \
+   GLuint tmp = pread_32(irb, Y_TILE(_x, _y));                 \
    d = (tmp << 8) | (tmp >> 24);                               \
 }
 
@@ -426,36 +499,24 @@ static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb,
 /**
  ** 8-bit stencil function (XXX FBO: This is obsolete)
  **/
-#define WRITE_STENCIL(_x, _y, d)                               \
-   pwrite_8(irb, no_tile_swizzle(irb, intel, _x, _y) + 3, d)
-
-#define READ_STENCIL(d, _x, _y)                                        \
-   d = pread_8(irb, no_tile_swizzle(irb, intel, _x, _y) + 3);
-
+#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)                               \
-   pwrite_8(irb, x_tile_swizzle(irb, intel, _x, _y) + 3, d)
-
-#define READ_STENCIL(d, _x, _y)                                        \
-   d = pread_8(irb, x_tile_swizzle(irb, intel, _x, _y) + 3);
-
+#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)                               \
-   pwrite_8(irb, y_tile_swizzle(irb, intel, _x, _y) + 3, d)
-
-#define READ_STENCIL(d, _x, _y)                                        \
-   d = pread_8(irb, y_tile_swizzle(irb, intel, _x, _y) + 3)
-
+#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"
 
@@ -481,6 +542,7 @@ intel_renderbuffer_unmap(struct intel_context *intel,
    if (irb == NULL || irb->region == NULL)
       return;
 
+   clear_span_cache(irb);
    irb->pfPitch = 0;
 
    rb->GetRow = NULL;
@@ -521,14 +583,10 @@ 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));
-         }
       }
    }
 
@@ -575,7 +633,7 @@ intelSpanRenderStart(GLcontext * ctx)
    intelFlush(&intel->ctx);
    LOCK_HARDWARE(intel);
 
-   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));
@@ -597,7 +655,7 @@ intelSpanRenderFinish(GLcontext * ctx)
 
    _swrast_flush(ctx);
 
-   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));
@@ -653,6 +711,21 @@ intel_set_span_functions(struct intel_context *intel,
         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) {