diff options
author | Kenneth Graunke <[email protected]> | 2013-08-13 16:07:56 -0700 |
---|---|---|
committer | Kenneth Graunke <[email protected]> | 2013-08-15 15:33:00 -0700 |
commit | 90129da82c91b731c7c65e8e3adbde58d8c62840 (patch) | |
tree | 8c287b2cd80242ec31ed13432e38ae1c990e1ef3 | |
parent | c189840b21e176d87cbb382e64e848061b8c7b06 (diff) |
i965/fs: Fix Sandybridge regressions from SEL optimization.
Sandybridge is the only platform that supports an IF instruction
with an embedded comparison. In this case, we need to emit a CMP
to go along with the SEL.
Fixes regressions in Piglit's glsl-fs-atan-3, fs-unpackHalf2x16,
fs-faceforward-float-float-float, isinf-and-isnan fs_basic, and
isinf-and-isnan fs_fbo.
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=68086
Signed-off-by: Kenneth Graunke <[email protected]>
Reviewed-by: Matt Turner <[email protected]>
Reviewed-by: Anuj Phogat <[email protected]>
Tested-by: lu hua <[email protected]>
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_fs_visitor.cpp | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp index a36c248550d..984b08a6b60 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp @@ -1911,10 +1911,19 @@ fs_visitor::try_replace_with_sel() emit(MOV(src0, then_mov->src[0])); } - fs_inst *sel = emit(BRW_OPCODE_SEL, then_mov->dst, src0, else_mov->src[0]); - sel->predicate = if_inst->predicate; - sel->predicate_inverse = if_inst->predicate_inverse; - sel->conditional_mod = if_inst->conditional_mod; + fs_inst *sel; + if (if_inst->conditional_mod) { + /* Sandybridge-specific IF with embedded comparison */ + emit(CMP(reg_null_d, if_inst->src[0], if_inst->src[1], + if_inst->conditional_mod)); + sel = emit(BRW_OPCODE_SEL, then_mov->dst, src0, else_mov->src[0]); + sel->predicate = BRW_PREDICATE_NORMAL; + } else { + /* Separate CMP and IF instructions */ + sel = emit(BRW_OPCODE_SEL, then_mov->dst, src0, else_mov->src[0]); + sel->predicate = if_inst->predicate; + sel->predicate_inverse = if_inst->predicate_inverse; + } } } |