<div dir="ltr">On 21 January 2013 00:49, Chad Versace <span dir="ltr"><<a href="mailto:chad.versace@linux.intel.com" target="_blank">chad.versace@linux.intel.com</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">

<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">That is, evaluate constant expressions of the following functions:<br>
  packSnorm2x16  unpackSnorm2x16<br>
  packUnorm2x16  unpackUnorm2x16<br>
  packHalf2x16   unpackHalf2x16<br>
<br>
v2: Reuse _mesa_pack_float_to_half and its inverse to evaluate<br>
    pack/unpackHalf2x16 [for idr].<br>
<br>
Signed-off-by: Chad Versace <<a href="mailto:chad.versace@linux.intel.com" target="_blank">chad.versace@linux.intel.com</a>><br>
---<br>
 src/glsl/ir_constant_expression.cpp | 187 ++++++++++++++++++++++++++++++++++++<br>
 1 file changed, 187 insertions(+)<br>
<br>
diff --git a/src/glsl/ir_constant_expression.cpp b/src/glsl/ir_constant_expression.cpp<br>
index 7678090..b34c6e8 100644<br>
--- a/src/glsl/ir_constant_expression.cpp<br>
+++ b/src/glsl/ir_constant_expression.cpp<br>
@@ -75,6 +75,157 @@ bitcast_f2u(float f)<br>
    return u;<br>
 }<br>
<br>
+/**<br>
+ * Evaluate one component of a floating-point 2x16 unpacking function.<br>
+ */<br>
+typedef uint16_t<br>
+(*pack_1x16_func_t)(float);<br>
+<br>
+/**<br>
+ * Evaluate one component of a floating-point 2x16 unpacking function.<br>
+ */<br>
+typedef float<br>
+(*unpack_1x16_func_t)(uint16_t);<br>
+<br>
+/**<br>
+ * Evaluate a 2x16 floating-point packing function.<br>
+ */<br>
+static uint32_t<br>
+pack_2x16(pack_1x16_func_t pack_1x16,<br>
+          float x, float y)<br>
+{<br>
+   /* From section 8.4 of the GLSL ES 3.00 spec:<br>
+    *<br>
+    *    packSnorm2x16<br>
+    *    -------------<br>
+    *    The first component of the vector will be written to the least<br>
+    *    significant bits of the output; the last component will be written to<br>
+    *    the most significant bits.<br>
+    *<br>
+    * The specifications for the other packing functions contain similar<br>
+    * language.<br>
+    */<br>
+   uint32_t u = 0;<br>
+   u |= ((uint32_t) pack_1x16(x) << 0);<br>
+   u |= ((uint32_t) pack_1x16(y) << 16);<br>
+   return u;<br>
+}<br>
+<br>
+/**<br>
+ * Evaluate a 2x16 floating-point unpacking function.<br>
+ */<br>
+static void<br>
+unpack_2x16(unpack_1x16_func_t unpack_1x16,<br>
+            uint32_t u,<br>
+            float *x, float *y)<br>
+{<br>
+    /* From section 8.4 of the GLSL ES 3.00 spec:<br>
+     *<br>
+     *    unpackSnorm2x16<br>
+     *    ---------------<br>
+     *    The first component of the returned vector will be extracted from<br>
+     *    the least significant bits of the input; the last component will be<br>
+     *    extracted from the most significant bits.<br>
+     *<br>
+     * The specifications for the other unpacking functions contain similar<br>
+     * language.<br>
+     */<br>
+   *x = unpack_1x16((uint16_t) (u & 0xffff));<br>
+   *y = unpack_1x16((uint16_t) (u >> 16));<br>
+}<br>
+<br>
+/**<br>
+ * Evaluate one component of packSnorm2x16.<br>
+ */<br>
+static uint16_t<br>
+pack_snorm_1x16(float x)<br>
+{<br>
+    /* From section 8.4 of the GLSL ES 3.00 spec:<br>
+     *<br>
+     *    packSnorm2x16<br>
+     *    ---------------<br>
+     *    The conversion for component c of v to fixed point is done as<br>
+     *    follows:<br>
+     *<br>
+     *      packSnorm2x16: round(clamp(c, -1, +1) * 32767.0)<br>
+     */<br>
+   return (uint16_t) _mesa_round_to_even(CLAMP(x, -1.0f, +1.0f) * 32767.0f);<br></blockquote><div><br></div><div>Brian Paul has a patch out on the list to change the return type of _mesa_round_to_even() to float, to placate some VStudio compiler warnings ("[Mesa-dev] [PATCH 10/11] glsl: make round_to_even() return float").  When that patch lands, this expression will be typecasting a float to a uint16_t, which is undefined for negative floats.  To be on the safe side, can we do something like this instead?<br>

<br></div><div>/* Note: we need to cast to int before casting to uint16_t, since casting a negative float directly to uint16_t is undefined */<br></div><div>return (uint16_t) (int) _mesa_round_to_even(...);<br><br></div>
<div>With that change, this patch is:<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:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">

+}<br>
+<br>
+/**<br>
+ * Evaluate one component of unpackSnorm2x16.<br>
+ */<br>
+static float<br>
+unpack_snorm_1x16(uint16_t u)<br>
+{<br>
+    /* From section 8.4 of the GLSL ES 3.00 spec:<br>
+     *<br>
+     *    unpackSnorm2x16<br>
+     *    ---------------<br>
+     *    The conversion for unpacked fixed-point value f to floating point is<br>
+     *    done as follows:<br>
+     *<br>
+     *       unpackSnorm2x16: clamp(f / 32767.0, -1,+1)<br>
+     */<br>
+   return CLAMP((int16_t) u / 32767.0f, -1.0f, +1.0f);<br>
+}<br>
+<br>
+/**<br>
+ * Evaluate one component packUnorm2x16.<br>
+ */<br>
+static uint16_t<br>
+pack_unorm_1x16(float x)<br>
+{<br>
+    /* From section 8.4 of the GLSL ES 3.00 spec:<br>
+     *<br>
+     *    packUnorm2x16<br>
+     *    ---------------<br>
+     *    The conversion for component c of v to fixed point is done as<br>
+     *    follows:<br>
+     *<br>
+     *       packUnorm2x16: round(clamp(c, 0, +1) * 65535.0)<br>
+     */<br>
+   return (uint16_t) _mesa_round_to_even(CLAMP(x, 0.0f, 1.0f) * 65535.0f);<br>
+}<br>
+<br>
+<br>
+/**<br>
+ * Evaluate one component of unpackUnorm2x16.<br>
+ */<br>
+static float<br>
+unpack_unorm_1x16(uint16_t u)<br>
+{<br>
+    /* From section 8.4 of the GLSL ES 3.00 spec:<br>
+     *<br>
+     *    unpackUnorm2x16<br>
+     *    ---------------<br>
+     *    The conversion for unpacked fixed-point value f to floating point is<br>
+     *    done as follows:<br>
+     *<br>
+     *       unpackUnorm2x16: f / 65535.0<br>
+     */<br>
+   return (float) u / 65535.0f;<br>
+}<br>
+<br>
+<br>
+/**<br>
+ * Evaluate one component of packHalf2x16.<br>
+ */<br>
+static uint16_t<br>
+pack_half_1x16(float x)<br>
+{<br>
+   return _mesa_float_to_half(x);<br>
+}<br>
+<br>
+/**<br>
+ * Evaluate one component of unpackHalf2x16.<br>
+ */<br>
+static float<br>
+unpack_half_1x16(uint16_t u)<br>
+{<br>
+   return _mesa_half_to_float(u);<br>
+}<br>
+<br>
 ir_constant *<br>
 ir_rvalue::constant_expression_value(struct hash_table *variable_context)<br>
 {<br>
@@ -440,6 +591,42 @@ ir_expression::constant_expression_value(struct hash_table *variable_context)<br>
       }<br>
       break;<br>
<br>
+   case ir_unop_pack_snorm_2x16:<br>
+      assert(op[0]->type == glsl_type::vec2_type);<br>
+      data.u[0] = pack_2x16(pack_snorm_1x16,<br>
+                            op[0]->value.f[0],<br>
+                            op[0]->value.f[1]);<br>
+      break;<br>
+   case ir_unop_unpack_snorm_2x16:<br>
+      assert(op[0]->type == glsl_type::uint_type);<br>
+      unpack_2x16(unpack_snorm_1x16,<br>
+                  op[0]->value.u[0],<br>
+                  &data.f[0], &data.f[1]);<br>
+      break;<br>
+   case ir_unop_pack_unorm_2x16:<br>
+      assert(op[0]->type == glsl_type::vec2_type);<br>
+      data.u[0] = pack_2x16(pack_unorm_1x16,<br>
+                            op[0]->value.f[0],<br>
+                            op[0]->value.f[1]);<br>
+      break;<br>
+   case ir_unop_unpack_unorm_2x16:<br>
+      assert(op[0]->type == glsl_type::uint_type);<br>
+      unpack_2x16(unpack_unorm_1x16,<br>
+                  op[0]->value.u[0],<br>
+                  &data.f[0], &data.f[1]);<br>
+      break;<br>
+   case ir_unop_pack_half_2x16:<br>
+      assert(op[0]->type == glsl_type::vec2_type);<br>
+      data.u[0] = pack_2x16(pack_half_1x16,<br>
+                            op[0]->value.f[0],<br>
+                            op[0]->value.f[1]);<br>
+      break;<br>
+   case ir_unop_unpack_half_2x16:<br>
+      assert(op[0]->type == glsl_type::uint_type);<br>
+      unpack_2x16(unpack_half_1x16,<br>
+                  op[0]->value.u[0],<br>
+                  &data.f[0], &data.f[1]);<br>
+      break;<br>
    case ir_binop_pow:<br>
       assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);<br>
       for (unsigned c = 0; c < op[0]->type->components(); c++) {<br>
<span><font color="#888888">--<br>
1.8.1.1<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>