[Mesa-dev] [PATCH 11/15] glsl: Add conditional-select IR.

Paul Berry stereotype441 at gmail.com
Fri Aug 23 09:06:40 PDT 2013


On 22 August 2013 16:08, Matt Turner <mattst88 at gmail.com> wrote:

> It's a ?: that operates per-component on vectors. Will be used in
> upcoming lowering passes for frexp and ldexp.
>

Should we modify the boolean variants of mix() in src/glsl/builtins/ir/
mix.ir to make use of this new IR operation?


> ---
>  src/glsl/ir.cpp                            | 25 +++++++++++++++++++++++++
>  src/glsl/ir.h                              | 18 ++++++++++++++++++
>  src/glsl/ir_builder.cpp                    | 14 ++++++++++++++
>  src/glsl/ir_builder.h                      |  2 ++
>  src/glsl/ir_constant_expression.cpp        |  8 ++++++++
>  src/glsl/ir_validate.cpp                   |  7 +++++++
>  src/mesa/program/ir_to_mesa.cpp            |  1 +
>  src/mesa/state_tracker/st_glsl_to_tgsi.cpp |  1 +
>  8 files changed, 76 insertions(+)
>
> diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp
> index c8d8802..46bc608 100644
> --- a/src/glsl/ir.cpp
> +++ b/src/glsl/ir.cpp
> @@ -409,6 +409,30 @@ ir_expression::ir_expression(int op, ir_rvalue *op0,
> ir_rvalue *op1)
>     }
>  }
>
> +ir_expression::ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1,
> ir_rvalue *op2)
> +{
> +   this->ir_type = ir_type_expression;
> +
> +   this->operation = ir_expression_operation(op);
> +   this->operands[0] = op0;
> +   this->operands[1] = op1;
> +   this->operands[2] = op2;
> +   this->operands[3] = NULL;
> +
> +   assert(op > ir_last_binop);
> +
> +   switch (this->operation) {
> +   case ir_triop_cond_sel:
> +      this->type = op1->type;
> +      break;
> +
> +   default:
> +      assert(!"not reached: missing automatic type setup for
> ir_expression");
> +      this->type = op0->type;
> +      break;
> +   }
> +}
> +
>  unsigned int
>  ir_expression::get_num_operands(ir_expression_operation op)
>  {
> @@ -519,6 +543,7 @@ static const char *const operator_strs[] = {
>     "vector_extract",
>     "fma",
>     "lrp",
> +   "cond_sel",
>     "bfi",
>     "bitfield_extract",
>     "vector_insert",
> diff --git a/src/glsl/ir.h b/src/glsl/ir.h
> index df6a36d..1c55758 100644
> --- a/src/glsl/ir.h
> +++ b/src/glsl/ir.h
> @@ -1182,6 +1182,19 @@ enum ir_expression_operation {
>     ir_triop_lrp,
>
>     /**
> +    * \name Conditional Select
> +    *
> +    * A vector conditional select instruction (like ?:, but operating per-
> +    * component on vectors).
> +    *
> +    * \see lower_instructions_visitor::ldexp_to_arith
> +    * \see lower_instructions_visitor::frexp_to_arith
> +    */
> +   /*@{*/
> +   ir_triop_cond_sel,
> +   /*@}*/
> +
> +   /**
>      * \name Second half of a lowered bitfieldInsert() operation.
>      *
>      * \see lower_instructions::bitfield_insert_to_bfm_bfi
> @@ -1237,6 +1250,11 @@ public:
>      */
>     ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1);
>
> +   /**
> +    * Constructor for ternary operation expressions
> +    */
> +   ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1, ir_rvalue *op2);
> +
>     virtual ir_expression *as_expression()
>     {
>        return this;
> diff --git a/src/glsl/ir_builder.cpp b/src/glsl/ir_builder.cpp
> index 7d9cf5e..1f05f84 100644
> --- a/src/glsl/ir_builder.cpp
> +++ b/src/glsl/ir_builder.cpp
> @@ -173,6 +173,14 @@ expr(ir_expression_operation op, operand a, operand b)
>     return new(mem_ctx) ir_expression(op, a.val, b.val);
>  }
>
> +ir_expression *
> +expr(ir_expression_operation op, operand a, operand b, operand c)
> +{
> +   void *mem_ctx = ralloc_parent(a.val);
> +
> +   return new(mem_ctx) ir_expression(op, a.val, b.val, c.val);
> +}
> +
>  ir_expression *add(operand a, operand b)
>  {
>     return expr(ir_binop_add, a, b);
> @@ -381,6 +389,12 @@ b2i(operand a)
>     return expr(ir_unop_b2i, a);
>  }
>
> +ir_expression *
> +cond_sel(operand a, operand b, operand c)
> +{
> +   return expr(ir_triop_cond_sel, a, b, c);
> +}
> +
>  ir_if*
>  if_tree(operand condition,
>          ir_instruction *then_branch)
> diff --git a/src/glsl/ir_builder.h b/src/glsl/ir_builder.h
> index 7049476..01f7d18 100644
> --- a/src/glsl/ir_builder.h
> +++ b/src/glsl/ir_builder.h
> @@ -165,6 +165,8 @@ ir_expression *u2i(operand a);
>  ir_expression *b2i(operand a);
>  ir_expression *i2b(operand a);
>
> +ir_expression *cond_sel(operand a, operand b, operand c);
> +
>  /**
>   * Swizzle away later components, but preserve the ordering.
>   */
> diff --git a/src/glsl/ir_constant_expression.cpp
> b/src/glsl/ir_constant_expression.cpp
> index 539e032..8beb7fc 100644
> --- a/src/glsl/ir_constant_expression.cpp
> +++ b/src/glsl/ir_constant_expression.cpp
> @@ -396,6 +396,7 @@ ir_expression::constant_expression_value(struct
> hash_table *variable_context)
>        case ir_binop_rshift:
>        case ir_binop_ldexp:
>        case ir_binop_vector_extract:
> +      case ir_triop_cond_sel:
>        case ir_triop_bitfield_extract:
>           break;
>
> @@ -1398,6 +1399,13 @@ ir_expression::constant_expression_value(struct
> hash_table *variable_context)
>        break;
>     }
>
> +   case ir_triop_cond_sel:
> +      for (unsigned c = 0; c < components; c++) {
> +         data.u[c] = op[0]->value.b[c] ? op[1]->value.u[c]
> +                                       : op[2]->value.u[c];
> +      }
> +      break;
> +
>     case ir_triop_vector_insert: {
>        const unsigned idx = op[2]->value.u[0];
>
> diff --git a/src/glsl/ir_validate.cpp b/src/glsl/ir_validate.cpp
> index 0244519..61b5e2c 100644
> --- a/src/glsl/ir_validate.cpp
> +++ b/src/glsl/ir_validate.cpp
> @@ -538,6 +538,13 @@ ir_validate::visit_leave(ir_expression *ir)
>        assert(ir->operands[2]->type == ir->operands[0]->type ||
> ir->operands[2]->type == glsl_type::float_type);
>        break;
>
> +   case ir_triop_cond_sel:
> +      assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL);
> +      assert(ir->type->vector_elements ==
> ir->operands[0]->type->vector_elements);
> +      assert(ir->type == ir->operands[1]->type);
> +      assert(ir->type == ir->operands[2]->type);
> +      break;
> +
>     case ir_triop_bfi:
>        assert(ir->operands[0]->type->is_integer());
>        assert(ir->operands[1]->type == ir->operands[2]->type);
> diff --git a/src/mesa/program/ir_to_mesa.cpp
> b/src/mesa/program/ir_to_mesa.cpp
> index 4675a1e..f50e2c9 100644
> --- a/src/mesa/program/ir_to_mesa.cpp
> +++ b/src/mesa/program/ir_to_mesa.cpp
> @@ -1499,6 +1499,7 @@ ir_to_mesa_visitor::visit(ir_expression *ir)
>     case ir_quadop_bitfield_insert:
>     case ir_binop_frexp:
>     case ir_binop_ldexp:
> +   case ir_triop_cond_sel:
>        assert(!"not supported");
>        break;
>
> diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> index 4dd2cc5..88d4ab8 100644
> --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> @@ -1981,6 +1981,7 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
>     case ir_triop_vector_insert:
>     case ir_binop_frexp:
>     case ir_binop_ldexp:
> +   case ir_triop_cond_sel:
>        /* This operation is not supported, or should have already been
> handled.
>         */
>        assert(!"Invalid ir opcode in glsl_to_tgsi_visitor::visit()");
> --
> 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/09549775/attachment-0001.html>


More information about the mesa-dev mailing list