From: Eric Anholt Date: Thu, 12 May 2011 16:03:24 +0000 (-0700) Subject: i965/fs: Use the embedded compare in SEL on gen6+. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c331b3123ecda127919458e24848b7c1596525ac;p=mesa.git i965/fs: Use the embedded compare in SEL on gen6+. 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. Reviewed-by: Kenneth Graunke --- diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp index 36040c3e071..09033aecd7c 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 6e81256cec5..b4857871c78 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: