On 22 August 2013 16:08, Matt Turner <matts...@gmail.com> wrote: > --- > src/mesa/drivers/dri/i965/brw_fs_channel_expressions.cpp | 1 + > src/mesa/drivers/dri/i965/brw_fs_visitor.cpp | 6 ++++++ > src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp | 6 ++++++ > 3 files changed, 13 insertions(+) > > diff --git a/src/mesa/drivers/dri/i965/brw_fs_channel_expressions.cpp > b/src/mesa/drivers/dri/i965/brw_fs_channel_expressions.cpp > index 6ee6d01..34dbc90 100644 > --- a/src/mesa/drivers/dri/i965/brw_fs_channel_expressions.cpp > +++ b/src/mesa/drivers/dri/i965/brw_fs_channel_expressions.cpp > @@ -362,6 +362,7 @@ > ir_channel_expressions_visitor::visit_leave(ir_assignment *ir) > > case ir_triop_fma: > case ir_triop_lrp: > + case ir_triop_cond_sel: > case ir_triop_bitfield_extract: > for (i = 0; i < vector_elements; i++) { > ir_rvalue *op0 = get_element(op_var[0], i); > diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp > b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp > index 4b54bee..27887d6 100644 > --- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp > +++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp > @@ -735,6 +735,12 @@ fs_visitor::visit(ir_expression *ir) > case ir_triop_lrp: > emit_lrp(this->result, op[0], op[1], op[2]); > break; > + > + case ir_triop_cond_sel: > + emit(CMP(reg_null_d, op[0], fs_reg(0), BRW_CONDITIONAL_NZ)); > + inst = emit(BRW_OPCODE_SEL, this->result, op[1], op[2]); > + inst->predicate = BRW_PREDICATE_NORMAL; > + break; > } > } >
For the uses of ir_triop_cond_sel we have currently (the lowering passes in patch 14), I believe this will generate efficient code. But if we adapt the mix() functions to use it, then there are probably going to be a lot of uses like this: x = mix(y, z, a < b); Which will compile down to this silly assembly (please excuse the pseudocode--I can't remember the assembly syntax exactly): CMP.lt tmp a b CMP.nz null tmp 0 SEL.f0 x y z What if we modify the loop that calls ir->operands[operand]->accept(this) on each operand (near the top of the visitor) so that it skips operand 0 when the expression is ir_triop_cond_sel. Then, in the switch statement, we can do something like this: emit_bool_to_cond_code(ir->operands[0]); inst = emit(BRW_OPCODE_SEL, this->result, op[1], op[2]); inst->predicate = BRW_PREDICATE_NORMAL; That should produce the assembly we want, which is: CMP.lt null a b SEL.fo x y z > > > diff --git a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp > b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp > index fbdf73d..0615309 100644 > --- a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp > +++ b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp > @@ -1731,6 +1731,12 @@ vec4_visitor::visit(ir_expression *ir) > emit(LRP(result_dst, op[2], op[1], op[0])); > break; > > + case ir_triop_cond_sel: > + emit(CMP(dst_null_d(), op[0], src_reg(0), BRW_CONDITIONAL_NZ)); > + inst = emit(BRW_OPCODE_SEL, result_dst, op[1], op[2]); > + inst->predicate = BRW_PREDICATE_NORMAL; > + break; > + > A nearly identical optimization ought to be possible here. > case ir_triop_bfi: > op[0] = fix_3src_operand(op[0]); > op[1] = fix_3src_operand(op[1]); > -- > 1.8.3.2 > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/mesa-dev >
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev