summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2011-05-12 09:03:24 -0700
committerEric Anholt <eric@anholt.net>2011-05-31 12:23:50 -0700
commitc331b3123ecda127919458e24848b7c1596525ac (patch)
treeed09f17fb8c7eaee4524997812fe47d69da1f25b
parent089aa313b40b495e9d9a9d209fe3851d43807f6e (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 <kenneth@whitecape.org>
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs.cpp12
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_visitor.cpp34
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: