diff options
author | Eric Anholt <[email protected]> | 2011-05-12 09:03:24 -0700 |
---|---|---|
committer | Eric Anholt <[email protected]> | 2011-05-31 12:23:50 -0700 |
commit | c331b3123ecda127919458e24848b7c1596525ac (patch) | |
tree | ed09f17fb8c7eaee4524997812fe47d69da1f25b | |
parent | 089aa313b40b495e9d9a9d209fe3851d43807f6e (diff) |
i965/fs: Use the embedded compare in SEL on gen6+.
This avoids the extra CMP and the predication on SEL, so in addition
to one less instruction, it makes scheduling less constrained.
Improves glbenchmark Egypt performance 0.6% +/- 0.2% (n=3). Reduces
FS instruction count across affected shaders in shader-db by 1.3%
without regressing any.
Reviewed-by: Kenneth Graunke <[email protected]>
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_fs.cpp | 12 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_fs_visitor.cpp | 34 |
2 files changed, 30 insertions, 16 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp index 36040c3e071..09033aecd7c 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs.cpp @@ -1033,12 +1033,16 @@ fs_visitor::propagate_constants() scan_inst->src[i] = inst->src[0]; progress = true; } else if (i == 0 && scan_inst->src[1].file != IMM) { - /* Fit this constant in by swapping the operands and - * flipping the predicate - */ scan_inst->src[0] = scan_inst->src[1]; scan_inst->src[1] = inst->src[0]; - scan_inst->predicate_inverse = !scan_inst->predicate_inverse; + + /* If this was predicated, flipping operands means + * we also need to flip the predicate. + */ + if (scan_inst->conditional_mod == BRW_CONDITIONAL_NONE) { + scan_inst->predicate_inverse = + !scan_inst->predicate_inverse; + } progress = true; } break; diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp index 6e81256cec5..b4857871c78 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp @@ -386,24 +386,34 @@ fs_visitor::visit(ir_expression *ir) break; case ir_binop_min: - /* Unalias the destination */ - this->result = fs_reg(this, ir->type); + if (intel->gen >= 6) { + inst = emit(BRW_OPCODE_SEL, this->result, op[0], op[1]); + inst->conditional_mod = BRW_CONDITIONAL_L; + } else { + /* Unalias the destination */ + this->result = fs_reg(this, ir->type); - inst = emit(BRW_OPCODE_CMP, this->result, op[0], op[1]); - inst->conditional_mod = BRW_CONDITIONAL_L; + inst = emit(BRW_OPCODE_CMP, this->result, op[0], op[1]); + inst->conditional_mod = BRW_CONDITIONAL_L; - inst = emit(BRW_OPCODE_SEL, this->result, op[0], op[1]); - inst->predicated = true; + inst = emit(BRW_OPCODE_SEL, this->result, op[0], op[1]); + inst->predicated = true; + } break; case ir_binop_max: - /* Unalias the destination */ - this->result = fs_reg(this, ir->type); + if (intel->gen >= 6) { + inst = emit(BRW_OPCODE_SEL, this->result, op[0], op[1]); + inst->conditional_mod = BRW_CONDITIONAL_GE; + } else { + /* Unalias the destination */ + this->result = fs_reg(this, ir->type); - inst = emit(BRW_OPCODE_CMP, this->result, op[0], op[1]); - inst->conditional_mod = BRW_CONDITIONAL_G; + inst = emit(BRW_OPCODE_CMP, this->result, op[0], op[1]); + inst->conditional_mod = BRW_CONDITIONAL_G; - inst = emit(BRW_OPCODE_SEL, this->result, op[0], op[1]); - inst->predicated = true; + inst = emit(BRW_OPCODE_SEL, this->result, op[0], op[1]); + inst->predicated = true; + } break; case ir_binop_pow: |