i965: Add surface format overrides for Gen6 gather
authorChris Forbes <chrisf@ijw.co.nz>
Mon, 3 Feb 2014 09:14:45 +0000 (22:14 +1300)
committerChris Forbes <chrisf@ijw.co.nz>
Fri, 7 Feb 2014 21:32:19 +0000 (10:32 +1300)
Signed-off-by: Chris Forbes <chrisf@ijw.co.nz>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/mesa/drivers/dri/i965/brw_wm_surface_state.c

index dd96c9bfd3c39e6362c41df822949738ff9e36b1..d16953f9db0f41308e24678401929cca3e13026e 100644 (file)
@@ -282,15 +282,42 @@ brw_update_texture_surface(struct gl_context *ctx,
    surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE,
                          6 * 4, 32, surf_offset);
 
-   (void) for_gather;   /* no w/a to apply for this gen */
+   uint32_t tex_format = translate_tex_format(brw, mt->format,
+                                              sampler->sRGBDecode);
+
+   if (for_gather) {
+      /* Sandybridge's gather4 message is broken for integer formats.
+       * To work around this, we pretend the surface is UNORM for
+       * 8 or 16-bit formats, and emit shader instructions to recover
+       * the real INT/UINT value.  For 32-bit formats, we pretend
+       * the surface is FLOAT, and simply reinterpret the resulting
+       * bits.
+       */
+      switch (tex_format) {
+      case BRW_SURFACEFORMAT_R8_SINT:
+      case BRW_SURFACEFORMAT_R8_UINT:
+         tex_format = BRW_SURFACEFORMAT_R8_UNORM;
+         break;
+
+      case BRW_SURFACEFORMAT_R16_SINT:
+      case BRW_SURFACEFORMAT_R16_UINT:
+         tex_format = BRW_SURFACEFORMAT_R16_UNORM;
+         break;
+
+      case BRW_SURFACEFORMAT_R32_SINT:
+      case BRW_SURFACEFORMAT_R32_UINT:
+         tex_format = BRW_SURFACEFORMAT_R32_FLOAT;
+         break;
+
+      default:
+         break;
+      }
+   }
 
    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(brw,
-                                    mt->format,
-                                   sampler->sRGBDecode) <<
-              BRW_SURFACE_FORMAT_SHIFT));
+             tex_format << BRW_SURFACE_FORMAT_SHIFT);
 
    surf[1] = intelObj->mt->region->bo->offset64 + intelObj->mt->offset; /* reloc */