[Mesa-dev] [PATCH] i965/fs: Use the embedded compare in SEL on gen6+.
Eric Anholt
eric at anholt.net
Fri May 27 19:52:13 PDT 2011
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.
---
src/mesa/drivers/dri/i965/brw_fs.cpp | 12 ++++++---
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 36040c3..09033ae 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 6e81256..b485787 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:
--
1.7.5.1
More information about the mesa-dev
mailing list