i965: Remove the validated BO list, now that it's unused.
[mesa.git] / src / mesa / drivers / dri / i965 / brw_wm_surface_state.c
index 233fe3b731065d2c5cae1b8cb8340c192674f1ed..bb7fd2e6503f400c0343379eed96fb2c4b16a095 100644 (file)
@@ -31,7 +31,7 @@
                    
 
 #include "main/mtypes.h"
-#include "main/texstore.h"
+#include "main/samplerobj.h"
 #include "program/prog_parameter.h"
 
 #include "intel_mipmap_tree.h"
 #include "brw_defines.h"
 #include "brw_wm.h"
 
-static GLuint translate_tex_target( GLenum target )
+GLuint
+translate_tex_target(GLenum target)
 {
    switch (target) {
    case GL_TEXTURE_1D: 
+   case GL_TEXTURE_1D_ARRAY_EXT:
       return BRW_SURFACE_1D;
 
    case GL_TEXTURE_RECTANGLE_NV: 
       return BRW_SURFACE_2D;
 
    case GL_TEXTURE_2D: 
+   case GL_TEXTURE_2D_ARRAY_EXT:
       return BRW_SURFACE_2D;
 
    case GL_TEXTURE_3D: 
@@ -68,59 +71,93 @@ static GLuint translate_tex_target( GLenum target )
    }
 }
 
-static uint32_t brw_format_for_mesa_format[MESA_FORMAT_COUNT] =
+uint32_t
+brw_format_for_mesa_format(gl_format mesa_format)
 {
-   [MESA_FORMAT_L8] = BRW_SURFACEFORMAT_L8_UNORM,
-   [MESA_FORMAT_I8] = BRW_SURFACEFORMAT_I8_UNORM,
-   [MESA_FORMAT_A8] = BRW_SURFACEFORMAT_A8_UNORM,
-   [MESA_FORMAT_AL88] = BRW_SURFACEFORMAT_L8A8_UNORM,
-   [MESA_FORMAT_AL1616] = BRW_SURFACEFORMAT_L16A16_UNORM,
-   [MESA_FORMAT_R8] = BRW_SURFACEFORMAT_R8_UNORM,
-   [MESA_FORMAT_R16] = BRW_SURFACEFORMAT_R16_UNORM,
-   [MESA_FORMAT_RG88] = BRW_SURFACEFORMAT_R8G8_UNORM,
-   [MESA_FORMAT_RG1616] = BRW_SURFACEFORMAT_R16G16_UNORM,
-   [MESA_FORMAT_ARGB8888] = BRW_SURFACEFORMAT_B8G8R8A8_UNORM,
-   [MESA_FORMAT_XRGB8888] = BRW_SURFACEFORMAT_B8G8R8X8_UNORM,
-   [MESA_FORMAT_RGB565] = BRW_SURFACEFORMAT_B5G6R5_UNORM,
-   [MESA_FORMAT_ARGB1555] = BRW_SURFACEFORMAT_B5G5R5A1_UNORM,
-   [MESA_FORMAT_ARGB4444] = BRW_SURFACEFORMAT_B4G4R4A4_UNORM,
-   [MESA_FORMAT_YCBCR_REV] = BRW_SURFACEFORMAT_YCRCB_NORMAL,
-   [MESA_FORMAT_YCBCR] = BRW_SURFACEFORMAT_YCRCB_SWAPUVY,
-   [MESA_FORMAT_RGB_FXT1] = BRW_SURFACEFORMAT_FXT1,
-   [MESA_FORMAT_RGBA_FXT1] = BRW_SURFACEFORMAT_FXT1,
-   [MESA_FORMAT_RGB_DXT1] = BRW_SURFACEFORMAT_DXT1_RGB,
-   [MESA_FORMAT_RGBA_DXT1] = BRW_SURFACEFORMAT_BC1_UNORM,
-   [MESA_FORMAT_RGBA_DXT3] = BRW_SURFACEFORMAT_BC2_UNORM,
-   [MESA_FORMAT_RGBA_DXT5] = BRW_SURFACEFORMAT_BC3_UNORM,
-   [MESA_FORMAT_SRGB_DXT1] = BRW_SURFACEFORMAT_DXT1_RGB_SRGB,
-   [MESA_FORMAT_SRGBA_DXT1] = BRW_SURFACEFORMAT_BC1_UNORM_SRGB,
-   [MESA_FORMAT_SRGBA_DXT3] = BRW_SURFACEFORMAT_BC2_UNORM_SRGB,
-   [MESA_FORMAT_SRGBA_DXT5] = BRW_SURFACEFORMAT_BC3_UNORM_SRGB,
-   [MESA_FORMAT_SARGB8] = BRW_SURFACEFORMAT_B8G8R8A8_UNORM_SRGB,
-   [MESA_FORMAT_SLA8] = BRW_SURFACEFORMAT_L8A8_UNORM_SRGB,
-   [MESA_FORMAT_SL8] = BRW_SURFACEFORMAT_L8_UNORM_SRGB,
-   [MESA_FORMAT_DUDV8] = BRW_SURFACEFORMAT_R8G8_SNORM,
-   [MESA_FORMAT_SIGNED_RGBA8888_REV] = BRW_SURFACEFORMAT_R8G8B8A8_SNORM,
-};
+   static const uint32_t table[MESA_FORMAT_COUNT] =
+   {
+      [MESA_FORMAT_L8] = BRW_SURFACEFORMAT_L8_UNORM,
+      [MESA_FORMAT_I8] = BRW_SURFACEFORMAT_I8_UNORM,
+      [MESA_FORMAT_A8] = BRW_SURFACEFORMAT_A8_UNORM,
+      [MESA_FORMAT_AL88] = BRW_SURFACEFORMAT_L8A8_UNORM,
+      [MESA_FORMAT_AL1616] = BRW_SURFACEFORMAT_L16A16_UNORM,
+      [MESA_FORMAT_R8] = BRW_SURFACEFORMAT_R8_UNORM,
+      [MESA_FORMAT_R16] = BRW_SURFACEFORMAT_R16_UNORM,
+      [MESA_FORMAT_RG88] = BRW_SURFACEFORMAT_R8G8_UNORM,
+      [MESA_FORMAT_RG1616] = BRW_SURFACEFORMAT_R16G16_UNORM,
+      [MESA_FORMAT_ARGB8888] = BRW_SURFACEFORMAT_B8G8R8A8_UNORM,
+      [MESA_FORMAT_XRGB8888] = BRW_SURFACEFORMAT_B8G8R8X8_UNORM,
+      [MESA_FORMAT_RGB565] = BRW_SURFACEFORMAT_B5G6R5_UNORM,
+      [MESA_FORMAT_ARGB1555] = BRW_SURFACEFORMAT_B5G5R5A1_UNORM,
+      [MESA_FORMAT_ARGB4444] = BRW_SURFACEFORMAT_B4G4R4A4_UNORM,
+      [MESA_FORMAT_YCBCR_REV] = BRW_SURFACEFORMAT_YCRCB_NORMAL,
+      [MESA_FORMAT_YCBCR] = BRW_SURFACEFORMAT_YCRCB_SWAPUVY,
+      [MESA_FORMAT_RGB_FXT1] = BRW_SURFACEFORMAT_FXT1,
+      [MESA_FORMAT_RGBA_FXT1] = BRW_SURFACEFORMAT_FXT1,
+      [MESA_FORMAT_RGB_DXT1] = BRW_SURFACEFORMAT_DXT1_RGB,
+      [MESA_FORMAT_RGBA_DXT1] = BRW_SURFACEFORMAT_BC1_UNORM,
+      [MESA_FORMAT_RGBA_DXT3] = BRW_SURFACEFORMAT_BC2_UNORM,
+      [MESA_FORMAT_RGBA_DXT5] = BRW_SURFACEFORMAT_BC3_UNORM,
+      [MESA_FORMAT_SRGB_DXT1] = BRW_SURFACEFORMAT_DXT1_RGB_SRGB,
+      [MESA_FORMAT_SRGBA_DXT1] = BRW_SURFACEFORMAT_BC1_UNORM_SRGB,
+      [MESA_FORMAT_SRGBA_DXT3] = BRW_SURFACEFORMAT_BC2_UNORM_SRGB,
+      [MESA_FORMAT_SRGBA_DXT5] = BRW_SURFACEFORMAT_BC3_UNORM_SRGB,
+      [MESA_FORMAT_SARGB8] = BRW_SURFACEFORMAT_B8G8R8A8_UNORM_SRGB,
+      [MESA_FORMAT_SLA8] = BRW_SURFACEFORMAT_L8A8_UNORM_SRGB,
+      [MESA_FORMAT_SL8] = BRW_SURFACEFORMAT_L8_UNORM_SRGB,
+      [MESA_FORMAT_DUDV8] = BRW_SURFACEFORMAT_R8G8_SNORM,
+      [MESA_FORMAT_SIGNED_R8] = BRW_SURFACEFORMAT_R8_SNORM,
+      [MESA_FORMAT_SIGNED_RG88_REV] = BRW_SURFACEFORMAT_R8G8_SNORM,
+      [MESA_FORMAT_SIGNED_RGBA8888_REV] = BRW_SURFACEFORMAT_R8G8B8A8_SNORM,
+      [MESA_FORMAT_SIGNED_R16] = BRW_SURFACEFORMAT_R16_SNORM,
+      [MESA_FORMAT_SIGNED_GR1616] = BRW_SURFACEFORMAT_R16G16_SNORM,
+      [MESA_FORMAT_RGBA_FLOAT32] = BRW_SURFACEFORMAT_R32G32B32A32_FLOAT,
+      [MESA_FORMAT_RG_FLOAT32] = BRW_SURFACEFORMAT_R32G32_FLOAT,
+      [MESA_FORMAT_R_FLOAT32] = BRW_SURFACEFORMAT_R32_FLOAT,
+      [MESA_FORMAT_INTENSITY_FLOAT32] = BRW_SURFACEFORMAT_I32_FLOAT,
+      [MESA_FORMAT_LUMINANCE_FLOAT32] = BRW_SURFACEFORMAT_L32_FLOAT,
+      [MESA_FORMAT_ALPHA_FLOAT32] = BRW_SURFACEFORMAT_A32_FLOAT,
+      [MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32] = BRW_SURFACEFORMAT_L32A32_FLOAT,
+      [MESA_FORMAT_RED_RGTC1] = BRW_SURFACEFORMAT_BC4_UNORM,
+      [MESA_FORMAT_SIGNED_RED_RGTC1] = BRW_SURFACEFORMAT_BC4_SNORM,
+      [MESA_FORMAT_RG_RGTC2] = BRW_SURFACEFORMAT_BC5_UNORM,
+      [MESA_FORMAT_SIGNED_RG_RGTC2] = BRW_SURFACEFORMAT_BC5_SNORM,
+      [MESA_FORMAT_RGB9_E5_FLOAT] = BRW_SURFACEFORMAT_R9G9B9E5_SHAREDEXP,
+      [MESA_FORMAT_R11_G11_B10_FLOAT] = BRW_SURFACEFORMAT_R11G11B10_FLOAT,
+   };
+   assert(mesa_format < MESA_FORMAT_COUNT);
+   return table[mesa_format];
+}
 
 bool
 brw_render_target_supported(gl_format format)
 {
+   /* These are not color render targets like the table holds, but we
+    * ask the question for FBO completeness.
+    */
    if (format == MESA_FORMAT_S8_Z24 ||
        format == MESA_FORMAT_X8_Z24 ||
+       format == MESA_FORMAT_S8 ||
        format == MESA_FORMAT_Z16) {
       return true;
    }
 
+   /* The value of this BRW_SURFACEFORMAT is 0, so hardcode it.
+    */
+   if (format == MESA_FORMAT_RGBA_FLOAT32)
+      return true;
+
    /* Not exactly true, as some of those formats are not renderable.
     * But at least we know how to translate them.
     */
-   return brw_format_for_mesa_format[format] != 0;
+   return brw_format_for_mesa_format(format) != 0;
 }
 
-static GLuint translate_tex_format( gl_format mesa_format,
-                                    GLenum internal_format,
-                                   GLenum depth_mode )
+GLuint
+translate_tex_format(gl_format mesa_format,
+                    GLenum internal_format,
+                    GLenum depth_mode,
+                    GLenum srgb_decode)
 {
    switch( mesa_format ) {
 
@@ -135,6 +172,7 @@ static GLuint translate_tex_format( gl_format mesa_format,
          return BRW_SURFACEFORMAT_L16_UNORM;
 
    case MESA_FORMAT_S8_Z24:
+   case MESA_FORMAT_X8_Z24:
       /* XXX: these different surface formats don't seem to
        * make any difference for shadow sampler/compares.
        */
@@ -146,29 +184,41 @@ static GLuint translate_tex_format( gl_format mesa_format,
          return BRW_SURFACEFORMAT_R24_UNORM_X8_TYPELESS;
       else
          return BRW_SURFACEFORMAT_L24X8_UNORM;
+      
+   case MESA_FORMAT_SARGB8:
+   case MESA_FORMAT_SLA8:
+   case MESA_FORMAT_SL8:
+      if (srgb_decode == GL_DECODE_EXT)
+        return brw_format_for_mesa_format(mesa_format);
+      else if (srgb_decode == GL_SKIP_DECODE_EXT)
+        return brw_format_for_mesa_format(_mesa_get_srgb_format_linear(mesa_format));
+
+   case MESA_FORMAT_RGBA8888_REV:
+      /* This format is not renderable? */
+      return BRW_SURFACEFORMAT_R8G8B8A8_UNORM;
+
+   case MESA_FORMAT_RGBA_FLOAT32:
+      /* The value of this BRW_SURFACEFORMAT is 0, which tricks the
+       * assertion below.
+       */
+      return BRW_SURFACEFORMAT_R32G32B32A32_FLOAT;
 
    default:
-      assert(brw_format_for_mesa_format[mesa_format] != 0);
-      return brw_format_for_mesa_format[mesa_format];
+      assert(brw_format_for_mesa_format(mesa_format) != 0);
+      return brw_format_for_mesa_format(mesa_format);
    }
 }
 
-static void
-brw_set_surface_tiling(struct brw_surface_state *surf, uint32_t tiling)
+static uint32_t
+brw_get_surface_tiling_bits(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;
+      return BRW_SURFACE_TILED;
    case I915_TILING_Y:
-      surf->ss3.tiled_surface = 1;
-      surf->ss3.tile_walk = BRW_TILEWALK_YMAJOR;
-      break;
+      return BRW_SURFACE_TILED | BRW_SURFACE_TILED_Y;
+   default:
+      return 0;
    }
 }
 
@@ -179,51 +229,43 @@ brw_update_texture_surface( struct gl_context *ctx, GLuint unit )
    struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current;
    struct intel_texture_object *intelObj = intel_texture_object(tObj);
    struct gl_texture_image *firstImage = tObj->Image[0][tObj->BaseLevel];
+   struct gl_sampler_object *sampler = _mesa_get_samplerobj(ctx, unit);
    const GLuint surf_index = SURF_INDEX_TEXTURE(unit);
-   struct brw_surface_state surf;
-   void *map;
+   uint32_t *surf;
+   int width, height, depth;
 
-   memset(&surf, 0, sizeof(surf));
+   intel_miptree_get_dimensions_for_image(firstImage, &width, &height, &depth);
 
-   surf.ss0.mipmap_layout_mode = BRW_SURFACE_MIPMAPLAYOUT_BELOW;
-   surf.ss0.surface_type = translate_tex_target(tObj->Target);
-   surf.ss0.surface_format = translate_tex_format(firstImage->TexFormat,
-                                                 firstImage->InternalFormat,
-                                                 tObj->DepthMode);
+   surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE,
+                         6 * 4, 32, &brw->wm.surf_offset[surf_index]);
 
-   /* This is ok for all textures with channel width 8bit or less:
-    */
-/*    surf.ss0.data_return_format = BRW_SURFACERETURNFORMAT_S1; */
-   surf.ss1.base_addr = intelObj->mt->region->buffer->offset; /* reloc */
+   surf[0] = (translate_tex_target(tObj->Target) << BRW_SURFACE_TYPE_SHIFT |
+             BRW_SURFACE_MIPMAPLAYOUT_BELOW << BRW_SURFACE_MIPLAYOUT_SHIFT |
+             BRW_SURFACE_CUBEFACE_ENABLES |
+             (translate_tex_format(firstImage->TexFormat,
+                                   firstImage->InternalFormat,
+                                   sampler->DepthMode,
+                                   sampler->sRGBDecode) <<
+              BRW_SURFACE_FORMAT_SHIFT));
 
-   surf.ss2.mip_count = intelObj->_MaxLevel - tObj->BaseLevel;
-   surf.ss2.width = firstImage->Width - 1;
-   surf.ss2.height = firstImage->Height - 1;
-   brw_set_surface_tiling(&surf, intelObj->mt->region->tiling);
-   surf.ss3.pitch = (intelObj->mt->region->pitch * intelObj->mt->cpp) - 1;
-   surf.ss3.depth = firstImage->Depth - 1;
+   surf[1] = intelObj->mt->region->bo->offset; /* reloc */
 
-   surf.ss4.min_lod = 0;
-   if (tObj->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;
-   }
+   surf[2] = ((intelObj->_MaxLevel - tObj->BaseLevel) << BRW_SURFACE_LOD_SHIFT |
+             (width - 1) << BRW_SURFACE_WIDTH_SHIFT |
+             (height - 1) << BRW_SURFACE_HEIGHT_SHIFT);
+
+   surf[3] = (brw_get_surface_tiling_bits(intelObj->mt->region->tiling) |
+             (depth - 1) << BRW_SURFACE_DEPTH_SHIFT |
+             ((intelObj->mt->region->pitch * intelObj->mt->cpp) - 1) <<
+             BRW_SURFACE_PITCH_SHIFT);
 
-   map = brw_state_batch(brw, sizeof(surf), 32,
-                        &brw->wm.surf_bo[surf_index],
-                        &brw->wm.surf_offset[surf_index]);
-   memcpy(map, &surf, sizeof(surf));
+   surf[4] = 0;
+   surf[5] = 0;
 
    /* Emit relocation to surface contents */
-   drm_intel_bo_emit_reloc(brw->wm.surf_bo[surf_index],
-                          brw->wm.surf_offset[surf_index] +
-                          offsetof(struct brw_surface_state, ss1),
-                          intelObj->mt->region->buffer, 0,
+   drm_intel_bo_emit_reloc(brw->intel.batch.bo,
+                          brw->wm.surf_offset[surf_index] + 4,
+                          intelObj->mt->region->bo, 0,
                           I915_GEM_DOMAIN_SAMPLER, 0);
 }
 
@@ -235,41 +277,39 @@ void
 brw_create_constant_surface(struct brw_context *brw,
                            drm_intel_bo *bo,
                            int width,
-                           drm_intel_bo **out_bo,
                            uint32_t *out_offset)
 {
    struct intel_context *intel = &brw->intel;
    const GLint w = width - 1;
-   struct brw_surface_state surf;
-   void *map;
+   uint32_t *surf;
 
-   memset(&surf, 0, sizeof(surf));
+   surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE,
+                         6 * 4, 32, out_offset);
 
-   surf.ss0.mipmap_layout_mode = BRW_SURFACE_MIPMAPLAYOUT_BELOW;
-   surf.ss0.surface_type = BRW_SURFACE_BUFFER;
-   surf.ss0.surface_format = BRW_SURFACEFORMAT_R32G32B32A32_FLOAT;
+   surf[0] = (BRW_SURFACE_BUFFER << BRW_SURFACE_TYPE_SHIFT |
+             BRW_SURFACE_MIPMAPLAYOUT_BELOW << BRW_SURFACE_MIPLAYOUT_SHIFT |
+             BRW_SURFACEFORMAT_R32G32B32A32_FLOAT << BRW_SURFACE_FORMAT_SHIFT);
 
    if (intel->gen >= 6)
-      surf.ss0.render_cache_read_write = 1;
+      surf[0] |= BRW_SURFACE_RC_READ_WRITE;
 
-   assert(bo);
-   surf.ss1.base_addr = bo->offset; /* reloc */
+   surf[1] = bo->offset; /* reloc */
 
-   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 = (width * 16) - 1; /* ignored?? */
-   brw_set_surface_tiling(&surf, I915_TILING_NONE); /* tiling now allowed */
+   surf[2] = (((w & 0x7f) - 1) << BRW_SURFACE_WIDTH_SHIFT |
+             (((w >> 7) & 0x1fff) - 1) << BRW_SURFACE_HEIGHT_SHIFT);
 
-   map = brw_state_batch(brw, sizeof(surf), 32, out_bo, out_offset);
-   memcpy(map, &surf, sizeof(surf));
+   surf[3] = ((((w >> 20) & 0x7f) - 1) << BRW_SURFACE_DEPTH_SHIFT |
+             (width * 16 - 1) << BRW_SURFACE_PITCH_SHIFT);
+
+   surf[4] = 0;
+   surf[5] = 0;
 
    /* Emit relocation to surface contents.  Section 5.1.1 of the gen4
     * bspec ("Data Cache") says that the data cache does not exist as
     * a separate cache and is just the sampler cache.
     */
-   drm_intel_bo_emit_reloc(*out_bo, (*out_offset +
-                                    offsetof(struct brw_surface_state, ss1)),
+   drm_intel_bo_emit_reloc(brw->intel.batch.bo,
+                          *out_offset + 4,
                           bo, 0,
                           I915_GEM_DOMAIN_SAMPLER, 0);
 }
@@ -281,7 +321,7 @@ brw_create_constant_surface(struct brw_context *brw,
  * state atom.
  */
 static void
-prepare_wm_constants(struct brw_context *brw)
+prepare_wm_pull_constants(struct brw_context *brw)
 {
    struct gl_context *ctx = &brw->intel.ctx;
    struct intel_context *intel = &brw->intel;
@@ -312,7 +352,7 @@ prepare_wm_constants(struct brw_context *brw)
    constants = brw->wm.const_bo->virtual;
    for (i = 0; i < brw->wm.prog_data->nr_pull_params; i++) {
       constants[i] = convert_param(brw->wm.prog_data->pull_param_convert[i],
-                                  *brw->wm.prog_data->pull_param[i]);
+                                  brw->wm.prog_data->pull_param[i]);
    }
    drm_intel_gem_bo_unmap_gtt(brw->wm.const_bo);
 
@@ -325,7 +365,7 @@ const struct brw_tracked_state brw_wm_constants = {
       .brw = (BRW_NEW_FRAGMENT_PROGRAM),
       .cache = 0
    },
-   .prepare = prepare_wm_constants,
+   .prepare = prepare_wm_pull_constants,
 };
 
 /**
@@ -348,16 +388,14 @@ static void upload_wm_constant_surface(struct brw_context *brw )
     * it.
     */
    if (brw->wm.const_bo == 0) {
-      if (brw->wm.surf_bo[surf] != NULL) {
-        drm_intel_bo_unreference(brw->wm.surf_bo[surf]);
-        brw->wm.surf_bo[surf] = NULL;
+      if (brw->wm.surf_offset[surf]) {
         brw->state.dirty.brw |= BRW_NEW_WM_SURFACES;
+        brw->wm.surf_offset[surf] = 0;
       }
       return;
    }
 
    brw_create_constant_surface(brw, brw->wm.const_bo, params->NumParameters,
-                              &brw->wm.surf_bo[surf],
                               &brw->wm.surf_offset[surf]);
    brw->state.dirty.brw |= BRW_NEW_WM_SURFACES;
 }
@@ -376,33 +414,24 @@ static void
 brw_update_null_renderbuffer_surface(struct brw_context *brw, unsigned int unit)
 {
    struct intel_context *intel = &brw->intel;
-   struct brw_surface_state surf;
-   void *map;
-
-   memset(&surf, 0, sizeof(surf));
-
-   surf.ss0.surface_type = BRW_SURFACE_NULL;
-   surf.ss0.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
-   surf.ss1.base_addr = 0;
+   uint32_t *surf;
 
-   surf.ss2.width = 0;
-   surf.ss2.height = 0;
-   brw_set_surface_tiling(&surf, I915_TILING_NONE);
-   surf.ss3.pitch = 0;
+   surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE,
+                         6 * 4, 32, &brw->wm.surf_offset[unit]);
 
+   surf[0] = (BRW_SURFACE_NULL << BRW_SURFACE_TYPE_SHIFT |
+             BRW_SURFACEFORMAT_B8G8R8A8_UNORM << BRW_SURFACE_FORMAT_SHIFT);
    if (intel->gen < 6) {
-      /* _NEW_COLOR */
-      surf.ss0.color_blend = 0;
-      surf.ss0.writedisable_red =   1;
-      surf.ss0.writedisable_green = 1;
-      surf.ss0.writedisable_blue =  1;
-      surf.ss0.writedisable_alpha = 1;
+      surf[0] |= (1 << BRW_SURFACE_WRITEDISABLE_R_SHIFT |
+                 1 << BRW_SURFACE_WRITEDISABLE_G_SHIFT |
+                 1 << BRW_SURFACE_WRITEDISABLE_B_SHIFT |
+                 1 << BRW_SURFACE_WRITEDISABLE_A_SHIFT);
    }
-
-   map = brw_state_batch(brw, sizeof(surf), 32,
-                        &brw->wm.surf_bo[unit],
-                        &brw->wm.surf_offset[unit]);
-   memcpy(map, &surf, sizeof(surf));
+   surf[1] = 0;
+   surf[2] = 0;
+   surf[3] = 0;
+   surf[4] = 0;
+   surf[5] = 0;
 }
 
 /**
@@ -419,10 +448,12 @@ brw_update_renderbuffer_surface(struct brw_context *brw,
    struct gl_context *ctx = &intel->ctx;
    struct intel_renderbuffer *irb = intel_renderbuffer(rb);
    struct intel_region *region = irb->region;
-   struct brw_surface_state surf;
-   void *map;
+   uint32_t *surf;
+   uint32_t tile_x, tile_y;
+   uint32_t format = 0;
 
-   memset(&surf, 0, sizeof(surf));
+   surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE,
+                         6 * 4, 32, &brw->wm.surf_offset[unit]);
 
    switch (irb->Base.Format) {
    case MESA_FORMAT_XRGB8888:
@@ -433,81 +464,79 @@ brw_update_renderbuffer_surface(struct brw_context *brw,
        * cases where GL_DST_ALPHA (or GL_ONE_MINUS_DST_ALPHA) is
        * used.
        */
-      surf.ss0.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
+      format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
+      break;
+   case MESA_FORMAT_INTENSITY_FLOAT32:
+   case MESA_FORMAT_LUMINANCE_FLOAT32:
+      /* For these formats, we just need to read/write the first
+       * channel into R, which is to say that we just treat them as
+       * GL_RED.
+       */
+      format = BRW_SURFACEFORMAT_R32_FLOAT;
       break;
    case MESA_FORMAT_SARGB8:
       /* without GL_EXT_framebuffer_sRGB we shouldn't bind sRGB
         surfaces to the blend/update as sRGB */
-      surf.ss0.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
+      if (ctx->Color.sRGBEnabled)
+        format = brw_format_for_mesa_format(irb->Base.Format);
+      else
+        format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
       break;
    default:
-      surf.ss0.surface_format = brw_format_for_mesa_format[irb->Base.Format];
-      assert(surf.ss0.surface_format != 0);
+      assert(brw_render_target_supported(irb->Base.Format));
+      format = brw_format_for_mesa_format(irb->Base.Format);
    }
 
-   surf.ss0.surface_type = BRW_SURFACE_2D;
-   if (region->tiling == I915_TILING_NONE) {
-      surf.ss1.base_addr = (region->draw_x +
-                           region->draw_y * region->pitch) * region->cpp;
-   } else {
-      uint32_t tile_base, tile_x, tile_y;
-      uint32_t pitch = region->pitch * region->cpp;
-
-      if (region->tiling == I915_TILING_X) {
-        tile_x = region->draw_x % (512 / region->cpp);
-        tile_y = region->draw_y % 8;
-        tile_base = ((region->draw_y / 8) * (8 * pitch));
-        tile_base += (region->draw_x - tile_x) / (512 / region->cpp) * 4096;
-      } else {
-        /* Y */
-        tile_x = region->draw_x % (128 / region->cpp);
-        tile_y = region->draw_y % 32;
-        tile_base = ((region->draw_y / 32) * (32 * pitch));
-        tile_base += (region->draw_x - tile_x) / (128 / region->cpp) * 4096;
-      }
-      assert(brw->has_surface_tile_offset || (tile_x == 0 && tile_y == 0));
-      assert(tile_x % 4 == 0);
-      assert(tile_y % 2 == 0);
-      /* Note that the low bits of these fields are missing, so
-       * there's the possibility of getting in trouble.
-       */
-      surf.ss1.base_addr = tile_base;
-      surf.ss5.x_offset = tile_x / 4;
-      surf.ss5.y_offset = tile_y / 2;
-   }
-   surf.ss1.base_addr += region->buffer->offset; /* reloc */
+   surf[0] = (BRW_SURFACE_2D << BRW_SURFACE_TYPE_SHIFT |
+             format << BRW_SURFACE_FORMAT_SHIFT);
+
+   /* reloc */
+   surf[1] = (intel_renderbuffer_tile_offsets(irb, &tile_x, &tile_y) +
+             region->bo->offset);
+
+   surf[2] = ((rb->Width - 1) << BRW_SURFACE_WIDTH_SHIFT |
+             (rb->Height - 1) << BRW_SURFACE_HEIGHT_SHIFT);
 
-   surf.ss2.width = rb->Width - 1;
-   surf.ss2.height = rb->Height - 1;
-   brw_set_surface_tiling(&surf, region->tiling);
-   surf.ss3.pitch = (region->pitch * region->cpp) - 1;
+   surf[3] = (brw_get_surface_tiling_bits(region->tiling) |
+             ((region->pitch * region->cpp) - 1) << BRW_SURFACE_PITCH_SHIFT);
+
+   surf[4] = 0;
+
+   assert(brw->has_surface_tile_offset || (tile_x == 0 && tile_y == 0));
+   /* Note that the low bits of these fields are missing, so
+    * there's the possibility of getting in trouble.
+    */
+   assert(tile_x % 4 == 0);
+   assert(tile_y % 2 == 0);
+   surf[5] = ((tile_x / 4) << BRW_SURFACE_X_OFFSET_SHIFT |
+             (tile_y / 2) << BRW_SURFACE_Y_OFFSET_SHIFT);
 
    if (intel->gen < 6) {
       /* _NEW_COLOR */
-      surf.ss0.color_blend = (!ctx->Color._LogicOpEnabled &&
-                             (ctx->Color.BlendEnabled & (1 << unit)));
-      surf.ss0.writedisable_red =   !ctx->Color.ColorMask[unit][0];
-      surf.ss0.writedisable_green = !ctx->Color.ColorMask[unit][1];
-      surf.ss0.writedisable_blue =  !ctx->Color.ColorMask[unit][2];
+      if (!ctx->Color.ColorLogicOpEnabled &&
+         (ctx->Color.BlendEnabled & (1 << unit)))
+        surf[0] |= BRW_SURFACE_BLEND_ENABLED;
+
+      if (!ctx->Color.ColorMask[unit][0])
+        surf[0] |= 1 << BRW_SURFACE_WRITEDISABLE_R_SHIFT;
+      if (!ctx->Color.ColorMask[unit][1])
+        surf[0] |= 1 << BRW_SURFACE_WRITEDISABLE_G_SHIFT;
+      if (!ctx->Color.ColorMask[unit][2])
+        surf[0] |= 1 << BRW_SURFACE_WRITEDISABLE_B_SHIFT;
+
       /* As mentioned above, disable writes to the alpha component when the
        * renderbuffer is XRGB.
        */
-      if (ctx->DrawBuffer->Visual.alphaBits == 0)
-        surf.ss0.writedisable_alpha = 1;
-      else
-        surf.ss0.writedisable_alpha = !ctx->Color.ColorMask[unit][3];
+      if (ctx->DrawBuffer->Visual.alphaBits == 0 ||
+         !ctx->Color.ColorMask[unit][3]) {
+        surf[0] |= 1 << BRW_SURFACE_WRITEDISABLE_A_SHIFT;
+      }
    }
 
-   map = brw_state_batch(brw, sizeof(surf), 32,
-                        &brw->wm.surf_bo[unit],
-                        &brw->wm.surf_offset[unit]);
-   memcpy(map, &surf, sizeof(surf));
-
-   drm_intel_bo_emit_reloc(brw->wm.surf_bo[unit],
-                          brw->wm.surf_offset[unit] +
-                          offsetof(struct brw_surface_state, ss1),
-                          region->buffer,
-                          surf.ss1.base_addr - region->buffer->offset,
+   drm_intel_bo_emit_reloc(brw->intel.batch.bo,
+                          brw->wm.surf_offset[unit] + 4,
+                          region->bo,
+                          surf[1] - region->bo->offset,
                           I915_GEM_DOMAIN_RENDER,
                           I915_GEM_DOMAIN_RENDER);
 }
@@ -519,29 +548,18 @@ prepare_wm_surfaces(struct brw_context *brw)
    int i;
    int nr_surfaces = 0;
 
-   if (ctx->DrawBuffer->_NumColorDrawBuffers >= 1) {
-      for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
-        struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[i];
-        struct intel_renderbuffer *irb = intel_renderbuffer(rb);
-        struct intel_region *region = irb ? irb->region : NULL;
-
-        brw_add_validated_bo(brw, region->buffer);
-        nr_surfaces = SURF_INDEX_DRAW(i) + 1;
-      }
+   for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
+      nr_surfaces = SURF_INDEX_DRAW(i) + 1;
    }
 
    if (brw->wm.const_bo) {
-      brw_add_validated_bo(brw, brw->wm.const_bo);
       nr_surfaces = SURF_INDEX_FRAG_CONST_BUFFER + 1;
    }
 
    for (i = 0; i < BRW_MAX_TEX_UNIT; i++) {
       const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i];
-      struct gl_texture_object *tObj = texUnit->_Current;
-      struct intel_texture_object *intelObj = intel_texture_object(tObj);
 
       if (texUnit->_ReallyEnabled) {
-        brw_add_validated_bo(brw, intelObj->mt->region->buffer);
         nr_surfaces = SURF_INDEX_TEXTURE(i) + 1;
       }
    }
@@ -590,8 +608,7 @@ upload_wm_surfaces(struct brw_context *brw)
       if (texUnit->_ReallyEnabled) {
         brw_update_texture_surface(ctx, i);
       } else {
-         drm_intel_bo_unreference(brw->wm.surf_bo[surf]);
-         brw->wm.surf_bo[surf] = NULL;
+         brw->wm.surf_offset[surf] = 0;
       }
    }
 
@@ -623,20 +640,16 @@ brw_wm_upload_binding_table(struct brw_context *brw)
    /* Might want to calculate nr_surfaces first, to avoid taking up so much
     * space for the binding table.
     */
-   bind = brw_state_batch(brw, sizeof(uint32_t) * BRW_WM_MAX_SURF,
-                         32, &brw->wm.bind_bo, &brw->wm.bind_bo_offset);
+   bind = brw_state_batch(brw, AUB_TRACE_BINDING_TABLE,
+                         sizeof(uint32_t) * BRW_WM_MAX_SURF,
+                         32, &brw->wm.bind_bo_offset);
 
    for (i = 0; i < BRW_WM_MAX_SURF; i++) {
       /* BRW_NEW_WM_SURFACES */
       bind[i] = brw->wm.surf_offset[i];
-      if (brw->wm.surf_bo[i]) {
-        bind[i] = brw->wm.surf_offset[i];
-      } else {
-        bind[i] = 0;
-      }
    }
 
-   brw->state.dirty.brw |= BRW_NEW_BINDING_TABLE;
+   brw->state.dirty.brw |= BRW_NEW_PS_BINDING_TABLE;
 }
 
 const struct brw_tracked_state brw_wm_binding_table = {