Mesa (master): glsl: Bitwise conversion operator support in ir_constant_expression.

Kenneth Graunke kwg at kemper.freedesktop.org
Thu Jun 7 07:17:55 UTC 2012


Module: Mesa
Branch: master
Commit: abe976755318fa9dd88a5c48289623ab7c12ce02
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=abe976755318fa9dd88a5c48289623ab7c12ce02

Author: Olivier Galibert <galibert at pobox.com>
Date:   Tue May  8 20:40:35 2012 +0200

glsl: Bitwise conversion operator support in ir_constant_expression.

A "test_out = floatBitsToUint(-1.0);" fired through the GLSL compiler
gives a correct "(assign (x) (var_ref test_out)
(constant uint (3212836864)))"

Signed-off-by: Olivier Galibert <galibert at pobox.com>
Reviewed-by: Kenneth Graunke <kenneth at whitecape.org>

---

 src/glsl/ir_constant_expression.cpp |   47 +++++++++++++++++++++++++++++++++++
 1 files changed, 47 insertions(+), 0 deletions(-)

diff --git a/src/glsl/ir_constant_expression.cpp b/src/glsl/ir_constant_expression.cpp
index 08a3328..7a4d15f 100644
--- a/src/glsl/ir_constant_expression.cpp
+++ b/src/glsl/ir_constant_expression.cpp
@@ -71,6 +71,29 @@ dot(ir_constant *op0, ir_constant *op1)
    return result;
 }
 
+/* This method is the only one supported by gcc.  Unions in particular
+ * are iffy, and read-through-converted-pointer is killed by strict
+ * aliasing.  OTOH, the compiler sees through the memcpy, so the
+ * resulting asm is reasonable.
+ */
+static float
+bitcast_u2f(unsigned int u)
+{
+   assert(sizeof(float) == sizeof(unsigned int));
+   float f;
+   memcpy(&f, &u, sizeof(f));
+   return f;
+}
+
+static unsigned int
+bitcast_f2u(float f)
+{
+   assert(sizeof(float) == sizeof(unsigned int));
+   unsigned int u;
+   memcpy(&u, &f, sizeof(f));
+   return u;
+}
+
 ir_constant *
 ir_rvalue::constant_expression_value(struct hash_table *variable_context)
 {
@@ -207,6 +230,30 @@ ir_expression::constant_expression_value(struct hash_table *variable_context)
 	 data.u[c] = op[0]->value.i[c];
       }
       break;
+   case ir_unop_bitcast_i2f:
+      assert(op[0]->type->base_type == GLSL_TYPE_INT);
+      for (unsigned c = 0; c < op[0]->type->components(); c++) {
+	 data.f[c] = bitcast_u2f(op[0]->value.i[c]);
+      }
+      break;
+   case ir_unop_bitcast_f2i:
+      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
+      for (unsigned c = 0; c < op[0]->type->components(); c++) {
+	 data.i[c] = bitcast_f2u(op[0]->value.f[c]);
+      }
+      break;
+   case ir_unop_bitcast_u2f:
+      assert(op[0]->type->base_type == GLSL_TYPE_UINT);
+      for (unsigned c = 0; c < op[0]->type->components(); c++) {
+	 data.f[c] = bitcast_u2f(op[0]->value.u[c]);
+      }
+      break;
+   case ir_unop_bitcast_f2u:
+      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
+      for (unsigned c = 0; c < op[0]->type->components(); c++) {
+	 data.u[c] = bitcast_f2u(op[0]->value.f[c]);
+      }
+      break;
    case ir_unop_any:
       assert(op[0]->type->is_boolean());
       data.b[0] = false;




More information about the mesa-commit mailing list