i965/fs: Gen4-5: Implement alpha test in shader for MRT
authorChris Forbes <chrisf@ijw.co.nz>
Sat, 26 Oct 2013 23:32:03 +0000 (12:32 +1300)
committerChris Forbes <chrisf@ijw.co.nz>
Wed, 6 Nov 2013 06:29:52 +0000 (19:29 +1300)
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>
src/mesa/drivers/dri/i965/brw_fs.cpp
src/mesa/drivers/dri/i965/brw_fs.h
src/mesa/drivers/dri/i965/brw_fs_visitor.cpp

index cd806c7..ee7b07d 100644 (file)
@@ -3252,6 +3252,9 @@ fs_visitor::run()
 
       emit(FS_OPCODE_PLACEHOLDER_HALT);
 
+      if (c->key.alpha_test_func)
+         emit_alpha_test();
+
       emit_fb_writes();
 
       split_virtual_grfs();
index 4f97a67..dcd5b19 100644 (file)
@@ -394,6 +394,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();
index 900d4a5..4f1036a 100644 (file)
@@ -2610,6 +2610,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()
 {