summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Forbes <chrisf@ijw.co.nz>2014-02-03 22:15:16 +1300
committerChris Forbes <chrisf@ijw.co.nz>2014-02-08 10:32:20 +1300
commit73b91fe05a2b4a09b29c69cfefda3f6c3d0ea68c (patch)
tree0b534d0b25bb1ccfebd25cfe436394201cf3f728
parentc2d51aaa11c2593edb9f4b9279745d39c79ff23c (diff)
i965/fs: Emit shader w/a for Gen6 gather
Signed-off-by: Chris Forbes <chrisf@ijw.co.nz> Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs.h1
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_visitor.cpp34
2 files changed, 35 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h
index 9c5c13ae39..3d668b9e47 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.h
+++ b/src/mesa/drivers/dri/i965/brw_fs.h
@@ -360,6 +360,7 @@ public:
fs_reg shadow_comp, fs_reg lod, fs_reg lod2,
fs_reg sample_index, fs_reg mcs, int sampler);
fs_reg emit_mcs_fetch(ir_texture *ir, fs_reg coordinate, int sampler);
+ void emit_gen6_gather_wa(uint8_t wa, fs_reg dst);
fs_reg fix_math_operand(fs_reg src);
fs_inst *emit_math(enum opcode op, fs_reg dst, fs_reg src0);
fs_inst *emit_math(enum opcode op, fs_reg dst, fs_reg src0, fs_reg src1);
diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
index d88d24c4d8..fd0813c373 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
@@ -1699,10 +1699,44 @@ fs_visitor::visit(ir_texture *ir)
}
}
+ if (brw->gen == 6 && ir->op == ir_tg4) {
+ emit_gen6_gather_wa(c->key.tex.gen6_gather_wa[sampler], dst);
+ }
+
swizzle_result(ir, dst, sampler);
}
/**
+ * Apply workarounds for Gen6 gather with UINT/SINT
+ */
+void
+fs_visitor::emit_gen6_gather_wa(uint8_t wa, fs_reg dst)
+{
+ if (!wa)
+ return;
+
+ int width = (wa & WA_8BIT) ? 8 : 16;
+
+ for (int i = 0; i < 4; i++) {
+ fs_reg dst_f = dst.retype(BRW_REGISTER_TYPE_F);
+ /* Convert from UNORM to UINT */
+ emit(MUL(dst_f, dst_f, fs_reg((float)((1 << width) - 1))));
+ emit(MOV(dst, 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, dst, fs_reg(32 - width)));
+ emit(ASR(dst, dst, fs_reg(32 - width)));
+ }
+
+ dst.reg_offset++;
+ }
+}
+
+/**
* Set up the gather channel based on the swizzle, for gather4.
*/
uint32_t