summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Forbes <chrisf@ijw.co.nz>2013-10-27 12:32:03 +1300
committerCarl Worth <cworth@cworth.org>2013-12-12 16:00:58 -0800
commit83f1f6d2ef0aed8b5515d063361850fa7a261454 (patch)
tree0e8330ee47c712586ba1b161de44281a44afeb64
parent56b0e3271a26d90f760319434ccb518b205dc2bb (diff)
i965/fs: Gen4-5: Implement alpha test in shader for MRT
V2: Add comment explaining what emit_alpha_test() is for; fix spurious temp and bogus whitespace. Signed-off-by: Chris Forbes <chrisf@ijw.co.nz> Reviewed-by: Eric Anholt <eric@anholt.net> (cherry picked from commit f7e15fcf56595aac99644292386a6e6d06dc6ec0)
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs.cpp3
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs.h1
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_visitor.cpp54
3 files changed, 58 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index e96e5ff49e5..50a4684efcf 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -2944,6 +2944,9 @@ fs_visitor::run()
emit(FS_OPCODE_PLACEHOLDER_HALT);
+ if (c->key.alpha_test_func)
+ emit_alpha_test();
+
emit_fb_writes();
split_virtual_grfs();
diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h
index 0645fb75a78..a4740a771dd 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.h
+++ b/src/mesa/drivers/dri/i965/brw_fs.h
@@ -395,6 +395,7 @@ public:
fs_reg dst, fs_reg src0, fs_reg src1, fs_reg one);
void emit_color_write(int target, int index, int first_color_mrf);
+ void emit_alpha_test();
void emit_fb_writes();
void emit_shader_time_begin();
diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
index b52690b920f..457e0ee810c 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
@@ -2228,6 +2228,60 @@ fs_visitor::emit_color_write(int target, int index, int first_color_mrf)
}
}
+static int
+cond_for_alpha_func(GLenum func)
+{
+ switch(func) {
+ case GL_GREATER:
+ return BRW_CONDITIONAL_G;
+ case GL_GEQUAL:
+ return BRW_CONDITIONAL_GE;
+ case GL_LESS:
+ return BRW_CONDITIONAL_L;
+ case GL_LEQUAL:
+ return BRW_CONDITIONAL_LE;
+ case GL_EQUAL:
+ return BRW_CONDITIONAL_EQ;
+ case GL_NOTEQUAL:
+ return BRW_CONDITIONAL_NEQ;
+ default:
+ assert(!"Not reached");
+ return 0;
+ }
+}
+
+/**
+ * Alpha test support for when we compile it into the shader instead
+ * of using the normal fixed-function alpha test.
+ */
+void
+fs_visitor::emit_alpha_test()
+{
+ this->current_annotation = "Alpha test";
+
+ fs_inst *cmp;
+ if (c->key.alpha_test_func == GL_ALWAYS)
+ return;
+
+ if (c->key.alpha_test_func == GL_NEVER) {
+ /* f0.1 = 0 */
+ fs_reg some_reg = fs_reg(retype(brw_vec8_grf(0, 0),
+ BRW_REGISTER_TYPE_UW));
+ cmp = emit(CMP(reg_null_f, some_reg, some_reg,
+ BRW_CONDITIONAL_NEQ));
+ } else {
+ /* RT0 alpha */
+ fs_reg color = outputs[0];
+ color.reg_offset += 3;
+
+ /* f0.1 &= func(color, ref) */
+ cmp = emit(CMP(reg_null_f, color, fs_reg(c->key.alpha_test_ref),
+ cond_for_alpha_func(c->key.alpha_test_func)));
+ }
+ cmp->predicate = BRW_PREDICATE_NORMAL;
+ cmp->flag_subreg = 1;
+}
+
void
fs_visitor::emit_fb_writes()
{