[Mesa-dev] [PATCH 12/15] i965: Add support for ir_triop_cond_sel.
Paul Berry
stereotype441 at gmail.com
Fri Aug 23 09:24:19 PDT 2013
On 22 August 2013 16:08, Matt Turner <mattst88 at 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 at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20130823/5a1aebc4/attachment.html>
More information about the mesa-dev
mailing list