i965: Add Gen6 gather wa to sampler key
authorChris Forbes <chrisf@ijw.co.nz>
Mon, 3 Feb 2014 09:13:03 +0000 (22:13 +1300)
committerChris Forbes <chrisf@ijw.co.nz>
Fri, 7 Feb 2014 21:32:06 +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_program.h
src/mesa/drivers/dri/i965/brw_wm.c

index 51182ea..d7fbe9c 100644 (file)
 #ifndef BRW_PROGRAM_H
 #define BRW_PROGRAM_H
 
+enum gen6_gather_sampler_wa {
+   WA_SIGN = 1,      /* whether we need to sign extend */
+   WA_8BIT = 2,      /* if we have an 8bit format needing wa */
+   WA_16BIT = 4,     /* if we have a 16bit format needing wa */
+};
+
 /**
  * Sampler information needed by VS, WM, and GS program cache keys.
  */
@@ -50,6 +56,11 @@ struct brw_sampler_prog_key_data {
     * Whether this sampler uses the compressed multisample surface layout.
     */
    uint16_t compressed_multisample_layout_mask;
+
+   /**
+    * For Sandybridge, which shader w/a we need for gather quirks.
+    */
+   uint8_t gen6_gather_wa[MAX_SAMPLERS];
 };
 
 #ifdef __cplusplus
index a0758d2..7eccbcb 100644 (file)
@@ -317,6 +317,20 @@ brw_wm_debug_recompile(struct brw_context *brw,
    }
 }
 
+static uint8_t
+gen6_gather_workaround(GLenum internalformat)
+{
+   switch (internalformat) {
+      case GL_R8I: return WA_SIGN | WA_8BIT;
+      case GL_R8UI: return WA_8BIT;
+      case GL_R16I: return WA_SIGN | WA_16BIT;
+      case GL_R16UI: return WA_16BIT;
+      /* note that even though GL_R32I and GL_R32UI have format overrides
+       * in the surface state, there is no shader w/a required */
+      default: return 0;
+   }
+}
+
 void
 brw_populate_sampler_prog_key_data(struct gl_context *ctx,
                                   const struct gl_program *prog,
@@ -372,6 +386,13 @@ brw_populate_sampler_prog_key_data(struct gl_context *ctx,
                key->gather_channel_quirk_mask |= 1 << s;
          }
 
+         /* Gen6's gather4 is broken for UINT/SINT; we treat them as
+          * UNORM/FLOAT instead and fix it in the shader.
+          */
+         if (brw->gen == 6 && prog->UsesGather) {
+            key->gen6_gather_wa[s] = gen6_gather_workaround(img->InternalFormat);
+         }
+
          /* If this is a multisample sampler, and uses the CMS MSAA layout,
           * then we need to emit slightly different code to first sample the
           * MCS surface.