diff options
author | Matt Turner <[email protected]> | 2014-08-08 21:04:26 -0700 |
---|---|---|
committer | Matt Turner <[email protected]> | 2014-08-18 18:35:53 -0700 |
commit | cc60a487d1bd2b34a07ce6cbe5161684772ecd70 (patch) | |
tree | 24e5c2543a191ee608a2a1b7280d12d9523e0199 | |
parent | 2a6b6621d83b83f4ce499cd0c5b8eb824f07d25d (diff) |
i965/fs: Optimize emit_bool_to_cond_code for logical exprs.
AND, OR, and XOR can generate the conditional code directly.
total instructions in shared programs: 4293335 -> 4292303 (-0.02%)
instructions in affected programs: 121408 -> 120376 (-0.85%)
Reviewed-by: Anuj Phogat <[email protected]>
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_fs_visitor.cpp | 141 |
1 files changed, 87 insertions, 54 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp index 1245c8a7667..fa2c2269356 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp @@ -2228,72 +2228,105 @@ fs_visitor::emit_bool_to_cond_code(ir_rvalue *ir) { ir_expression *expr = ir->as_expression(); - if (expr && - expr->operation != ir_binop_logic_and && - expr->operation != ir_binop_logic_or && - expr->operation != ir_binop_logic_xor) { - fs_reg op[2]; - fs_inst *inst; + if (!expr) { + ir->accept(this); - assert(expr->get_num_operands() <= 2); - for (unsigned int i = 0; i < expr->get_num_operands(); i++) { - assert(expr->operands[i]->type->is_scalar()); + fs_inst *inst = emit(AND(reg_null_d, this->result, fs_reg(1))); + inst->conditional_mod = BRW_CONDITIONAL_NZ; + return; + } - expr->operands[i]->accept(this); - op[i] = this->result; + fs_reg op[2]; + fs_inst *inst; - resolve_ud_negate(&op[i]); - } + assert(expr->get_num_operands() <= 2); + for (unsigned int i = 0; i < expr->get_num_operands(); i++) { + assert(expr->operands[i]->type->is_scalar()); - switch (expr->operation) { - case ir_unop_logic_not: - inst = emit(AND(reg_null_d, op[0], fs_reg(1))); - inst->conditional_mod = BRW_CONDITIONAL_Z; - break; + expr->operands[i]->accept(this); + op[i] = this->result; - case ir_unop_f2b: - if (brw->gen >= 6) { - emit(CMP(reg_null_d, op[0], fs_reg(0.0f), BRW_CONDITIONAL_NZ)); - } else { - inst = emit(MOV(reg_null_f, op[0])); - inst->conditional_mod = BRW_CONDITIONAL_NZ; - } - break; + resolve_ud_negate(&op[i]); + } - case ir_unop_i2b: - if (brw->gen >= 6) { - emit(CMP(reg_null_d, op[0], fs_reg(0), BRW_CONDITIONAL_NZ)); - } else { - inst = emit(MOV(reg_null_d, op[0])); - inst->conditional_mod = BRW_CONDITIONAL_NZ; - } - break; + switch (expr->operation) { + case ir_unop_logic_not: + inst = emit(AND(reg_null_d, op[0], fs_reg(1))); + inst->conditional_mod = BRW_CONDITIONAL_Z; + break; - case ir_binop_greater: - case ir_binop_gequal: - case ir_binop_less: - case ir_binop_lequal: - case ir_binop_equal: - case ir_binop_all_equal: - case ir_binop_nequal: - case ir_binop_any_nequal: - resolve_bool_comparison(expr->operands[0], &op[0]); - resolve_bool_comparison(expr->operands[1], &op[1]); + case ir_binop_logic_xor: + if (ctx->Const.UniformBooleanTrue == 1) { + fs_reg dst = fs_reg(this, glsl_type::uint_type); + emit(XOR(dst, op[0], op[1])); + inst = emit(AND(reg_null_d, dst, fs_reg(1))); + inst->conditional_mod = BRW_CONDITIONAL_NZ; + } else { + inst = emit(XOR(reg_null_d, op[0], op[1])); + inst->conditional_mod = BRW_CONDITIONAL_NZ; + } + break; - emit(CMP(reg_null_d, op[0], op[1], - brw_conditional_for_comparison(expr->operation))); - break; + case ir_binop_logic_or: + if (ctx->Const.UniformBooleanTrue == 1) { + fs_reg dst = fs_reg(this, glsl_type::uint_type); + emit(OR(dst, op[0], op[1])); + inst = emit(AND(reg_null_d, dst, fs_reg(1))); + inst->conditional_mod = BRW_CONDITIONAL_NZ; + } else { + inst = emit(OR(reg_null_d, op[0], op[1])); + inst->conditional_mod = BRW_CONDITIONAL_NZ; + } + break; - default: - unreachable("not reached"); + case ir_binop_logic_and: + if (ctx->Const.UniformBooleanTrue == 1) { + fs_reg dst = fs_reg(this, glsl_type::uint_type); + emit(AND(dst, op[0], op[1])); + inst = emit(AND(reg_null_d, dst, fs_reg(1))); + inst->conditional_mod = BRW_CONDITIONAL_NZ; + } else { + inst = emit(AND(reg_null_d, op[0], op[1])); + inst->conditional_mod = BRW_CONDITIONAL_NZ; } - return; - } + break; - ir->accept(this); + case ir_unop_f2b: + if (brw->gen >= 6) { + emit(CMP(reg_null_d, op[0], fs_reg(0.0f), BRW_CONDITIONAL_NZ)); + } else { + inst = emit(MOV(reg_null_f, op[0])); + inst->conditional_mod = BRW_CONDITIONAL_NZ; + } + break; - fs_inst *inst = emit(AND(reg_null_d, this->result, fs_reg(1))); - inst->conditional_mod = BRW_CONDITIONAL_NZ; + case ir_unop_i2b: + if (brw->gen >= 6) { + emit(CMP(reg_null_d, op[0], fs_reg(0), BRW_CONDITIONAL_NZ)); + } else { + inst = emit(MOV(reg_null_d, op[0])); + inst->conditional_mod = BRW_CONDITIONAL_NZ; + } + break; + + case ir_binop_greater: + case ir_binop_gequal: + case ir_binop_less: + case ir_binop_lequal: + case ir_binop_equal: + case ir_binop_all_equal: + case ir_binop_nequal: + case ir_binop_any_nequal: + resolve_bool_comparison(expr->operands[0], &op[0]); + resolve_bool_comparison(expr->operands[1], &op[1]); + + emit(CMP(reg_null_d, op[0], op[1], + brw_conditional_for_comparison(expr->operation))); + break; + + default: + unreachable("not reached"); + } } /** |