i965/vec4: Emit shader w/a for Gen6 gather
authorChris Forbes <chrisf@ijw.co.nz>
Mon, 3 Feb 2014 09:15:41 +0000 (22:15 +1300)
committerChris Forbes <chrisf@ijw.co.nz>
Fri, 7 Feb 2014 21:32:23 +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_vec4.h
src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp

index e17b5cd..1cf74db 100644 (file)
@@ -482,6 +482,7 @@ public:
 
    uint32_t gather_channel(ir_texture *ir, int sampler);
    src_reg emit_mcs_fetch(ir_texture *ir, src_reg coordinate, int sampler);
+   void emit_gen6_gather_wa(uint8_t wa, dst_reg dst);
    void swizzle_result(ir_texture *ir, src_reg orig_val, int sampler);
 
    void emit_ndc_computation();
index aa5fb6a..5da043c 100644 (file)
@@ -2499,10 +2499,41 @@ vec4_visitor::visit(ir_texture *ir)
       }
    }
 
+   if (brw->gen == 6 && ir->op == ir_tg4) {
+      emit_gen6_gather_wa(key->tex.gen6_gather_wa[sampler], inst->dst);
+   }
+
    swizzle_result(ir, src_reg(inst->dst), sampler);
 }
 
 /**
+ * Apply workarounds for Gen6 gather with UINT/SINT
+ */
+void
+vec4_visitor::emit_gen6_gather_wa(uint8_t wa, dst_reg dst)
+{
+   if (!wa)
+      return;
+
+   int width = (wa & WA_8BIT) ? 8 : 16;
+   dst_reg dst_f = dst;
+   dst_f.type = BRW_REGISTER_TYPE_F;
+
+   /* Convert from UNORM to UINT */
+   emit(MUL(dst_f, src_reg(dst_f), src_reg((float)((1 << width) - 1))));
+   emit(MOV(dst, src_reg(dst_f)));
+
+   if (wa & WA_SIGN) {
+      /* Reinterpret the UINT value as a signed INT value by
+       * shifting the sign bit into place, then shifting back
+       * preserving sign.
+       */
+      emit(SHL(dst, src_reg(dst), src_reg(32 - width)));
+      emit(ASR(dst, src_reg(dst), src_reg(32 - width)));
+   }
+}
+
+/**
  * Set up the gather channel based on the swizzle, for gather4.
  */
 uint32_t