<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>