Mesa (master): i965: Recognize saturates and turn them into a saturated mov .

Eric Anholt anholt at kemper.freedesktop.org
Sat Nov 20 03:16:28 UTC 2010


Module: Mesa
Branch: master
Commit: 19631fab35ca4d5ca64d606922f3f20774b27645
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=19631fab35ca4d5ca64d606922f3f20774b27645

Author: Eric Anholt <eric at anholt.net>
Date:   Fri Nov 19 10:36:06 2010 +0800

i965: Recognize saturates and turn them into a saturated mov.

On pre-gen6, this turns 4 instructions into 1.  We could still do
better by folding the saturate into the instruction generating the
value if nobody else uses it, but that should be a separate pass.

---

 src/mesa/drivers/dri/i965/brw_fs.cpp |   26 ++++++++++++++++++++++++++
 src/mesa/drivers/dri/i965/brw_fs.h   |    1 +
 2 files changed, 27 insertions(+), 0 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index 34f9784..1b2989f 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -704,6 +704,27 @@ fs_visitor::visit(ir_dereference_array *ir)
    }
 }
 
+/* Instruction selection: Produce a MOV.sat instead of
+ * MIN(MAX(val, 0), 1) when possible.
+ */
+bool
+fs_visitor::try_emit_saturate(ir_expression *ir)
+{
+   ir_rvalue *sat_val = ir->as_rvalue_to_saturate();
+
+   if (!sat_val)
+      return false;
+
+   sat_val->accept(this);
+   fs_reg src = this->result;
+
+   this->result = fs_reg(this, ir->type);
+   fs_inst *inst = emit(fs_inst(BRW_OPCODE_MOV, this->result, src));
+   inst->saturate = true;
+
+   return true;
+}
+
 void
 fs_visitor::visit(ir_expression *ir)
 {
@@ -712,6 +733,10 @@ fs_visitor::visit(ir_expression *ir)
    fs_inst *inst;
 
    assert(ir->get_num_operands() <= 2);
+
+   if (try_emit_saturate(ir))
+      return;
+
    for (operand = 0; operand < ir->get_num_operands(); operand++) {
       ir->operands[operand]->accept(this);
       if (this->result.file == BAD_FILE) {
@@ -3162,6 +3187,7 @@ fs_visitor::generate_code()
 
       brw_set_conditionalmod(p, inst->conditional_mod);
       brw_set_predicate_control(p, inst->predicated);
+      brw_set_saturate(p, inst->saturate);
 
       switch (inst->opcode) {
       case BRW_OPCODE_MOV:
diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h
index 896dc57..f546fab 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.h
+++ b/src/mesa/drivers/dri/i965/brw_fs.h
@@ -397,6 +397,7 @@ public:
    fs_inst *emit_texture_gen5(ir_texture *ir, fs_reg dst, fs_reg coordinate);
    fs_inst *emit_math(fs_opcodes op, fs_reg dst, fs_reg src0);
    fs_inst *emit_math(fs_opcodes op, fs_reg dst, fs_reg src0, fs_reg src1);
+   bool try_emit_saturate(ir_expression *ir);
    void emit_bool_to_cond_code(ir_rvalue *condition);
    void emit_if_gen6(ir_if *ir);
    void emit_unspill(fs_inst *inst, fs_reg reg, uint32_t spill_offset);




More information about the mesa-commit mailing list