diff options
author | Chris Forbes <chrisf@ijw.co.nz> | 2013-10-27 12:32:03 +1300 |
---|---|---|
committer | Carl Worth <cworth@cworth.org> | 2013-12-12 16:00:58 -0800 |
commit | 83f1f6d2ef0aed8b5515d063361850fa7a261454 (patch) | |
tree | 0e8330ee47c712586ba1b161de44281a44afeb64 | |
parent | 56b0e3271a26d90f760319434ccb518b205dc2bb (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.cpp | 3 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_fs.h | 1 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_fs_visitor.cpp | 54 |
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() { |