<div dir="ltr">On 22 August 2013 16:08, Matt Turner <span dir="ltr"><<a href="mailto:mattst88@gmail.com" target="_blank">mattst88@gmail.com</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

---<br>
 src/glsl/ir_optimization.h      |   1 +<br>
 src/glsl/lower_instructions.cpp | 106 ++++++++++++++++++++++++++++++++++++++++<br>
 2 files changed, 107 insertions(+)<br></blockquote><div><br></div><div>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.<br>
<br>I've sent comments on patches 3, 5, 8, 10, 11, 12, and 13.  Patches 1, 2, 4, 6, 7, 9, and 15 are:<br><br>Reviewed-by: Paul Berry <<a href="mailto:stereotype441@gmail.com">stereotype441@gmail.com</a>><br></div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

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