i965g: more work on compilation -- surface management
authorKeith Whitwell <keithw@vmware.com>
Sun, 1 Nov 2009 12:08:14 +0000 (12:08 +0000)
committerKeith Whitwell <keithw@vmware.com>
Sun, 1 Nov 2009 12:08:14 +0000 (12:08 +0000)
src/gallium/drivers/i965/brw_context.h
src/gallium/drivers/i965/brw_defines.h
src/gallium/drivers/i965/brw_screen.h
src/gallium/drivers/i965/brw_screen_surface.c
src/gallium/drivers/i965/brw_screen_texture.c
src/gallium/drivers/i965/brw_state.h
src/gallium/drivers/i965/brw_state_cache.c
src/gallium/drivers/i965/brw_structs.h
src/gallium/drivers/i965/brw_wm_surface_state.c

index 8067e20c968eeab6cbd85d8f661843a656ad9b5e..471855ab63c7607d3edb64b1249c64a69c427543 100644 (file)
@@ -146,6 +146,8 @@ struct brw_blend_state {
    struct brw_cc3 cc3;
    struct brw_cc5 cc5;
    struct brw_cc6 cc6;
+
+   struct brw_surf_ss0 ss0;
 };
 
 
@@ -501,15 +503,14 @@ struct brw_context
       const struct brw_rasterizer_state *rast;
       const struct brw_depth_stencil_state *zstencil;
 
-      const struct brw_texture *texture[PIPE_MAX_SAMPLERS];
       const struct brw_sampler *sampler[PIPE_MAX_SAMPLERS];
-      unsigned num_textures;
+      const struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];
+      unsigned num_vertex_elements;
       unsigned num_samplers;
-      
 
-      struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];
+      struct brw_texture *texture[PIPE_MAX_SAMPLERS];
       struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
-      unsigned num_vertex_elements;
+      unsigned num_textures;
       unsigned num_vertex_buffers;
 
       struct pipe_scissor_state scissor;
index 544d36306cdb20a3cf55290c2df087b7c11cb93c..65cd71c939c01d94b33e3fe2dbeed787e6f49dde 100644 (file)
 #define URB_SIZES(brw)                  (BRW_IS_IGDNG(brw) ? 1024 : \
                                          (BRW_IS_G4X(brw) ? 384 : 256))  /* 512 bit units */
 
+
+#define BRW_TILING_NONE  0
+#define BRW_TILING_Y     1
+#define BRW_TILING_X     2
+
 #endif
index efa27db1e0f554082671ee1829fd54f4b0307eaa..844c6355d501022955203286b4ab12b0c56fda81 100644 (file)
@@ -32,6 +32,7 @@
 #include "pipe/p_screen.h"
 
 #include "brw_reg.h"
+#include "brw_structs.h"
 
 struct brw_winsys_screen;
 
@@ -68,10 +69,23 @@ struct brw_texture
 {
    struct pipe_texture base;
 
-   ubyte shader_swizzle;
+   struct brw_winsys_buffer *bo;
+   struct brw_surface_state ss;
+
+   unsigned brw_target;
+   unsigned pitch;
+   unsigned tiling;
+   unsigned cpp;
 };
 
 
+struct brw_surface
+{
+   struct pipe_surface base;
+   struct brw_surface_state ss;
+   struct brw_winsys_buffer *bo;
+};
+
 /*
  * Cast wrappers
  */
@@ -87,6 +101,12 @@ brw_transfer(struct pipe_transfer *transfer)
    return (struct brw_transfer *)transfer;
 }
 
+static INLINE struct brw_surface *
+brw_surface(struct pipe_surface *surface)
+{
+   return (struct brw_surface *)surface;
+}
+
 static INLINE struct brw_buffer *
 brw_buffer(struct pipe_buffer *buffer)
 {
index e0df6cc629b74426f0d0c0e551b8c79dd491cdac..01d4b2d2b1a51f0fbc3b06a914135566f901d70b 100644 (file)
@@ -2,6 +2,123 @@
 #include "pipe/p_screen.h"
 #include "brw_screen.h"
 
+
+/**
+ * Sets up a surface state structure to point at the given region.
+ * While it is only used for the front/back buffer currently, it should be
+ * usable for further buffers when doing ARB_draw_buffer support.
+ */
+static void
+brw_update_renderbuffer_surface(struct brw_context *brw,
+                               struct gl_renderbuffer *rb,
+                               unsigned int unit)
+{
+   struct brw_winsys_buffer *region_bo = NULL;
+   struct intel_renderbuffer *irb = intel_renderbuffer(rb);
+   struct intel_region *region = irb ? irb->region : NULL;
+   struct {
+      unsigned int surface_type;
+      unsigned int surface_format;
+      unsigned int width, height, pitch, cpp;
+      GLubyte color_mask[4];
+      GLboolean color_blend;
+      uint32_t tiling;
+      uint32_t draw_offset;
+   } key;
+
+   memset(&key, 0, sizeof(key));
+
+   if (region != NULL) {
+      region_bo = region->buffer;
+
+      key.surface_type = BRW_SURFACE_2D;
+      switch (irb->texformat->MesaFormat) {
+      case PIPE_FORMAT_ARGB8888:
+        key.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
+        break;
+      case PIPE_FORMAT_RGB565:
+        key.surface_format = BRW_SURFACEFORMAT_B5G6R5_UNORM;
+        break;
+      case PIPE_FORMAT_ARGB1555:
+        key.surface_format = BRW_SURFACEFORMAT_B5G5R5A1_UNORM;
+        break;
+      case PIPE_FORMAT_ARGB4444:
+        key.surface_format = BRW_SURFACEFORMAT_B4G4R4A4_UNORM;
+        break;
+      default:
+        debug_printf("Bad renderbuffer format: %d\n",
+                     irb->texformat->MesaFormat);
+        assert(0);
+        key.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
+        return;
+      }
+      key.tiling = region->tiling;
+      if (brw->intel.intelScreen->driScrnPriv->dri2.enabled) {
+        key.width = rb->Width;
+        key.height = rb->Height;
+      } else {
+        key.width = region->width;
+        key.height = region->height;
+      }
+      key.pitch = region->pitch;
+      key.cpp = region->cpp;
+      key.draw_offset = region->draw_offset; /* cur 3d or cube face offset */
+   } 
+
+   memcpy(key.color_mask, ctx->Color.ColorMask,
+         sizeof(key.color_mask));
+
+   key.color_blend = (!ctx->Color._LogicOpEnabled &&
+                     ctx->Color.BlendEnabled);
+
+   brw->sws->bo_unreference(brw->wm.surf_bo[unit]);
+   brw->wm.surf_bo[unit] = brw_search_cache(&brw->surface_cache,
+                                           BRW_SS_SURFACE,
+                                           &key, sizeof(key),
+                                           &region_bo, 1,
+                                           NULL);
+
+   if (brw->wm.surf_bo[unit] == NULL) {
+      struct brw_surface_state surf;
+
+      memset(&surf, 0, sizeof(surf));
+
+      surf.ss0.surface_format = key.surface_format;
+      surf.ss0.surface_type = key.surface_type;
+      if (key.tiling == I915_TILING_NONE) {
+        surf.ss1.base_addr = key.draw_offset;
+      } else {
+        uint32_t tile_offset = key.draw_offset % 4096;
+
+        surf.ss1.base_addr = key.draw_offset - tile_offset;
+
+        assert(BRW_IS_G4X(brw) || tile_offset == 0);
+        if (BRW_IS_G4X(brw)) {
+           if (key.tiling == I915_TILING_X) {
+              /* Note that the low bits of these fields are missing, so
+               * there's the possibility of getting in trouble.
+               */
+              surf.ss5.x_offset = (tile_offset % 512) / key.cpp / 4;
+              surf.ss5.y_offset = tile_offset / 512 / 2;
+           } else {
+              surf.ss5.x_offset = (tile_offset % 128) / key.cpp / 4;
+              surf.ss5.y_offset = tile_offset / 128 / 2;
+           }
+        }
+      }
+
+      if (region_bo != NULL)
+        surf.ss1.base_addr += region_bo->offset; /* reloc */
+
+      surf.ss2.width = key.width - 1;
+      surf.ss2.height = key.height - 1;
+      brw_set_surface_tiling(&surf, key.tiling);
+      surf.ss3.pitch = (key.pitch * key.cpp) - 1;
+
+}
+
+
+
 struct brw_surface_id {
    unsigned face:3;
    unsigned zslice:13;
index 50c30878c6f1dd22275da33dd6d06ec818d1c4a1..3d069add6fc6ba99343d3b2c556264330985f4ab 100644 (file)
 
 #define FILE_DEBUG_FLAG DEBUG_MIPTREE
 
+
+
+static GLuint translate_tex_target( unsigned target )
+{
+   switch (target) {
+   case PIPE_TEXTURE_1D: 
+      return BRW_SURFACE_1D;
+
+   case PIPE_TEXTURE_2D: 
+      return BRW_SURFACE_2D;
+
+   case PIPE_TEXTURE_3D: 
+      return BRW_SURFACE_3D;
+
+   case PIPE_TEXTURE_CUBE:
+      return BRW_SURFACE_CUBE;
+
+   default: 
+      assert(0); 
+      return BRW_SURFACE_1D;
+   }
+}
+
+
+static GLuint translate_tex_format( enum pipe_format pf )
+{
+   switch( pf ) {
+   case PIPE_FORMAT_L8_UNORM:
+      return BRW_SURFACEFORMAT_L8_UNORM;
+
+   case PIPE_FORMAT_I8_UNORM:
+      return BRW_SURFACEFORMAT_I8_UNORM;
+
+   case PIPE_FORMAT_A8_UNORM:
+      return BRW_SURFACEFORMAT_A8_UNORM; 
+
+   case PIPE_FORMAT_A8L8_UNORM:
+      return BRW_SURFACEFORMAT_L8A8_UNORM;
+
+   case PIPE_FORMAT_A8R8G8B8_UNORM: /* XXX */
+   case PIPE_FORMAT_B8G8R8A8_UNORM: /* XXX */
+   case PIPE_FORMAT_R8G8B8A8_UNORM: /* XXX */
+      return BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
+
+   case PIPE_FORMAT_R8G8B8X8_UNORM:
+      return BRW_SURFACEFORMAT_R8G8B8X8_UNORM;
+
+   case PIPE_FORMAT_R5G6B5_UNORM:
+      return BRW_SURFACEFORMAT_B5G6R5_UNORM;
+
+   case PIPE_FORMAT_A1R5G5B5_UNORM:
+      return BRW_SURFACEFORMAT_B5G5R5A1_UNORM;
+
+   case PIPE_FORMAT_A4R4G4B4_UNORM:
+      return BRW_SURFACEFORMAT_B4G4R4A4_UNORM;
+
+
+   case PIPE_FORMAT_L16_UNORM:
+      return BRW_SURFACEFORMAT_L16_UNORM;
+
+      /* XXX: Z texturing: 
+   case PIPE_FORMAT_I16_UNORM:
+      return BRW_SURFACEFORMAT_I16_UNORM;
+       */
+
+      /* XXX: Z texturing:
+   case PIPE_FORMAT_A16_UNORM:
+      return BRW_SURFACEFORMAT_A16_UNORM; 
+      */
+
+   case PIPE_FORMAT_YCBCR_REV:
+      return BRW_SURFACEFORMAT_YCRCB_NORMAL;
+
+   case PIPE_FORMAT_YCBCR:
+      return BRW_SURFACEFORMAT_YCRCB_SWAPUVY;
+
+      /* XXX: Add FXT to gallium?
+   case PIPE_FORMAT_FXT1_RGBA:
+      return BRW_SURFACEFORMAT_FXT1;
+      */
+
+   case PIPE_FORMAT_DXT1_RGB:
+       return BRW_SURFACEFORMAT_DXT1_RGB;
+
+   case PIPE_FORMAT_DXT1_RGBA:
+       return BRW_SURFACEFORMAT_BC1_UNORM;
+       
+   case PIPE_FORMAT_DXT3_RGBA:
+       return BRW_SURFACEFORMAT_BC2_UNORM;
+       
+   case PIPE_FORMAT_DXT5_RGBA:
+       return BRW_SURFACEFORMAT_BC3_UNORM;
+
+   case PIPE_FORMAT_R8G8B8A8_SRGB:
+      return BRW_SURFACEFORMAT_B8G8R8A8_UNORM_SRGB;
+
+   case PIPE_FORMAT_A8L8_SRGB:
+      return BRW_SURFACEFORMAT_L8A8_UNORM_SRGB;
+
+   case PIPE_FORMAT_L8_SRGB:
+      return BRW_SURFACEFORMAT_L8_UNORM_SRGB;
+
+   case PIPE_FORMAT_DXT1_SRGB:
+      return BRW_SURFACEFORMAT_BC1_UNORM_SRGB;
+
+      /* XXX: which pipe depth formats does i965 suppport
+       */
+   case PIPE_FORMAT_S8Z24_UNORM:
+   case PIPE_FORMAT_X8Z24_UNORM:
+   case PIPE_FORMAT_Z24S8_UNORM:
+   case PIPE_FORMAT_Z24X8_UNORM:
+         return BRW_SURFACEFORMAT_I24X8_UNORM;
+
+#if 0
+      /* XXX: these different surface formats don't seem to
+       * make any difference for shadow sampler/compares.
+       */
+      if (depth_mode == GL_INTENSITY) 
+         return BRW_SURFACEFORMAT_I24X8_UNORM;
+      else if (depth_mode == GL_ALPHA)
+         return BRW_SURFACEFORMAT_A24X8_UNORM;
+      else
+         return BRW_SURFACEFORMAT_L24X8_UNORM;
+#endif
+
+      /* XXX: presumably for bump mapping.  Add this to mesa state
+       * tracker?
+       */
+   case PIPE_FORMAT_R8G8_SNORM:
+      return BRW_SURFACEFORMAT_R8G8_SNORM;
+
+   case PIPE_FORMAT_R8G8B8A8_SNORM:
+      return BRW_SURFACEFORMAT_R8G8B8A8_SNORM;
+
+   default:
+      assert(0);
+      return 0;
+   }
+}
+
+static void
+brw_set_surface_tiling(struct brw_surface_state *surf, uint32_t tiling)
+{
+   switch (tiling) {
+   case BRW_TILING_NONE:
+      surf->ss3.tiled_surface = 0;
+      surf->ss3.tile_walk = 0;
+      break;
+   case BRW_TILING_X:
+      surf->ss3.tiled_surface = 1;
+      surf->ss3.tile_walk = BRW_TILEWALK_XMAJOR;
+      break;
+   case BRW_TILING_Y:
+      surf->ss3.tiled_surface = 1;
+      surf->ss3.tile_walk = BRW_TILEWALK_YMAJOR;
+      break;
+   }
+}
+
+
 GLboolean brw_miptree_layout(struct brw_context *brw,
                             struct intel_mipmap_tree *mt,
                             uint32_t tiling)
@@ -216,3 +376,58 @@ GLboolean brw_miptree_layout(struct brw_context *brw,
    return GL_TRUE;
 }
 
+
+static void brw_create_texture( struct pipe_screen *screen,
+                               const pipe_texture *templ )
+
+{  
+
+   key.format = tex->base.format;
+   key.pitch = tex->pitch;
+   key.depth = tex->base.depth[0];
+   key.bo = tex->buffer;
+   key.offset = 0;
+
+   key.target = tex->brw_target;       /* translated to BRW enum */
+   //key.depthmode = 0; /* XXX: add this to gallium? or the state tracker? */
+   key.last_level = tex->base.last_level;
+   key.width = tex->base.depth[0];
+   key.height = tex->base.height[0];
+   key.cpp = tex->cpp;
+   key.tiling = tex->tiling;
+
+
+
+   surf.ss0.mipmap_layout_mode = BRW_SURFACE_MIPMAPLAYOUT_BELOW;
+   surf.ss0.surface_type = translate_tex_target(key->target);
+   surf.ss0.surface_format = translate_tex_format(key->format /* , key->depthmode */ );
+
+   /* This is ok for all textures with channel width 8bit or less:
+    */
+/*    surf.ss0.data_return_format = BRW_SURFACERETURNFORMAT_S1; */
+   assert(key->bo);
+   surf.ss1.base_addr = key->bo->offset; /* reloc */
+   surf.ss2.mip_count = key->last_level;
+   surf.ss2.width = key->width - 1;
+   surf.ss2.height = key->height - 1;
+   brw_set_surface_tiling(&surf, key->tiling);
+   surf.ss3.pitch = (key->pitch * key->cpp) - 1;
+   surf.ss3.depth = key->depth - 1;
+
+   surf.ss4.min_lod = 0;
+   if (key->target == PIPE_TEXTURE_CUBE) {
+      surf.ss0.cube_pos_x = 1;
+      surf.ss0.cube_pos_y = 1;
+      surf.ss0.cube_pos_z = 1;
+      surf.ss0.cube_neg_x = 1;
+      surf.ss0.cube_neg_y = 1;
+      surf.ss0.cube_neg_z = 1;
+   }
+
+}
+
+
+
+
+
index 2275e9ad690fd5094305b8cca7267ffea01707b3..b47b04fd46ff56c872565f1449326867a9ef5e58 100644 (file)
@@ -94,19 +94,6 @@ const struct brw_tracked_state brw_indices;
 const struct brw_tracked_state brw_vertices;
 const struct brw_tracked_state brw_index_buffer;
 
-/**
- * Use same key for WM and VS surfaces.
- */
-struct brw_surface_key {
-   unsigned target;
-   struct brw_winsys_buffer *bo;
-   GLint format;
-   GLint first_level, last_level;
-   GLint width, height, depth;
-   GLint pitch, cpp;
-   uint32_t tiling;
-   GLuint offset;
-};
 
 /***********************************************************************
  * brw_state.c
@@ -171,9 +158,6 @@ void brw_clear_batch_cache( struct brw_context *brw );
 /***********************************************************************
  * brw_wm_surface_state.c 
  */
-struct brw_winsys_buffer *
-brw_create_constant_surface( struct brw_context *brw,
-                             struct brw_surface_key *key );
 
 /***********************************************************************
  * brw_state_debug.c
index 4310d01ba2e29632b8a9297efc8d79166e5acca2..9cf44f7a5cc299ee00f71f8ad97cf1984132f5d7 100644 (file)
@@ -179,7 +179,8 @@ brw_search_cache(struct brw_cache *cache,
                  enum brw_cache_id cache_id,
                  const void *key,
                  GLuint key_size,
-                 struct brw_winsys_buffer **reloc_bufs, GLuint nr_reloc_bufs,
+                 struct brw_winsys_buffer **reloc_bufs, 
+                GLuint nr_reloc_bufs,
                  void *aux_return)
 {
    struct brw_cache_item *item;
index f5d6a2599b42b0e6c756fc70d5b47001565b1be5..bf10bc04de75ebdf84c61a7abba2f092b96b4bd9 100644 (file)
@@ -1048,7 +1048,7 @@ struct brw_sf_viewport
  */
 struct brw_surface_state
 {
-   struct {
+   struct brw_surf_ss0 {
       GLuint cube_pos_z:1; 
       GLuint cube_neg_z:1; 
       GLuint cube_pos_y:1; 
@@ -1070,18 +1070,18 @@ struct brw_surface_state
       GLuint surface_type:3;       /**< BRW_SURFACE_1D/2D/3D/CUBE */
    } ss0;
    
-   struct {
+   struct brw_surf_ss1 {
       GLuint base_addr;  
    } ss1;
    
-   struct {
+   struct brw_surf_ss2 {
       GLuint pad:2;
       GLuint mip_count:4; 
       GLuint width:13; 
       GLuint height:13; 
    } ss2;
 
-   struct {
+   struct brw_surf_ss3 {
       GLuint tile_walk:1; 
       GLuint tiled_surface:1; 
       GLuint pad:1; 
@@ -1089,7 +1089,7 @@ struct brw_surface_state
       GLuint depth:11; 
    } ss3;
    
-   struct {
+   struct brw_surf_ss4 {
       GLuint multisample_position_palette_index:3;
       GLuint pad1:1;
       GLuint num_multisamples:3;
@@ -1099,7 +1099,7 @@ struct brw_surface_state
       GLuint min_lod:4; 
    } ss4;
 
-   struct {
+   struct brw_surf_ss5 {
       GLuint pad1:16;
       GLuint llc_mapping:1;
       GLuint mlc_mapping:1;
index 7157feb6f3913ec0174e4aaa55f8ba5678bcb049..88485c76cb4dad985086ba7d1890eafbf33b1fef 100644 (file)
   *   Keith Whitwell <keith@tungstengraphics.com>
   */
                    
+#include "pipe/p_format.h"
 
 #include "brw_batchbuffer.h"
 #include "brw_context.h"
 #include "brw_state.h"
 #include "brw_defines.h"
+#include "brw_screen.h"
 
 
-static GLuint translate_tex_target( GLenum target )
-{
-   switch (target) {
-   case GL_TEXTURE_1D: 
-      return BRW_SURFACE_1D;
-
-   case GL_TEXTURE_RECTANGLE_NV: 
-      return BRW_SURFACE_2D;
-
-   case GL_TEXTURE_2D: 
-      return BRW_SURFACE_2D;
-
-   case GL_TEXTURE_3D: 
-      return BRW_SURFACE_3D;
-
-   case GL_TEXTURE_CUBE_MAP: 
-      return BRW_SURFACE_CUBE;
-
-   default: 
-      assert(0); 
-      return 0;
-   }
-}
-
-
-static GLuint translate_tex_format( GLuint mesa_format, 
-                                   GLenum depth_mode )
-{
-   switch( pipe_format ) {
-   case PIPE_FORMAT_L8_UNORM:
-      return BRW_SURFACEFORMAT_L8_UNORM;
-
-   case PIPE_FORMAT_I8_UNORM:
-      return BRW_SURFACEFORMAT_I8_UNORM;
-
-   case PIPE_FORMAT_A8_UNORM:
-      return BRW_SURFACEFORMAT_A8_UNORM; 
-
-   case PIPE_FORMAT_A8L8_UNORM:
-      return BRW_SURFACEFORMAT_L8A8_UNORM;
-
-   case PIPE_FORMAT_A8R8G8B8_UNORM:
-   case PIPE_FORMAT_B8G8R8A8_UNORM:
-   case PIPE_FORMAT_R8G8B8A8_UNORM:
-      return BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
-
-   case PIPE_FORMAT_R8G8B8X8_UNORM:
-      return BRW_SURFACEFORMAT_R8G8B8X8_UNORM;
-
-   case PIPE_FORMAT_:
-      return BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
 
-   case PIPE_FORMAT_RGB565:
-      return BRW_SURFACEFORMAT_B5G6R5_UNORM;
-
-   case PIPE_FORMAT_ARGB1555:
-      return BRW_SURFACEFORMAT_B5G5R5A1_UNORM;
-
-   case PIPE_FORMAT_ARGB4444:
-      return BRW_SURFACEFORMAT_B4G4R4A4_UNORM;
-
-
-   case PIPE_FORMAT_L16_UNORM:
-      return BRW_SURFACEFORMAT_L16_UNORM;
-
-   case PIPE_FORMAT_I16_UNORM:
-      return BRW_SURFACEFORMAT_I16_UNORM;
-
-   case PIPE_FORMAT_A16_UNORM:
-      return BRW_SURFACEFORMAT_A16_UNORM; 
-
-   case PIPE_FORMAT_YCBCR_REV:
-      return BRW_SURFACEFORMAT_YCRCB_NORMAL;
-
-   case PIPE_FORMAT_YCBCR:
-      return BRW_SURFACEFORMAT_YCRCB_SWAPUVY;
-
-   case PIPE_FORMAT_RGB_FXT1:
-   case PIPE_FORMAT_RGBA_FXT1:
-      return BRW_SURFACEFORMAT_FXT1;
-
-   case PIPE_FORMAT_RGB_DXT1:
-       return BRW_SURFACEFORMAT_DXT1_RGB;
-
-   case PIPE_FORMAT_RGBA_DXT1:
-       return BRW_SURFACEFORMAT_BC1_UNORM;
-       
-   case PIPE_FORMAT_RGBA_DXT3:
-       return BRW_SURFACEFORMAT_BC2_UNORM;
-       
-   case PIPE_FORMAT_RGBA_DXT5:
-       return BRW_SURFACEFORMAT_BC3_UNORM;
-
-   case PIPE_FORMAT_R8G8B8A8_SRGB:
-      return BRW_SURFACEFORMAT_B8G8R8A8_UNORM_SRGB;
-
-   case PIPE_FORMAT_A8L8_SRGB:
-      return BRW_SURFACEFORMAT_L8A8_UNORM_SRGB;
-
-   case PIPE_FORMAT_L8_SRGB:
-      return BRW_SURFACEFORMAT_L8_UNORM_SRGB;
-
-   case PIPE_FORMAT_SRGB_DXT1:
-      return BRW_SURFACEFORMAT_BC1_UNORM_SRGB;
-
-   case PIPE_FORMAT_S8_Z24:
-      /* XXX: these different surface formats don't seem to
-       * make any difference for shadow sampler/compares.
-       */
-      if (depth_mode == GL_INTENSITY) 
-         return BRW_SURFACEFORMAT_I24X8_UNORM;
-      else if (depth_mode == GL_ALPHA)
-         return BRW_SURFACEFORMAT_A24X8_UNORM;
-      else
-         return BRW_SURFACEFORMAT_L24X8_UNORM;
-
-   case PIPE_FORMAT_DUDV8:
-      return BRW_SURFACEFORMAT_R8G8_SNORM;
-
-   case PIPE_FORMAT_SIGNED_RGBA8888_REV:
-      return BRW_SURFACEFORMAT_R8G8B8A8_SNORM;
-
-   default:
-      assert(0);
-      return 0;
-   }
-}
-
-static void
-brw_set_surface_tiling(struct brw_surface_state *surf, uint32_t tiling)
-{
-   switch (tiling) {
-   case I915_TILING_NONE:
-      surf->ss3.tiled_surface = 0;
-      surf->ss3.tile_walk = 0;
-      break;
-   case I915_TILING_X:
-      surf->ss3.tiled_surface = 1;
-      surf->ss3.tile_walk = BRW_TILEWALK_XMAJOR;
-      break;
-   case I915_TILING_Y:
-      surf->ss3.tiled_surface = 1;
-      surf->ss3.tile_walk = BRW_TILEWALK_YMAJOR;
-      break;
-   }
-}
-
-static struct brw_winsys_buffer *
-brw_create_texture_surface( struct brw_context *brw,
-                           struct brw_surface_key *key )
-{
-   struct brw_surface_state surf;
-   struct brw_winsys_buffer *bo;
-
-   memset(&surf, 0, sizeof(surf));
-
-   surf.ss0.mipmap_layout_mode = BRW_SURFACE_MIPMAPLAYOUT_BELOW;
-   surf.ss0.surface_type = translate_tex_target(key->target);
-   if (key->bo) {
-      surf.ss0.surface_format = translate_tex_format(key->format,
-                                                    key->internal_format,
-                                                    key->depthmode);
-   }
-   else {
-      switch (key->depth) {
-      case 32:
-         surf.ss0.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
-         break;
-      default:
-      case 24:
-         surf.ss0.surface_format = BRW_SURFACEFORMAT_B8G8R8X8_UNORM;
-         break;
-      case 16:
-         surf.ss0.surface_format = BRW_SURFACEFORMAT_B5G6R5_UNORM;
-         break;
-      }
-   }
-
-   /* This is ok for all textures with channel width 8bit or less:
-    */
-/*    surf.ss0.data_return_format = BRW_SURFACERETURNFORMAT_S1; */
-   if (key->bo)
-      surf.ss1.base_addr = key->bo->offset; /* reloc */
-   else
-      surf.ss1.base_addr = key->offset;
-
-   surf.ss2.mip_count = key->last_level;
-   surf.ss2.width = key->width - 1;
-   surf.ss2.height = key->height - 1;
-   brw_set_surface_tiling(&surf, key->tiling);
-   surf.ss3.pitch = (key->pitch * key->cpp) - 1;
-   surf.ss3.depth = key->depth - 1;
-
-   surf.ss4.min_lod = 0;
-   if (key->target == GL_TEXTURE_CUBE_MAP) {
-      surf.ss0.cube_pos_x = 1;
-      surf.ss0.cube_pos_y = 1;
-      surf.ss0.cube_pos_z = 1;
-      surf.ss0.cube_neg_x = 1;
-      surf.ss0.cube_neg_y = 1;
-      surf.ss0.cube_neg_z = 1;
-   }
-
-   bo = brw_upload_cache(&brw->surface_cache, BRW_SS_SURFACE,
-                        key, sizeof(*key),
-                        &key->bo, key->bo ? 1 : 0,
-                        &surf, sizeof(surf),
-                        NULL, NULL);
-
-   if (key->bo) {
-      /* Emit relocation to surface contents */
-      dri_bo_emit_reloc(bo,
-                       I915_GEM_DOMAIN_SAMPLER, 0,
-                       0,
-                       offsetof(struct brw_surface_state, ss1),
-                       key->bo);
-   }
-   return bo;
-}
 
 static void
-brw_update_texture_surface( struct brw_context *brw, GLuint unit )
+brw_update_texture_surface( struct brw_context *brw,
+                           struct brw_texture *tex,
+                           GLuint surf )
 {
-   struct pipe_texture *tex = brw->texture[unit];
-   struct brw_surface_key key;
-   const GLuint surf = SURF_INDEX_TEXTURE(unit);
-
-   memset(&key, 0, sizeof(key));
-
-   key.format = tex->base.format;
-   key.pitch = tex->pitch;
-   key.depth = tex->base.depth[0];
-   key.bo = tex->buffer;
-   key.offset = 0;
-
-   key.target = tObj->target;  /* translated to BRW enum */
-   /* key.depthmode = tObj->DepthMode; */ /* XXX: add this to gallium? or the state tracker? */
-   key.first_level = 0;
-   key.last_level = tex->base.last_level;
-   key.width = tex->base.depth[0];
-   key.height = tex->base.height[0];
-   key.cpp = tex->cpp;
-   key.tiling = tex->tiling;
-
-   brw->sws->bo_unreference(brw->wm.surf_bo[surf]);
    brw->wm.surf_bo[surf] = brw_search_cache(&brw->surface_cache,
                                             BRW_SS_SURFACE,
-                                            &key, sizeof(key),
-                                            &key.bo, key.bo ? 1 : 0,
+                                            &tex->ss, sizeof tex->ss,
+                                            &tex->bo, 1,
                                             NULL);
-   if (brw->wm.surf_bo[surf] == NULL) {
-      brw->wm.surf_bo[surf] = brw_create_texture_surface(brw, &key);
-   }
-}
-
-
-
-/**
- * Create the constant buffer surface.  Vertex/fragment shader constants will be
- * read from this buffer with Data Port Read instructions/messages.
- */
-struct brw_winsys_buffer *
-brw_create_constant_surface( struct brw_context *brw,
-                             struct brw_surface_key *key )
-{
-   const GLint w = key->width - 1;
-   struct brw_surface_state surf;
-   struct brw_winsys_buffer *bo;
-
-   memset(&surf, 0, sizeof(surf));
-
-   surf.ss0.mipmap_layout_mode = BRW_SURFACE_MIPMAPLAYOUT_BELOW;
-   surf.ss0.surface_type = BRW_SURFACE_BUFFER;
-   surf.ss0.surface_format = BRW_SURFACEFORMAT_R32G32B32A32_FLOAT;
-
-   assert(key->bo);
-   if (key->bo)
-      surf.ss1.base_addr = key->bo->offset; /* reloc */
-   else
-      surf.ss1.base_addr = key->offset;
-
-   surf.ss2.width = w & 0x7f;            /* bits 6:0 of size or width */
-   surf.ss2.height = (w >> 7) & 0x1fff;  /* bits 19:7 of size or width */
-   surf.ss3.depth = (w >> 20) & 0x7f;    /* bits 26:20 of size or width */
-   surf.ss3.pitch = (key->pitch * key->cpp) - 1; /* ignored?? */
-   brw_set_surface_tiling(&surf, key->tiling); /* tiling now allowed */
-   bo = brw_upload_cache(&brw->surface_cache, BRW_SS_SURFACE,
-                        key, sizeof(*key),
-                        &key->bo, key->bo ? 1 : 0,
-                        &surf, sizeof(surf),
-                        NULL, NULL);
 
-   if (key->bo) {
+   if (brw->wm.surf_bo[surf] == NULL) {
+      brw->wm.surf_bo[surf] = brw_upload_cache(&brw->surface_cache, BRW_SS_SURFACE,
+                                              &tex->ss, sizeof tex->ss,
+                                              &tex->bo, 1,
+                                              &tex->ss, sizeof tex->ss,
+                                              NULL, NULL);
+      
       /* Emit relocation to surface contents */
-      dri_bo_emit_reloc(bo,
-                       I915_GEM_DOMAIN_SAMPLER, 0,
-                       0,
-                       offsetof(struct brw_surface_state, ss1),
-                       key->bo);
+      brw->sws->bo_emit_reloc(brw->wm.surf_bo[surf],
+                             I915_GEM_DOMAIN_SAMPLER, 0,
+                             0,
+                             offsetof(struct brw_surface_state, ss1),
+                             tex->bo);
    }
-
-   return bo;
 }
 
-/* Creates a new WM constant buffer reflecting the current fragment program's
- * constants, if needed by the fragment program.
- *
- * Otherwise, constants go through the CURBEs using the brw_constant_buffer
- * state atom.
- */
-static drm_intel_bo *
-brw_wm_update_constant_buffer(struct brw_context *brw)
-{
-   struct brw_fragment_program *fp =
-      (struct brw_fragment_program *) brw->fragment_program;
-   const struct gl_program_parameter_list *params = fp->program.Base.Parameters;
-   const int size = params->NumParameters * 4 * sizeof(GLfloat);
-   drm_intel_bo *const_buffer;
 
-   /* BRW_NEW_FRAGMENT_PROGRAM */
-   if (!fp->use_const_buffer)
-      return NULL;
 
-   const_buffer = drm_intel_bo_alloc(intel->bufmgr, 
-                                    BRW_BUFFER_TYPE_SHADER_CONSTANTS,
-                                    size, 64);
 
-   /* _NEW_PROGRAM_CONSTANTS */
-   dri_bo_subdata(const_buffer, 0, size, params->ParameterValues);
 
-   return const_buffer;
-}
 
-/**
- * Update the surface state for a WM constant buffer.
- * The constant buffer will be (re)allocated here if needed.
- */
-static void
-brw_update_wm_constant_surface( struct brw_context *brw,
-                                GLuint surf)
-{
-   struct brw_context *brw = brw_context(ctx);
-   struct brw_surface_key key;
-   struct brw_fragment_program *fp =
-      (struct brw_fragment_program *) brw->fragment_program;
-   const struct gl_program_parameter_list *params =
-      fp->program.Base.Parameters;
-
-   /* If we're in this state update atom, we need to update WM constants, so
-    * free the old buffer and create a new one for the new contents.
-    */
-   brw->sws->bo_unreference(fp->const_buffer);
-   fp->const_buffer = brw_wm_update_constant_buffer(brw);
-
-   /* If there's no constant buffer, then no surface BO is needed to point at
-    * it.
-    */
-   if (fp->const_buffer == 0) {
-      drm_intel_bo_unreference(brw->wm.surf_bo[surf]);
-      brw->wm.surf_bo[surf] = NULL;
-      return;
-   }
-
-   memset(&key, 0, sizeof(key));
-
-   key.format = PIPE_FORMAT_RGBA_FLOAT32;
-   key.internal_format = GL_RGBA;
-   key.bo = fp->const_buffer;
-   key.depthmode = GL_NONE;
-   key.pitch = params->NumParameters;
-   key.width = params->NumParameters;
-   key.height = 1;
-   key.depth = 1;
-   key.cpp = 16;
-
-   /*
-   printf("%s:\n", __FUNCTION__);
-   printf("  width %d  height %d  depth %d  cpp %d  pitch %d\n",
-          key.width, key.height, key.depth, key.cpp, key.pitch);
-   */
-
-   brw->sws->bo_unreference(brw->wm.surf_bo[surf]);
-   brw->wm.surf_bo[surf] = brw_search_cache(&brw->surface_cache,
-                                            BRW_SS_SURFACE,
-                                            &key, sizeof(key),
-                                            &key.bo, key.bo ? 1 : 0,
-                                            NULL);
-   if (brw->wm.surf_bo[surf] == NULL) {
-      brw->wm.surf_bo[surf] = brw_create_constant_surface(brw, &key);
-   }
-   brw->state.dirty.brw |= BRW_NEW_WM_SURFACES;
-}
-
-/**
- * Updates surface / buffer for fragment shader constant buffer, if
- * one is required.
- *
- * This consumes the state updates for the constant buffer, and produces
- * BRW_NEW_WM_SURFACES to get picked up by brw_prepare_wm_surfaces for
- * inclusion in the binding table.
- */
-static void prepare_wm_constant_surface(struct brw_context *brw )
-{
-   struct brw_fragment_program *fp =
-      (struct brw_fragment_program *) brw->fragment_program;
-   GLuint surf = SURF_INDEX_FRAG_CONST_BUFFER;
-
-   drm_intel_bo_unreference(fp->const_buffer);
-   fp->const_buffer = brw_wm_update_constant_buffer(brw);
-
-   /* If there's no constant buffer, then no surface BO is needed to point at
-    * it.
-    */
-   if (fp->const_buffer == 0) {
-      if (brw->wm.surf_bo[surf] != NULL) {
-        drm_intel_bo_unreference(brw->wm.surf_bo[surf]);
-        brw->wm.surf_bo[surf] = NULL;
-        brw->state.dirty.brw |= BRW_NEW_WM_SURFACES;
-      }
-      return;
-   }
-
-   brw_update_wm_constant_surface(ctx, surf);
-}
-
-const struct brw_tracked_state brw_wm_constant_surface = {
-   .dirty = {
-      .mesa = (_NEW_PROGRAM_CONSTANTS),
-      .brw = (BRW_NEW_FRAGMENT_PROGRAM),
-      .cache = 0
-   },
-   .prepare = prepare_wm_constant_surface,
-};
 
 
 /**
@@ -480,142 +81,46 @@ const struct brw_tracked_state brw_wm_constant_surface = {
  */
 static void
 brw_update_renderbuffer_surface(struct brw_context *brw,
-                               struct gl_renderbuffer *rb,
+                               struct brw_surface *surface,
                                unsigned int unit)
 {
-   struct brw_winsys_buffer *region_bo = NULL;
-   struct intel_renderbuffer *irb = intel_renderbuffer(rb);
-   struct intel_region *region = irb ? irb->region : NULL;
-   struct {
-      unsigned int surface_type;
-      unsigned int surface_format;
-      unsigned int width, height, pitch, cpp;
-      GLubyte color_mask[4];
-      GLboolean color_blend;
-      uint32_t tiling;
-      uint32_t draw_offset;
-   } key;
-
-   memset(&key, 0, sizeof(key));
-
-   if (region != NULL) {
-      region_bo = region->buffer;
-
-      key.surface_type = BRW_SURFACE_2D;
-      switch (irb->texformat->MesaFormat) {
-      case PIPE_FORMAT_ARGB8888:
-        key.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
-        break;
-      case PIPE_FORMAT_RGB565:
-        key.surface_format = BRW_SURFACEFORMAT_B5G6R5_UNORM;
-        break;
-      case PIPE_FORMAT_ARGB1555:
-        key.surface_format = BRW_SURFACEFORMAT_B5G5R5A1_UNORM;
-        break;
-      case PIPE_FORMAT_ARGB4444:
-        key.surface_format = BRW_SURFACEFORMAT_B4G4R4A4_UNORM;
-        break;
-      default:
-        debug_printf("Bad renderbuffer format: %d\n",
-                     irb->texformat->MesaFormat);
-        assert(0);
-        key.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
-        return;
-      }
-      key.tiling = region->tiling;
-      if (brw->intel.intelScreen->driScrnPriv->dri2.enabled) {
-        key.width = rb->Width;
-        key.height = rb->Height;
-      } else {
-        key.width = region->width;
-        key.height = region->height;
-      }
-      key.pitch = region->pitch;
-      key.cpp = region->cpp;
-      key.draw_offset = region->draw_offset; /* cur 3d or cube face offset */
-   } else {
-      key.surface_type = BRW_SURFACE_NULL;
-      key.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
-      key.tiling = I915_TILING_X;
-      key.width = 1;
-      key.height = 1;
-      key.cpp = 4;
-      key.draw_offset = 0;
-   }
-   memcpy(key.color_mask, ctx->Color.ColorMask,
-         sizeof(key.color_mask));
-   key.color_blend = (!ctx->Color._LogicOpEnabled &&
-                     ctx->Color.BlendEnabled);
+   struct brw_surf_ss0 blend_ss0 = brw->curr.blend->ss0;
+   struct brw_surface_state ss;
+
+   /* Surfaces are potentially shared between contexts, so can't
+    * scribble the in-place ss0 value in the surface.
+    */
+   memcpy(&ss, &surface->ss, sizeof ss);
+
+   ss.ss0.color_blend        = blend_ss0.color_blend;
+   ss.ss0.writedisable_blue  = blend_ss0.writedisable_blue;
+   ss.ss0.writedisable_green = blend_ss0.writedisable_green;
+   ss.ss0.writedisable_red   = blend_ss0.writedisable_red;
+   ss.ss0.writedisable_alpha = blend_ss0.writedisable_alpha;
 
    brw->sws->bo_unreference(brw->wm.surf_bo[unit]);
    brw->wm.surf_bo[unit] = brw_search_cache(&brw->surface_cache,
                                            BRW_SS_SURFACE,
-                                           &key, sizeof(key),
-                                           &region_bo, 1,
+                                           &ss, sizeof(ss),
+                                           &surface->bo, 1,
                                            NULL);
 
    if (brw->wm.surf_bo[unit] == NULL) {
-      struct brw_surface_state surf;
-
-      memset(&surf, 0, sizeof(surf));
-
-      surf.ss0.surface_format = key.surface_format;
-      surf.ss0.surface_type = key.surface_type;
-      if (key.tiling == I915_TILING_NONE) {
-        surf.ss1.base_addr = key.draw_offset;
-      } else {
-        uint32_t tile_offset = key.draw_offset % 4096;
-
-        surf.ss1.base_addr = key.draw_offset - tile_offset;
-
-        assert(BRW_IS_G4X(brw) || tile_offset == 0);
-        if (BRW_IS_G4X(brw)) {
-           if (key.tiling == I915_TILING_X) {
-              /* Note that the low bits of these fields are missing, so
-               * there's the possibility of getting in trouble.
-               */
-              surf.ss5.x_offset = (tile_offset % 512) / key.cpp / 4;
-              surf.ss5.y_offset = tile_offset / 512 / 2;
-           } else {
-              surf.ss5.x_offset = (tile_offset % 128) / key.cpp / 4;
-              surf.ss5.y_offset = tile_offset / 128 / 2;
-           }
-        }
-      }
-      if (region_bo != NULL)
-        surf.ss1.base_addr += region_bo->offset; /* reloc */
-
-      surf.ss2.width = key.width - 1;
-      surf.ss2.height = key.height - 1;
-      brw_set_surface_tiling(&surf, key.tiling);
-      surf.ss3.pitch = (key.pitch * key.cpp) - 1;
-
-      /* _NEW_COLOR */
-      surf.ss0.color_blend = key.color_blend;
-      surf.ss0.writedisable_red =   !key.color_mask[0];
-      surf.ss0.writedisable_green = !key.color_mask[1];
-      surf.ss0.writedisable_blue =  !key.color_mask[2];
-      surf.ss0.writedisable_alpha = !key.color_mask[3];
-
-      /* Key size will never match key size for textures, so we're safe. */
+
       brw->wm.surf_bo[unit] = brw_upload_cache(&brw->surface_cache,
                                                BRW_SS_SURFACE,
-                                               &key, sizeof(key),
-                                              &region_bo, 1,
-                                              &surf, sizeof(surf),
+                                               &ss, sizeof ss,
+                                              &surface->bo, 1,
+                                              &ss, sizeof ss,
                                               NULL, NULL);
-      if (region_bo != NULL) {
-        /* We might sample from it, and we might render to it, so flag
-         * them both.  We might be able to figure out from other state
-         * a more restrictive relocation to emit.
-         */
-        drm_intel_bo_emit_reloc(brw->wm.surf_bo[unit],
-                                offsetof(struct brw_surface_state, ss1),
-                                region_bo,
-                                surf.ss1.base_addr - region_bo->offset,
-                                I915_GEM_DOMAIN_RENDER,
-                                I915_GEM_DOMAIN_RENDER);
-      }
+
+      /* XXX: we will only be rendering to this surface:
+       */
+      brw->sws->bo_emit_reloc(brw->wm.surf_bo[unit],
+                             I915_GEM_DOMAIN_RENDER, 0, 
+                             ss.ss1.base_addr - surface->bo->offset, /* XXX */
+                             offsetof(struct brw_surface_state, ss1),
+                             surface->bo);
    }
 }
 
@@ -631,21 +136,21 @@ brw_wm_get_binding_table(struct brw_context *brw)
 
    assert(brw->wm.nr_surfaces <= BRW_WM_MAX_SURF);
 
+   /* Note there is no key for this search beyond the values in the
+    * relocation array:
+    */
    bind_bo = brw_search_cache(&brw->surface_cache, BRW_SS_SURF_BIND,
                              NULL, 0,
                              brw->wm.surf_bo, brw->wm.nr_surfaces,
                              NULL);
 
    if (bind_bo == NULL) {
-      GLuint data_size = brw->wm.nr_surfaces * sizeof(GLuint);
       uint32_t data[BRW_WM_MAX_SURF];
+      GLuint data_size = brw->wm.nr_surfaces * sizeof data[0];
       int i;
 
       for (i = 0; i < brw->wm.nr_surfaces; i++)
-         if (brw->wm.surf_bo[i])
-            data[i] = brw->wm.surf_bo[i]->offset;
-         else
-            data[i] = 0;
+        data[i] = brw->wm.surf_bo[i]->offset;
 
       bind_bo = brw_upload_cache( &brw->surface_cache, BRW_SS_SURF_BIND,
                                  NULL, 0,
@@ -654,70 +159,79 @@ brw_wm_get_binding_table(struct brw_context *brw)
                                  NULL, NULL);
 
       /* Emit binding table relocations to surface state */
-      for (i = 0; i < BRW_WM_MAX_SURF; i++) {
-        if (brw->wm.surf_bo[i] != NULL) {
-           dri_bo_emit_reloc(bind_bo,
-                             I915_GEM_DOMAIN_INSTRUCTION, 0,
-                             0,
-                             i * sizeof(GLuint),
-                             brw->wm.surf_bo[i]);
-        }
+      for (i = 0; i < brw->wm.nr_surfaces; i++) {
+        brw->sws->bo_emit_reloc(bind_bo,
+                                I915_GEM_DOMAIN_INSTRUCTION, 0,
+                                0,
+                                i * sizeof(GLuint),
+                                brw->wm.surf_bo[i]);
       }
    }
 
    return bind_bo;
 }
 
-static void prepare_wm_surfaces(struct brw_context *brw )
+static int prepare_wm_surfaces(struct brw_context *brw )
 {
    GLuint i;
-   int old_nr_surfaces;
-
-   /* _NEW_BUFFERS */
-   /* Update surfaces for drawing buffers */
-   if (ctx->DrawBuffer->_NumColorDrawBuffers >= 1) {
-      for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
-         brw_update_renderbuffer_surface(brw,
-                                        ctx->DrawBuffer->_ColorDrawBuffers[i],
-                                        i);
-      }
-   } else {
-      brw_update_renderbuffer_surface(brw, NULL, 0);
+   int nr_surfaces = 0;
+
+   /* Unreference old buffers
+    */
+   for (i = 0; i < brw->wm.nr_surfaces; i++) {
+      brw->sws->bo_unreference(brw->wm.surf_bo[i]);
+      brw->wm.surf_bo[i] = NULL;
    }
 
-   old_nr_surfaces = brw->wm.nr_surfaces;
-   brw->wm.nr_surfaces = PIPE_MAX_COLOR_BUFS;
 
-   if (brw->wm.surf_bo[SURF_INDEX_FRAG_CONST_BUFFER] != NULL)
-       brw->wm.nr_surfaces = SURF_INDEX_FRAG_CONST_BUFFER + 1;
+   /* PIPE_NEW_COLOR_BUFFERS | PIPE_NEW_BLEND
+    *
+    * Update surfaces for drawing buffers.  Mixes in colormask and
+    * blend state.
+    *
+    * XXX: no color buffer case
+    */
+   for (i = 0; i < brw->curr.fb.nr_cbufs; i++) {
+      brw_update_renderbuffer_surface(brw, 
+                                     brw_surface(brw->curr.fb.cbufs[i]), 
+                                     nr_surfaces++);
+   }
 
-   /* Update surfaces for textures */
-   for (i = 0; i < BRW_MAX_TEX_UNIT; i++) {
-      const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i];
-      const GLuint surf = SURF_INDEX_TEXTURE(i);
+   /* PIPE_NEW_TEXTURE 
+    */
+   for (i = 0; i < brw->curr.num_textures; i++) {
+      brw_update_texture_surface(brw, 
+                                brw->curr.texture[i],
+                                nr_surfaces++);
+   }
 
-      /* _NEW_TEXTURE, BRW_NEW_TEXDATA */
-      if (texUnit->_ReallyEnabled) {
-        brw_update_texture_surface(ctx, i);
-        brw->wm.nr_surfaces = surf + 1;
-      } else {
-         brw->sws->bo_unreference(brw->wm.surf_bo[surf]);
-         brw->wm.surf_bo[surf] = NULL;
-      }
+   /* PIPE_NEW_FRAGMENT_CONSTANTS
+    */
+#if 0
+   if (brw->curr.fragment_constants) {
+      brw_update_fragment_constant_surface(brw, 
+                                          brw->curr.fragment_constants, 
+                                          nr_surfaces++);
    }
+#endif
 
    brw->sws->bo_unreference(brw->wm.bind_bo);
    brw->wm.bind_bo = brw_wm_get_binding_table(brw);
 
-   if (brw->wm.nr_surfaces != old_nr_surfaces)
+   if (brw->wm.nr_surfaces != nr_surfaces) {
+      brw->wm.nr_surfaces = nr_surfaces;
       brw->state.dirty.brw |= BRW_NEW_NR_WM_SURFACES;
+   }
+
+   return 0;
 }
 
 const struct brw_tracked_state brw_wm_surfaces = {
    .dirty = {
-      .mesa = (_NEW_COLOR |
-               _NEW_TEXTURE |
-               _NEW_BUFFERS),
+      .mesa = (PIPE_NEW_COLOR_BUFFERS |
+               PIPE_NEW_BOUND_TEXTURES |
+               PIPE_NEW_FRAGMENT_CONSTANTS |
+              PIPE_NEW_BLEND),
       .brw = (BRW_NEW_CONTEXT |
              BRW_NEW_WM_SURFACES),
       .cache = 0