diff options
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_fs.cpp | 26 | ||||
-rw-r--r-- | 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 34f978435af..1b2989f46ec 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 896dc57705b..f546fabd557 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); |