mesa/965: add support for GL_EXT_framebuffer_sRGB (v2)
[mesa.git] / src / mesa / drivers / dri / i965 / brw_wm_surface_state.c
index 76fc94df1f6bbcaaec3652c11950fa97a7696ffb..c931df3c605cf9f1268e4ef9f66c9bec0a004e4a 100644 (file)
@@ -42,7 +42,7 @@
 #include "brw_context.h"
 #include "brw_state.h"
 #include "brw_defines.h"
-
+#include "brw_wm.h"
 
 static GLuint translate_tex_target( GLenum target )
 {
@@ -68,104 +68,73 @@ static GLuint translate_tex_target( GLenum target )
    }
 }
 
+static uint32_t brw_format_for_mesa_format[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_RGBA8888_REV] = BRW_SURFACEFORMAT_R8G8B8A8_SNORM,
+};
+
+bool
+brw_render_target_supported(gl_format format)
+{
+   if (format == MESA_FORMAT_S8_Z24 ||
+       format == MESA_FORMAT_X8_Z24 ||
+       format == MESA_FORMAT_Z16) {
+      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;
+}
 
 static GLuint translate_tex_format( gl_format mesa_format,
                                     GLenum internal_format,
-                                   GLenum depth_mode )
+                                   GLenum depth_mode, 
+                                   GLenum srgb_decode )
 {
    switch( mesa_format ) {
-   case MESA_FORMAT_L8:
-      return BRW_SURFACEFORMAT_L8_UNORM;
-
-   case MESA_FORMAT_I8:
-      return BRW_SURFACEFORMAT_I8_UNORM;
-
-   case MESA_FORMAT_A8:
-      return BRW_SURFACEFORMAT_A8_UNORM; 
-
-   case MESA_FORMAT_AL88:
-      return BRW_SURFACEFORMAT_L8A8_UNORM;
-
-   case MESA_FORMAT_AL1616:
-      return BRW_SURFACEFORMAT_L16A16_UNORM;
-
-   case MESA_FORMAT_R8:
-      return BRW_SURFACEFORMAT_R8_UNORM;
-
-   case MESA_FORMAT_R16:
-      return BRW_SURFACEFORMAT_R16_UNORM;
-
-   case MESA_FORMAT_RG88:
-      return BRW_SURFACEFORMAT_R8G8_UNORM;
-
-   case MESA_FORMAT_RG1616:
-      return BRW_SURFACEFORMAT_R16G16_UNORM;
-
-   case MESA_FORMAT_RGB888:
-      assert(0);               /* not supported for sampling */
-      return BRW_SURFACEFORMAT_R8G8B8_UNORM;      
-
-   case MESA_FORMAT_ARGB8888:
-      return BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
-
-   case MESA_FORMAT_XRGB8888:
-      return BRW_SURFACEFORMAT_B8G8R8X8_UNORM;
-
-   case MESA_FORMAT_RGBA8888_REV:
-      _mesa_problem(NULL, "unexpected format in i965:translate_tex_format()");
-      return BRW_SURFACEFORMAT_R8G8B8A8_UNORM;
-
-   case MESA_FORMAT_RGB565:
-      return BRW_SURFACEFORMAT_B5G6R5_UNORM;
-
-   case MESA_FORMAT_ARGB1555:
-      return BRW_SURFACEFORMAT_B5G5R5A1_UNORM;
-
-   case MESA_FORMAT_ARGB4444:
-      return BRW_SURFACEFORMAT_B4G4R4A4_UNORM;
-
-   case MESA_FORMAT_YCBCR_REV:
-      return BRW_SURFACEFORMAT_YCRCB_NORMAL;
-
-   case MESA_FORMAT_YCBCR:
-      return BRW_SURFACEFORMAT_YCRCB_SWAPUVY;
-
-   case MESA_FORMAT_RGB_FXT1:
-   case MESA_FORMAT_RGBA_FXT1:
-      return BRW_SURFACEFORMAT_FXT1;
 
    case MESA_FORMAT_Z16:
       if (depth_mode == GL_INTENSITY) 
          return BRW_SURFACEFORMAT_I16_UNORM;
       else if (depth_mode == GL_ALPHA)
          return BRW_SURFACEFORMAT_A16_UNORM;
+      else if (depth_mode == GL_RED)
+         return BRW_SURFACEFORMAT_R16_UNORM;
       else
          return BRW_SURFACEFORMAT_L16_UNORM;
 
-   case MESA_FORMAT_RGB_DXT1:
-       return BRW_SURFACEFORMAT_DXT1_RGB;
-
-   case MESA_FORMAT_RGBA_DXT1:
-       return BRW_SURFACEFORMAT_BC1_UNORM;
-       
-   case MESA_FORMAT_RGBA_DXT3:
-       return BRW_SURFACEFORMAT_BC2_UNORM;
-       
-   case MESA_FORMAT_RGBA_DXT5:
-       return BRW_SURFACEFORMAT_BC3_UNORM;
-
-   case MESA_FORMAT_SARGB8:
-      return BRW_SURFACEFORMAT_B8G8R8A8_UNORM_SRGB;
-
-   case MESA_FORMAT_SLA8:
-      return BRW_SURFACEFORMAT_L8A8_UNORM_SRGB;
-
-   case MESA_FORMAT_SL8:
-      return BRW_SURFACEFORMAT_L8_UNORM_SRGB;
-
-   case MESA_FORMAT_SRGB_DXT1:
-      return BRW_SURFACEFORMAT_BC1_UNORM_SRGB;
-
    case MESA_FORMAT_S8_Z24:
       /* XXX: these different surface formats don't seem to
        * make any difference for shadow sampler/compares.
@@ -174,18 +143,21 @@ static GLuint translate_tex_format( gl_format mesa_format,
          return BRW_SURFACEFORMAT_I24X8_UNORM;
       else if (depth_mode == GL_ALPHA)
          return BRW_SURFACEFORMAT_A24X8_UNORM;
+      else if (depth_mode == GL_RED)
+         return BRW_SURFACEFORMAT_R24_UNORM_X8_TYPELESS;
       else
          return BRW_SURFACEFORMAT_L24X8_UNORM;
-
-   case MESA_FORMAT_DUDV8:
-      return BRW_SURFACEFORMAT_R8G8_SNORM;
-
-   case MESA_FORMAT_SIGNED_RGBA8888_REV:
-      return BRW_SURFACEFORMAT_R8G8B8A8_SNORM;
-
+      
+   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)];
    default:
-      assert(0);
-      return 0;
+      assert(brw_format_for_mesa_format[mesa_format] != 0);
+      return brw_format_for_mesa_format[mesa_format];
    }
 }
 
@@ -214,7 +186,7 @@ brw_update_texture_surface( struct gl_context *ctx, GLuint unit )
    struct brw_context *brw = brw_context(ctx);
    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][intelObj->firstLevel];
+   struct gl_texture_image *firstImage = tObj->Image[0][tObj->BaseLevel];
    const GLuint surf_index = SURF_INDEX_TEXTURE(unit);
    struct brw_surface_state surf;
    void *map;
@@ -225,14 +197,14 @@ brw_update_texture_surface( struct gl_context *ctx, GLuint unit )
    surf.ss0.surface_type = translate_tex_target(tObj->Target);
    surf.ss0.surface_format = translate_tex_format(firstImage->TexFormat,
                                                  firstImage->InternalFormat,
-                                                 tObj->DepthMode);
+                                                 tObj->DepthMode, tObj->sRGBDecode);
 
    /* 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.ss2.mip_count = intelObj->lastLevel - intelObj->firstLevel;
+   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);
@@ -274,6 +246,7 @@ brw_create_constant_surface(struct brw_context *brw,
                            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;
@@ -284,6 +257,9 @@ brw_create_constant_surface(struct brw_context *brw,
    surf.ss0.surface_type = BRW_SURFACE_BUFFER;
    surf.ss0.surface_format = BRW_SURFACEFORMAT_R32G32B32A32_FLOAT;
 
+   if (intel->gen >= 6)
+      surf.ss0.render_cache_read_write = 1;
+
    assert(bo);
    surf.ss1.base_addr = bo->offset; /* reloc */
 
@@ -404,6 +380,38 @@ const struct brw_tracked_state brw_wm_constant_surface = {
    .emit = upload_wm_constant_surface,
 };
 
+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;
+
+   surf.ss2.width = 0;
+   surf.ss2.height = 0;
+   brw_set_surface_tiling(&surf, I915_TILING_NONE);
+   surf.ss3.pitch = 0;
+
+   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;
+   }
+
+   map = brw_state_batch(brw, sizeof(surf), 32,
+                        &brw->wm.surf_bo[unit],
+                        &brw->wm.surf_offset[unit]);
+   memcpy(map, &surf, sizeof(surf));
+}
 
 /**
  * Sets up a surface state structure to point at the given region.
@@ -417,123 +425,56 @@ brw_update_renderbuffer_surface(struct brw_context *brw,
 {
    struct intel_context *intel = &brw->intel;
    struct gl_context *ctx = &intel->ctx;
-   drm_intel_bo *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_x;
-      uint32_t draw_y;
-   } key;
+   struct intel_region *region = irb->region;
    struct brw_surface_state surf;
    void *map;
 
-   memset(&key, 0, sizeof(key));
-
-   if (region != NULL) {
-      region_bo = region->buffer;
-
-      key.surface_type = BRW_SURFACE_2D;
-      switch (irb->Base.Format) {
-      /* XRGB and ARGB are treated the same here because the chips in this
-       * family cannot render to XRGB targets.  This means that we have to
-       * mask writes to alpha (ala glColorMask) and reconfigure the alpha
-       * blending hardware to use GL_ONE (or GL_ZERO) for cases where
-       * GL_DST_ALPHA (or GL_ONE_MINUS_DST_ALPHA) is used.
-       */
-      case MESA_FORMAT_ARGB8888:
-      case MESA_FORMAT_XRGB8888:
-        key.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
-        break;
-      case MESA_FORMAT_SARGB8:
-        key.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM_SRGB;
-        break;
-      case MESA_FORMAT_RGB565:
-        key.surface_format = BRW_SURFACEFORMAT_B5G6R5_UNORM;
-        break;
-      case MESA_FORMAT_ARGB1555:
-        key.surface_format = BRW_SURFACEFORMAT_B5G5R5A1_UNORM;
-        break;
-      case MESA_FORMAT_ARGB4444:
-        key.surface_format = BRW_SURFACEFORMAT_B4G4R4A4_UNORM;
-        break;
-      case MESA_FORMAT_A8:
-        key.surface_format = BRW_SURFACEFORMAT_A8_UNORM;
-        break;
-      case MESA_FORMAT_R8:
-        key.surface_format = BRW_SURFACEFORMAT_R8_UNORM;
-        break;
-      case MESA_FORMAT_R16:
-        key.surface_format = BRW_SURFACEFORMAT_R16_UNORM;
-        break;
-      case MESA_FORMAT_RG88:
-        key.surface_format = BRW_SURFACEFORMAT_R8G8_UNORM;
-        break;
-      case MESA_FORMAT_RG1616:
-        key.surface_format = BRW_SURFACEFORMAT_R16G16_UNORM;
-        break;
-      default:
-        _mesa_problem(ctx, "Bad renderbuffer format: %d\n", irb->Base.Format);
-      }
-      key.tiling = region->tiling;
-      key.width = rb->Width;
-      key.height = rb->Height;
-      key.pitch = region->pitch;
-      key.cpp = region->cpp;
-      key.draw_x = region->draw_x;
-      key.draw_y = region->draw_y;
-   } 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_x = 0;
-      key.draw_y = 0;
-   }
-
-   if (intel->gen < 6) {
-      /* _NEW_COLOR */
-      memcpy(key.color_mask, ctx->Color.ColorMask[unit],
-            sizeof(key.color_mask));
+   memset(&surf, 0, sizeof(surf));
 
-      /* As mentioned above, disable writes to the alpha component when the
-       * renderbuffer is XRGB.
+   switch (irb->Base.Format) {
+   case MESA_FORMAT_XRGB8888:
+      /* XRGB is handled as ARGB because the chips in this family
+       * cannot render to XRGB targets.  This means that we have to
+       * mask writes to alpha (ala glColorMask) and reconfigure the
+       * alpha blending hardware to use GL_ONE (or GL_ZERO) for
+       * cases where GL_DST_ALPHA (or GL_ONE_MINUS_DST_ALPHA) is
+       * used.
        */
-      if (ctx->DrawBuffer->Visual.alphaBits == 0)
-        key.color_mask[3] = GL_FALSE;
-
-      key.color_blend = (!ctx->Color._LogicOpEnabled &&
-                        (ctx->Color.BlendEnabled & (1 << unit)));
+      surf.ss0.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
+      break;
+   case MESA_FORMAT_SARGB8:
+      /* without GL_EXT_framebuffer_sRGB we shouldn't bind sRGB
+        surfaces to the blend/update as sRGB */
+      if (ctx->Color.sRGBEnabled)
+        surf.ss0.surface_format = brw_format_for_mesa_format[irb->Base.Format];
+      else
+        surf.ss0.surface_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);
    }
 
-   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_x + key.draw_y * key.pitch) * key.cpp;
+   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 = key.pitch * key.cpp;
+      uint32_t pitch = region->pitch * region->cpp;
 
-      if (key.tiling == I915_TILING_X) {
-        tile_x = key.draw_x % (512 / key.cpp);
-        tile_y = key.draw_y % 8;
-        tile_base = ((key.draw_y / 8) * (8 * pitch));
-        tile_base += (key.draw_x - tile_x) / (512 / key.cpp) * 4096;
+      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 = key.draw_x % (128 / key.cpp);
-        tile_y = key.draw_y % 32;
-        tile_base = ((key.draw_y / 32) * (32 * pitch));
-        tile_base += (key.draw_x - tile_x) / (128 / key.cpp) * 4096;
+        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);
@@ -545,21 +486,27 @@ brw_update_renderbuffer_surface(struct brw_context *brw,
       surf.ss5.x_offset = tile_x / 4;
       surf.ss5.y_offset = tile_y / 2;
    }
-   if (region_bo != NULL)
-      surf.ss1.base_addr += region_bo->offset; /* reloc */
+   surf.ss1.base_addr += region->buffer->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;
+   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;
 
    if (intel->gen < 6) {
       /* _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];
+      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];
+      /* 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];
    }
 
    map = brw_state_batch(brw, sizeof(surf), 32,
@@ -567,15 +514,13 @@ brw_update_renderbuffer_surface(struct brw_context *brw,
                         &brw->wm.surf_offset[unit]);
    memcpy(map, &surf, sizeof(surf));
 
-   if (region_bo != NULL) {
-      drm_intel_bo_emit_reloc(brw->wm.surf_bo[unit],
-                             brw->wm.surf_offset[unit] +
-                             offsetof(struct brw_surface_state, ss1),
-                             region_bo,
-                             surf.ss1.base_addr - region_bo->offset,
-                             I915_GEM_DOMAIN_RENDER,
-                             I915_GEM_DOMAIN_RENDER);
-   }
+   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,
+                          I915_GEM_DOMAIN_RENDER,
+                          I915_GEM_DOMAIN_RENDER);
 }
 
 static void
@@ -635,12 +580,16 @@ upload_wm_surfaces(struct brw_context *brw)
    /* 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);
+        if (intel_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[i])) {
+           brw_update_renderbuffer_surface(brw,
+                                           ctx->DrawBuffer->_ColorDrawBuffers[i],
+                                           i);
+        } else {
+           brw_update_null_renderbuffer_surface(brw, i);
+        }
       }
    } else {
-      brw_update_renderbuffer_surface(brw, NULL, 0);
+      brw_update_null_renderbuffer_surface(brw, 0);
    }
 
    /* Update surfaces for textures */