From d81d7a4b65565a873338f54b0a17795d91ccc625 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sat, 22 Sep 2012 17:25:20 +0200 Subject: [PATCH] i965/fs: Pull ir_binop_min/ir_binop_max handling to a separate function. This will be reused from the ARB_fp compiler. I touched up the pre-gen6 path to not overwrite dst in the first instruction, which prevents the need for aliasing checks (we'll need that in the ARB_fp compiler, but it actually hasn't been needed in this codebase since the revert of the nasty old MOV-avoidance code). I also made the conditional_mod between gen6 and pre-gen6 consistent, which shouldn't matter except for denorm/(+/-)0 comparisons where the choice between left and right hand side of the comparison changes. Reviewed-by: Kenneth Graunke --- src/mesa/drivers/dri/i965/brw_fs.h | 2 + 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: -- 2.30.2