diff options
author | Chris Forbes <[email protected]> | 2013-10-27 12:32:03 +1300 |
---|---|---|
committer | Chris Forbes <[email protected]> | 2013-11-06 19:29:52 +1300 |
commit | f7e15fcf56595aac99644292386a6e6d06dc6ec0 (patch) | |
tree | 9e5f4964fbfe46c8be042cd020f1e266e3e5b6c5 /src | |
parent | ca82ba90dd7ef78be2b95972dc19913c76d5e6a8 (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 <[email protected]>
Reviewed-by: Eric Anholt <[email protected]>
Diffstat (limited to 'src')
-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 cd806c77c41..ee7b07d9b75 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs.cpp @@ -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(); diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h index 4f97a67a960..dcd5b19e4d7 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.h +++ b/src/mesa/drivers/dri/i965/brw_fs.h @@ -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(); diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp index 900d4a5902c..4f1036a12cb 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp @@ -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() { |