diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_fs.h | 2 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_fs_visitor.cpp | 52 |
2 files changed, 23 insertions, 31 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h index 72b51b719bd..2209e416b6d 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.h +++ b/src/mesa/drivers/dri/i965/brw_fs.h @@ -316,6 +316,8 @@ public: fs_reg shadow_comp, fs_reg lod, fs_reg lod2); fs_inst *emit_math(enum opcode op, fs_reg dst, fs_reg src0); fs_inst *emit_math(enum opcode op, fs_reg dst, fs_reg src0, fs_reg src1); + void emit_minmax(uint32_t conditionalmod, fs_reg dst, + fs_reg src0, fs_reg src1); bool try_emit_saturate(ir_expression *ir); bool try_emit_mad(ir_expression *ir, int mul_arg); void emit_bool_to_cond_code(ir_rvalue *condition); diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp index f60b622b67b..134238d42a6 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp @@ -178,6 +178,24 @@ fs_visitor::visit(ir_dereference_array *ir) } } +void +fs_visitor::emit_minmax(uint32_t conditionalmod, fs_reg dst, + fs_reg src0, fs_reg src1) +{ + fs_inst *inst; + + if (intel->gen >= 6) { + inst = emit(BRW_OPCODE_SEL, dst, src0, src1); + inst->conditional_mod = conditionalmod; + } else { + inst = emit(BRW_OPCODE_CMP, reg_null_cmp, src0, src1); + inst->conditional_mod = conditionalmod; + + inst = emit(BRW_OPCODE_SEL, dst, src0, src1); + inst->predicated = true; + } +} + /* Instruction selection: Produce a MOV.sat instead of * MIN(MAX(val, 0), 1) when possible. */ @@ -515,40 +533,12 @@ fs_visitor::visit(ir_expression *ir) break; case ir_binop_min: - resolve_ud_negate(&op[0]); - resolve_ud_negate(&op[1]); - - 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_SEL, this->result, op[0], op[1]); - inst->predicated = true; - } - break; case ir_binop_max: resolve_ud_negate(&op[0]); resolve_ud_negate(&op[1]); - - 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_SEL, this->result, op[0], op[1]); - inst->predicated = true; - } + emit_minmax(ir->operation == ir_binop_min ? + BRW_CONDITIONAL_L : BRW_CONDITIONAL_GE, + this->result, op[0], op[1]); break; case ir_binop_pow: |