mesa: add/update comments in _mesa_copy_buffer_subdata()
[mesa.git] / src / mesa / drivers / dri / i965 / brw_wm_surface_state.c
index 4308432b1289b348d4c95a72dbfc01ffea271644..dedf59437c9513dd00acada3b76069901e46f3f3 100644 (file)
@@ -38,6 +38,7 @@
 #include "intel_batchbuffer.h"
 #include "intel_tex.h"
 #include "intel_fbo.h"
+#include "intel_buffer_objects.h"
 
 #include "brw_context.h"
 #include "brw_state.h"
@@ -57,6 +58,7 @@ translate_tex_target(GLenum target)
 
    case GL_TEXTURE_2D: 
    case GL_TEXTURE_2D_ARRAY_EXT:
+   case GL_TEXTURE_EXTERNAL_OES:
       return BRW_SURFACE_2D;
 
    case GL_TEXTURE_3D: 
@@ -278,83 +280,181 @@ const struct surface_format_info surface_formats[] = {
 uint32_t
 brw_format_for_mesa_format(gl_format mesa_format)
 {
+   /* This table is ordered according to the enum ordering in formats.h.  We do
+    * expect that enum to be extended without our explicit initialization
+    * staying in sync, so we initialize to 0 even though
+    * BRW_SURFACEFORMAT_R32G32B32A32_FLOAT happens to also be 0.
+    */
    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_L16] = BRW_SURFACEFORMAT_L16_UNORM,
-      [MESA_FORMAT_A16] = BRW_SURFACEFORMAT_A16_UNORM,
-      [MESA_FORMAT_I16] = BRW_SURFACEFORMAT_I16_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_RGBA8888] = 0,
+      [MESA_FORMAT_RGBA8888_REV] = 0,
       [MESA_FORMAT_ARGB8888] = BRW_SURFACEFORMAT_B8G8R8A8_UNORM,
+      [MESA_FORMAT_ARGB8888_REV] = 0,
       [MESA_FORMAT_XRGB8888] = BRW_SURFACEFORMAT_B8G8R8X8_UNORM,
+      [MESA_FORMAT_XRGB8888_REV] = 0,
+      [MESA_FORMAT_RGB888] = 0,
+      [MESA_FORMAT_BGR888] = 0,
       [MESA_FORMAT_RGB565] = BRW_SURFACEFORMAT_B5G6R5_UNORM,
-      [MESA_FORMAT_ARGB1555] = BRW_SURFACEFORMAT_B5G5R5A1_UNORM,
+      [MESA_FORMAT_RGB565_REV] = 0,
       [MESA_FORMAT_ARGB4444] = BRW_SURFACEFORMAT_B4G4R4A4_UNORM,
+      [MESA_FORMAT_ARGB4444_REV] = 0,
+      [MESA_FORMAT_RGBA5551] = 0,
+      [MESA_FORMAT_ARGB1555] = BRW_SURFACEFORMAT_B5G5R5A1_UNORM,
+      [MESA_FORMAT_ARGB1555_REV] = 0,
+      [MESA_FORMAT_AL44] = 0,
+      [MESA_FORMAT_AL88] = BRW_SURFACEFORMAT_L8A8_UNORM,
+      [MESA_FORMAT_AL88_REV] = 0,
+      [MESA_FORMAT_AL1616] = BRW_SURFACEFORMAT_L16A16_UNORM,
+      [MESA_FORMAT_AL1616_REV] = 0,
+      [MESA_FORMAT_RGB332] = 0,
+      [MESA_FORMAT_A8] = BRW_SURFACEFORMAT_A8_UNORM,
+      [MESA_FORMAT_A16] = BRW_SURFACEFORMAT_A16_UNORM,
+      [MESA_FORMAT_L8] = BRW_SURFACEFORMAT_L8_UNORM,
+      [MESA_FORMAT_L16] = BRW_SURFACEFORMAT_L16_UNORM,
+      [MESA_FORMAT_I8] = BRW_SURFACEFORMAT_I8_UNORM,
+      [MESA_FORMAT_I16] = BRW_SURFACEFORMAT_I16_UNORM,
       [MESA_FORMAT_YCBCR_REV] = BRW_SURFACEFORMAT_YCRCB_NORMAL,
       [MESA_FORMAT_YCBCR] = BRW_SURFACEFORMAT_YCRCB_SWAPUVY,
+      [MESA_FORMAT_R8] = BRW_SURFACEFORMAT_R8_UNORM,
+      [MESA_FORMAT_GR88] = BRW_SURFACEFORMAT_R8G8_UNORM,
+      [MESA_FORMAT_RG88] = 0,
+      [MESA_FORMAT_R16] = BRW_SURFACEFORMAT_R16_UNORM,
+      [MESA_FORMAT_RG1616] = BRW_SURFACEFORMAT_R16G16_UNORM,
+      [MESA_FORMAT_RG1616_REV] = 0,
+      [MESA_FORMAT_ARGB2101010] = BRW_SURFACEFORMAT_B10G10R10A2_UNORM,
+      [MESA_FORMAT_Z24_S8] = 0,
+      [MESA_FORMAT_S8_Z24] = 0,
+      [MESA_FORMAT_Z16] = 0,
+      [MESA_FORMAT_X8_Z24] = 0,
+      [MESA_FORMAT_Z24_S8] = 0,
+      [MESA_FORMAT_Z32] = 0,
+      [MESA_FORMAT_S8] = 0,
+
+      [MESA_FORMAT_SRGB8] = 0,
+      [MESA_FORMAT_SRGBA8] = 0,
+      [MESA_FORMAT_SARGB8] = BRW_SURFACEFORMAT_B8G8R8A8_UNORM_SRGB,
+      [MESA_FORMAT_SL8] = BRW_SURFACEFORMAT_L8_UNORM_SRGB,
+      [MESA_FORMAT_SLA8] = BRW_SURFACEFORMAT_L8A8_UNORM_SRGB,
+      [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_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_RGBA_FLOAT16] = BRW_SURFACEFORMAT_R16G16B16A16_FLOAT,
+      [MESA_FORMAT_RGB_FLOAT32] = 0,
+      [MESA_FORMAT_RGB_FLOAT16] = 0,
       [MESA_FORMAT_ALPHA_FLOAT32] = BRW_SURFACEFORMAT_A32_FLOAT,
+      [MESA_FORMAT_ALPHA_FLOAT16] = BRW_SURFACEFORMAT_A16_FLOAT,
+      [MESA_FORMAT_LUMINANCE_FLOAT32] = BRW_SURFACEFORMAT_L32_FLOAT,
+      [MESA_FORMAT_LUMINANCE_FLOAT16] = BRW_SURFACEFORMAT_L16_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,
+      [MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16] = BRW_SURFACEFORMAT_L16A16_FLOAT,
+      [MESA_FORMAT_INTENSITY_FLOAT32] = BRW_SURFACEFORMAT_I32_FLOAT,
+      [MESA_FORMAT_INTENSITY_FLOAT16] = BRW_SURFACEFORMAT_I16_FLOAT,
+      [MESA_FORMAT_R_FLOAT32] = BRW_SURFACEFORMAT_R32_FLOAT,
+      [MESA_FORMAT_R_FLOAT16] = BRW_SURFACEFORMAT_R16_FLOAT,
+      [MESA_FORMAT_RG_FLOAT32] = BRW_SURFACEFORMAT_R32G32_FLOAT,
+      [MESA_FORMAT_RG_FLOAT16] = BRW_SURFACEFORMAT_R16G16_FLOAT,
+
+      [MESA_FORMAT_ALPHA_UINT8] = 0,
+      [MESA_FORMAT_ALPHA_UINT16] = 0,
+      [MESA_FORMAT_ALPHA_UINT32] = 0,
+      [MESA_FORMAT_ALPHA_INT8] = 0,
+      [MESA_FORMAT_ALPHA_INT16] = 0,
+      [MESA_FORMAT_ALPHA_INT32] = 0,
+
+      [MESA_FORMAT_INTENSITY_UINT8] = 0,
+      [MESA_FORMAT_INTENSITY_UINT16] = 0,
+      [MESA_FORMAT_INTENSITY_UINT32] = 0,
+      [MESA_FORMAT_INTENSITY_INT8] = 0,
+      [MESA_FORMAT_INTENSITY_INT16] = 0,
+      [MESA_FORMAT_INTENSITY_INT32] = 0,
+
+      [MESA_FORMAT_LUMINANCE_UINT8] = 0,
+      [MESA_FORMAT_LUMINANCE_UINT16] = 0,
+      [MESA_FORMAT_LUMINANCE_UINT32] = 0,
+      [MESA_FORMAT_LUMINANCE_INT8] = 0,
+      [MESA_FORMAT_LUMINANCE_INT16] = 0,
+      [MESA_FORMAT_LUMINANCE_INT32] = 0,
+
+      [MESA_FORMAT_LUMINANCE_ALPHA_UINT8] = 0,
+      [MESA_FORMAT_LUMINANCE_ALPHA_UINT16] = 0,
+      [MESA_FORMAT_LUMINANCE_ALPHA_UINT32] = 0,
+      [MESA_FORMAT_LUMINANCE_ALPHA_INT8] = 0,
+      [MESA_FORMAT_LUMINANCE_ALPHA_INT16] = 0,
+      [MESA_FORMAT_LUMINANCE_ALPHA_INT32] = 0,
 
+      [MESA_FORMAT_R_INT8] = BRW_SURFACEFORMAT_R8_SINT,
+      [MESA_FORMAT_RG_INT8] = BRW_SURFACEFORMAT_R8G8_SINT,
+      [MESA_FORMAT_RGB_INT8] = 0,
+      [MESA_FORMAT_RGBA_INT8] = BRW_SURFACEFORMAT_R8G8B8A8_SINT,
+      [MESA_FORMAT_R_INT16] = BRW_SURFACEFORMAT_R16_SINT,
+      [MESA_FORMAT_RG_INT16] = BRW_SURFACEFORMAT_R16G16_SINT,
+      [MESA_FORMAT_RGB_INT16] = 0,
+      [MESA_FORMAT_RGBA_INT16] = BRW_SURFACEFORMAT_R16G16B16A16_SINT,
       [MESA_FORMAT_R_INT32] = BRW_SURFACEFORMAT_R32_SINT,
       [MESA_FORMAT_RG_INT32] = BRW_SURFACEFORMAT_R32G32_SINT,
       [MESA_FORMAT_RGB_INT32] = BRW_SURFACEFORMAT_R32G32B32_SINT,
       [MESA_FORMAT_RGBA_INT32] = BRW_SURFACEFORMAT_R32G32B32A32_SINT,
 
+      [MESA_FORMAT_R_UINT8] = BRW_SURFACEFORMAT_R8_UINT,
+      [MESA_FORMAT_RG_UINT8] = BRW_SURFACEFORMAT_R8G8_UINT,
+      [MESA_FORMAT_RGB_UINT8] = 0,
+      [MESA_FORMAT_RGBA_UINT8] = BRW_SURFACEFORMAT_R8G8B8A8_UINT,
+      [MESA_FORMAT_R_UINT16] = BRW_SURFACEFORMAT_R16_UINT,
+      [MESA_FORMAT_RG_UINT16] = BRW_SURFACEFORMAT_R16G16_UINT,
+      [MESA_FORMAT_RGB_UINT16] = 0,
+      [MESA_FORMAT_RGBA_UINT16] = BRW_SURFACEFORMAT_R16G16B16A16_UINT,
       [MESA_FORMAT_R_UINT32] = BRW_SURFACEFORMAT_R32_UINT,
       [MESA_FORMAT_RG_UINT32] = BRW_SURFACEFORMAT_R32G32_UINT,
       [MESA_FORMAT_RGB_UINT32] = BRW_SURFACEFORMAT_R32G32B32_UINT,
       [MESA_FORMAT_RGBA_UINT32] = BRW_SURFACEFORMAT_R32G32B32A32_UINT,
 
-      [MESA_FORMAT_RGBA_UINT16] = BRW_SURFACEFORMAT_R16G16B16A16_UINT,
-      [MESA_FORMAT_RGBA_INT16] = BRW_SURFACEFORMAT_R16G16B16A16_SINT,
-      [MESA_FORMAT_RG_UINT16] = BRW_SURFACEFORMAT_R16G16_UINT,
-      [MESA_FORMAT_RG_INT16] = BRW_SURFACEFORMAT_R16G16_SINT,
-      [MESA_FORMAT_R_UINT16] = BRW_SURFACEFORMAT_R16_UINT,
-      [MESA_FORMAT_R_INT16] = BRW_SURFACEFORMAT_R16_SINT,
+      [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_RGBX8888] = 0,
+      [MESA_FORMAT_SIGNED_RGBA8888] = 0,
+      [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_SIGNED_RGB_16] = 0,
+      [MESA_FORMAT_SIGNED_RGBA_16] = 0,
+      [MESA_FORMAT_RGBA_16] = BRW_SURFACEFORMAT_R16G16B16A16_UNORM,
 
-      [MESA_FORMAT_RGBA_UINT8] = BRW_SURFACEFORMAT_R8G8B8A8_UINT,
-      [MESA_FORMAT_RGBA_INT8] = BRW_SURFACEFORMAT_R8G8B8A8_SINT,
-      [MESA_FORMAT_RG_UINT8] = BRW_SURFACEFORMAT_R8G8_UINT,
-      [MESA_FORMAT_RG_INT8] = BRW_SURFACEFORMAT_R8G8_SINT,
-      [MESA_FORMAT_R_UINT8] = BRW_SURFACEFORMAT_R8_UINT,
-      [MESA_FORMAT_R_INT8] = BRW_SURFACEFORMAT_R8_SINT,
+      [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_L_LATC1] = 0,
+      [MESA_FORMAT_SIGNED_L_LATC1] = 0,
+      [MESA_FORMAT_LA_LATC2] = 0,
+      [MESA_FORMAT_SIGNED_LA_LATC2] = 0,
+
+      [MESA_FORMAT_SIGNED_A8] = 0,
+      [MESA_FORMAT_SIGNED_L8] = 0,
+      [MESA_FORMAT_SIGNED_AL88] = 0,
+      [MESA_FORMAT_SIGNED_I8] = 0,
+      [MESA_FORMAT_SIGNED_A16] = 0,
+      [MESA_FORMAT_SIGNED_L16] = 0,
+      [MESA_FORMAT_SIGNED_AL1616] = 0,
+      [MESA_FORMAT_SIGNED_I16] = 0,
+
+      [MESA_FORMAT_RGB9_E5_FLOAT] = BRW_SURFACEFORMAT_R9G9B9E5_SHAREDEXP,
+      [MESA_FORMAT_R11_G11_B10_FLOAT] = BRW_SURFACEFORMAT_R11G11B10_FLOAT,
+
+      [MESA_FORMAT_Z32_FLOAT] = 0,
+      [MESA_FORMAT_Z32_FLOAT_X24S8] = 0,
    };
    assert(mesa_format < MESA_FORMAT_COUNT);
    return table[mesa_format];
@@ -401,6 +501,10 @@ brw_init_surface_formats(struct brw_context *brw)
       case BRW_SURFACEFORMAT_L32_FLOAT:
         render = BRW_SURFACEFORMAT_R32_FLOAT;
         break;
+      case BRW_SURFACEFORMAT_I16_FLOAT:
+      case BRW_SURFACEFORMAT_L16_FLOAT:
+        render = BRW_SURFACEFORMAT_R16_FLOAT;
+        break;
       case BRW_SURFACEFORMAT_B8G8R8X8_UNORM:
         /* XRGB is handled as ARGB because the chips in this family
          * cannot render to XRGB targets.  This means that we have to
@@ -439,12 +543,16 @@ brw_init_surface_formats(struct brw_context *brw)
    brw->format_supported_as_render_target[MESA_FORMAT_X8_Z24] = true;
    brw->format_supported_as_render_target[MESA_FORMAT_S8] = true;
    brw->format_supported_as_render_target[MESA_FORMAT_Z16] = true;
+   brw->format_supported_as_render_target[MESA_FORMAT_Z32_FLOAT] = true;
+   brw->format_supported_as_render_target[MESA_FORMAT_Z32_FLOAT_X24S8] = true;
 
    /* We remap depth formats to a supported texturing format in
     * translate_tex_format().
     */
    ctx->TextureFormatSupported[MESA_FORMAT_S8_Z24] = true;
    ctx->TextureFormatSupported[MESA_FORMAT_X8_Z24] = true;
+   ctx->TextureFormatSupported[MESA_FORMAT_Z32_FLOAT] = true;
+   ctx->TextureFormatSupported[MESA_FORMAT_Z32_FLOAT_X24S8] = true;
 }
 
 bool
@@ -466,29 +574,18 @@ translate_tex_format(gl_format mesa_format,
    switch( mesa_format ) {
 
    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;
+      return BRW_SURFACEFORMAT_I16_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.
-       */
-      if (depth_mode == GL_INTENSITY) 
-         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;
-      
+      return BRW_SURFACEFORMAT_I24X8_UNORM;
+
+   case MESA_FORMAT_Z32_FLOAT:
+      return BRW_SURFACEFORMAT_I32_FLOAT;
+
+   case MESA_FORMAT_Z32_FLOAT_X24S8:
+      return BRW_SURFACEFORMAT_R32G32_FLOAT;
+
    case MESA_FORMAT_SARGB8:
    case MESA_FORMAT_SLA8:
    case MESA_FORMAT_SL8:
@@ -547,7 +644,7 @@ brw_update_texture_surface( struct gl_context *ctx, GLuint unit )
    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,
+             (translate_tex_format(mt->format,
                                    firstImage->InternalFormat,
                                    sampler->DepthMode,
                                    sampler->sRGBDecode) <<
@@ -620,6 +717,90 @@ brw_create_constant_surface(struct brw_context *brw,
                           I915_GEM_DOMAIN_SAMPLER, 0);
 }
 
+/**
+ * Set up a binding table entry for use by stream output logic (transform
+ * feedback).
+ *
+ * buffer_size_minus_1 must me less than BRW_MAX_NUM_BUFFER_ENTRIES.
+ */
+void
+brw_update_sol_surface(struct brw_context *brw,
+                       struct gl_buffer_object *buffer_obj,
+                       uint32_t *out_offset, unsigned num_vector_components,
+                       unsigned stride_dwords, unsigned offset_dwords)
+{
+   drm_intel_bo *bo = intel_buffer_object(buffer_obj)->buffer;
+   uint32_t *surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE, 6 * 4, 32,
+                                    out_offset);
+   uint32_t pitch_minus_1 = 4*stride_dwords - 1;
+   uint32_t offset_bytes = 4 * offset_dwords;
+   size_t size_dwords = buffer_obj->Size / 4;
+   uint32_t buffer_size_minus_1, width, height, depth, surface_format;
+
+   /* FIXME: can we rely on core Mesa to ensure that the buffer isn't
+    * too big to map using a single binding table entry?
+    */
+   assert((size_dwords - offset_dwords) / stride_dwords
+          <= BRW_MAX_NUM_BUFFER_ENTRIES);
+
+   if (size_dwords > offset_dwords + num_vector_components) {
+      /* There is room for at least 1 transform feedback output in the buffer.
+       * Compute the number of additional transform feedback outputs the
+       * buffer has room for.
+       */
+      buffer_size_minus_1 =
+         (size_dwords - offset_dwords - num_vector_components) / stride_dwords;
+   } else {
+      /* There isn't even room for a single transform feedback output in the
+       * buffer.  We can't configure the binding table entry to prevent output
+       * entirely; we'll have to rely on the geometry shader to detect
+       * overflow.  But to minimize the damage in case of a bug, set up the
+       * binding table entry to just allow a single output.
+       */
+      buffer_size_minus_1 = 0;
+   }
+   width = buffer_size_minus_1 & 0x7f;
+   height = (buffer_size_minus_1 & 0xfff80) >> 7;
+   depth = (buffer_size_minus_1 & 0x7f00000) >> 20;
+
+   switch (num_vector_components) {
+   case 1:
+      surface_format = BRW_SURFACEFORMAT_R32_FLOAT;
+      break;
+   case 2:
+      surface_format = BRW_SURFACEFORMAT_R32G32_FLOAT;
+      break;
+   case 3:
+      surface_format = BRW_SURFACEFORMAT_R32G32B32_FLOAT;
+      break;
+   case 4:
+      surface_format = BRW_SURFACEFORMAT_R32G32B32A32_FLOAT;
+      break;
+   default:
+      assert(!"Invalid vector size for transform feedback output");
+      surface_format = BRW_SURFACEFORMAT_R32_FLOAT;
+      break;
+   }
+
+   surf[0] = BRW_SURFACE_BUFFER << BRW_SURFACE_TYPE_SHIFT |
+      BRW_SURFACE_MIPMAPLAYOUT_BELOW << BRW_SURFACE_MIPLAYOUT_SHIFT |
+      surface_format << BRW_SURFACE_FORMAT_SHIFT |
+      BRW_SURFACE_RC_READ_WRITE;
+   surf[1] = bo->offset + offset_bytes; /* reloc */
+   surf[2] = (width << BRW_SURFACE_WIDTH_SHIFT |
+             height << BRW_SURFACE_HEIGHT_SHIFT);
+   surf[3] = (depth << BRW_SURFACE_DEPTH_SHIFT |
+              pitch_minus_1 << BRW_SURFACE_PITCH_SHIFT);
+   surf[4] = 0;
+   surf[5] = 0;
+
+   /* Emit relocation to surface contents. */
+   drm_intel_bo_emit_reloc(brw->intel.batch.bo,
+                          *out_offset + 4,
+                          bo, offset_bytes,
+                          I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER);
+}
+
 /* Creates a new WM constant buffer reflecting the current fragment program's
  * constants, if needed by the fragment program.
  *
@@ -648,7 +829,7 @@ brw_upload_wm_pull_constants(struct brw_context *brw)
         drm_intel_bo_unreference(brw->wm.const_bo);
         brw->wm.const_bo = NULL;
         brw->bind.surf_offset[surf_index] = 0;
-        brw->state.dirty.brw |= BRW_NEW_WM_SURFACES;
+        brw->state.dirty.brw |= BRW_NEW_SURFACES;
       }
       return;
    }
@@ -670,7 +851,7 @@ brw_upload_wm_pull_constants(struct brw_context *brw)
                                       params->NumParameters,
                                       &brw->bind.surf_offset[surf_index]);
 
-   brw->state.dirty.brw |= BRW_NEW_WM_SURFACES;
+   brw->state.dirty.brw |= BRW_NEW_SURFACES;
 }
 
 const struct brw_tracked_state brw_wm_pull_constants = {
@@ -824,7 +1005,7 @@ brw_update_renderbuffer_surfaces(struct brw_context *brw)
    } else {
       intel->vtbl.update_null_renderbuffer_surface(brw, 0);
    }
-   brw->state.dirty.brw |= BRW_NEW_WM_SURFACES;
+   brw->state.dirty.brw |= BRW_NEW_SURFACES;
 }
 
 const struct brw_tracked_state brw_renderbuffer_surfaces = {
@@ -866,7 +1047,7 @@ brw_update_texture_surfaces(struct brw_context *brw)
       }
    }
 
-   brw->state.dirty.brw |= BRW_NEW_WM_SURFACES;
+   brw->state.dirty.brw |= BRW_NEW_SURFACES;
 }
 
 const struct brw_tracked_state brw_texture_surfaces = {
@@ -895,7 +1076,7 @@ brw_upload_binding_table(struct brw_context *brw)
                          sizeof(uint32_t) * BRW_MAX_SURFACES,
                          32, &brw->bind.bo_offset);
 
-   /* BRW_NEW_WM_SURFACES and BRW_NEW_VS_CONSTBUF */
+   /* BRW_NEW_SURFACES and BRW_NEW_VS_CONSTBUF */
    for (i = 0; i < BRW_MAX_SURFACES; i++) {
       bind[i] = brw->bind.surf_offset[i];
    }
@@ -909,7 +1090,7 @@ const struct brw_tracked_state brw_binding_table = {
       .mesa = 0,
       .brw = (BRW_NEW_BATCH |
              BRW_NEW_VS_CONSTBUF |
-             BRW_NEW_WM_SURFACES),
+             BRW_NEW_SURFACES),
       .cache = 0
    },
    .emit = brw_upload_binding_table,