[Mesa-dev] [PATCH 14/15] glsl: Add frexp_to_arith lowering pass.

Paul Berry stereotype441 at gmail.com
Fri Aug 23 09:48:21 PDT 2013


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

> ---
>  src/glsl/ir_optimization.h      |   1 +
>  src/glsl/lower_instructions.cpp | 106
> ++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 107 insertions(+)
>

Depending on how we decide to resolve the "ir_expression writing to one of
its parameters" issue I brought up in patch 5, I believe this patch will
either need to go away or get substantially rewritten.  Patch 15 may also
need a small tweak.

I've sent comments on patches 3, 5, 8, 10, 11, 12, and 13.  Patches 1, 2,
4, 6, 7, 9, and 15 are:

Reviewed-by: Paul Berry <stereotype441 at gmail.com>


>
> diff --git a/src/glsl/ir_optimization.h b/src/glsl/ir_optimization.h
> index 074686c..51c73bb 100644
> --- a/src/glsl/ir_optimization.h
> +++ b/src/glsl/ir_optimization.h
> @@ -39,6 +39,7 @@
>  #define LRP_TO_ARITH       0x80
>  #define BITFIELD_INSERT_TO_BFM_BFI 0x100
>  #define LDEXP_TO_ARITH     0x200
> +#define FREXP_TO_ARITH     0x400
>
>  /**
>   * \see class lower_packing_builtins_visitor
> diff --git a/src/glsl/lower_instructions.cpp
> b/src/glsl/lower_instructions.cpp
> index 8b0a8e1..495c232 100644
> --- a/src/glsl/lower_instructions.cpp
> +++ b/src/glsl/lower_instructions.cpp
> @@ -87,6 +87,10 @@
>   * -------------
>   * Converts ir_binop_ldexp to arithmetic and bit operations.
>   *
> + * FREXP_TO_ARITH:
> + * -------------
> + * Converts ir_binop_frexp to arithmetic and bit operations.
> + *
>   * LRP_TO_ARITH:
>   * -------------
>   * Converts ir_triop_lrp to (op0 * (1.0f - op2)) + (op1 * op2).
> @@ -131,6 +135,7 @@ private:
>     void lrp_to_arith(ir_expression *);
>     void bitfield_insert_to_bfm_bfi(ir_expression *);
>     void ldexp_to_arith(ir_expression *);
> +   void frexp_to_arith(ir_expression *);
>  };
>
>  /**
> @@ -455,6 +460,102 @@
> lower_instructions_visitor::ldexp_to_arith(ir_expression *ir)
>     this->progress = true;
>  }
>
> +void
> +lower_instructions_visitor::frexp_to_arith(ir_expression *ir)
> +{
> +   /* Translates
> +    *    ir_binop_frexp x_input exp
> +    * into:
> +    *
> +    *    x = x_input;
> +    *    exp = 0;
> +    *
> +    *    if (abs(x) != 0.0) {
> +    *       bits = bitcast_f2u(x);
> +    *
> +    *       exp += (bitcast_f2u(abs(x)) >> exp_shift) + exp_bias;
> +    *       bits &= sign_mantissa_mask;
> +    *       bits |= exponent_mask;
> +    *       x = bitcast_u2f(bits);
> +    *    }
> +    *    return x;
> +    *
> +    * which we can't actually implement as such, since the GLSL IR doesn't
> +    * have vectorized if-statements. We actually implement it without
> branches
> +    * using conditional-select:
> +    *
> +    *    x = x_input;
> +    *
> +    *    is_not_zero = abs(x) != 0.0f;
> +    *
> +    *    exp = u2i(bitcast_f2u(abs(x)) >> exp_shift);
> +    *    exp += cond_sel(is_not_zero, exp_bias, 0);
> +    *
> +    *    bits = bitcast_f2u(x);
> +    *    bits &= sign_mantissa_mask;
> +    *    bits |= cond_sel(is_not_zero, exponent_mask, 0u);
> +    *    x = bitcast_u2f(bits);
> +    *    return x;
> +    */
> +
> +   const unsigned vec_elem = ir->type->vector_elements;
> +
> +   /* Types */
> +   const glsl_type *uvec = glsl_type::get_instance(GLSL_TYPE_UINT,
> vec_elem, 1);
> +   const glsl_type *bvec = glsl_type::get_instance(GLSL_TYPE_BOOL,
> vec_elem, 1);
> +   const glsl_type *ivec = glsl_type::get_instance(GLSL_TYPE_INT,
> vec_elem, 1);
> +
> +   /* Constants */
> +   ir_constant *zeroi = ir_constant::zero(ir, ivec);
> +   ir_constant *zerou = ir_constant::zero(ir, uvec);
> +   ir_constant *zerof = ir_constant::zero(ir, ir->type);
> +
> +   ir_constant *exp_bias = new(ir) ir_constant(-126, vec_elem);
> +   ir_constant *exp_shift = new(ir) ir_constant(23u, vec_elem);
> +
> +   ir_constant *sign_mantissa_mask = new(ir) ir_constant(0x807fffffu,
> vec_elem);
> +   ir_constant *exponent_mask = new(ir) ir_constant(0x3f000000u,
> vec_elem);
> +
> +   /* Temporary variables */
> +   ir_variable *x = new(ir) ir_variable(ir->type, "x", ir_var_temporary);
> +
> +   ir_variable *bits = new(ir) ir_variable(uvec, "bits",
> ir_var_temporary);
> +
> +   ir_variable *is_not_zero = new(ir) ir_variable(bvec, "is_not_zero",
> +                                                  ir_var_temporary);
> +
> +   /* Variable passed as <exp> parameter */
> +   ir_variable *exponent = ir->operands[1]->variable_referenced();
> +
> +
> +   ir_instruction &i = *base_ir;
> +
> +   /* Initialize x = x_input; exponent = 0; */
> +   i.insert_before(x);
> +   i.insert_before(assign(x, ir->operands[0]));
> +   i.insert_before(is_not_zero);
> +   i.insert_before(assign(is_not_zero, nequal(abs(x), zerof)));
> +
> +   /* Calculate exponent */
> +   /* Use bitcast to unsigned to get shr, not asr. */
> +   i.insert_before(assign(exponent, add(u2i(rshift(bitcast_f2u(abs(x)),
> +                                                   exp_shift)),
> +                                        cond_sel(is_not_zero, exp_bias,
> +                                                              zeroi))));
> +
> +   /* Calculate mantissa */
> +   i.insert_before(bits);
> +   i.insert_before(assign(bits, bit_and(bitcast_f2u(x),
> sign_mantissa_mask)));
> +   i.insert_before(assign(bits, bit_or(bits, cond_sel(is_not_zero,
> +                                                      exponent_mask,
> zerou))));
> +
> +   ir->operation = ir_unop_bitcast_u2f;
> +   ir->operands[0] = new(ir) ir_dereference_variable(bits);
> +   ir->operands[1] = NULL;
> +
> +   this->progress = true;
> +}
> +
>  ir_visitor_status
>  lower_instructions_visitor::visit_leave(ir_expression *ir)
>  {
> @@ -506,6 +607,11 @@ lower_instructions_visitor::visit_leave(ir_expression
> *ir)
>           ldexp_to_arith(ir);
>        break;
>
> +   case ir_binop_frexp:
> +      if (lowering(FREXP_TO_ARITH))
> +         frexp_to_arith(ir);
> +      break;
> +
>     default:
>        return visit_continue;
>     }
> --
> 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/1cf4b5a6/attachment.html>


More information about the mesa-dev mailing list