Add methods to ir_constant to get scalar components in a particular type
authorIan Romanick <ian.d.romanick@intel.com>
Fri, 4 Jun 2010 23:30:07 +0000 (16:30 -0700)
committerIan Romanick <ian.d.romanick@intel.com>
Fri, 11 Jun 2010 20:51:09 +0000 (13:51 -0700)
ir.cpp
ir.h

diff --git a/ir.cpp b/ir.cpp
index f7e03cb58dd2e71f84f6aea7363326c1d8f39946..7e5873b646c8867cf1fcfeac4d33c3f198e2a612 100644 (file)
--- a/ir.cpp
+++ b/ir.cpp
@@ -240,6 +240,74 @@ ir_constant::ir_constant(const ir_constant *c, unsigned i)
    }
 }
 
+bool
+ir_constant::get_bool_component(unsigned i) const
+{
+   switch (this->type->base_type) {
+   case GLSL_TYPE_UINT:  return this->value.u[i] != 0;
+   case GLSL_TYPE_INT:   return this->value.i[i] != 0;
+   case GLSL_TYPE_FLOAT: return ((int)this->value.f[i]) != 0;
+   case GLSL_TYPE_BOOL:  return this->value.b[i];
+   default:              assert(!"Should not get here."); break;
+   }
+
+   /* Must return something to make the compiler happy.  This is clearly an
+    * error case.
+    */
+   return false;
+}
+
+float
+ir_constant::get_float_component(unsigned i) const
+{
+   switch (this->type->base_type) {
+   case GLSL_TYPE_UINT:  return (float) this->value.u[i];
+   case GLSL_TYPE_INT:   return (float) this->value.i[i];
+   case GLSL_TYPE_FLOAT: return this->value.f[i];
+   case GLSL_TYPE_BOOL:  return this->value.b[i] ? 1.0 : 0.0;
+   default:              assert(!"Should not get here."); break;
+   }
+
+   /* Must return something to make the compiler happy.  This is clearly an
+    * error case.
+    */
+   return 0.0;
+}
+
+int
+ir_constant::get_int_component(unsigned i) const
+{
+   switch (this->type->base_type) {
+   case GLSL_TYPE_UINT:  return this->value.u[i];
+   case GLSL_TYPE_INT:   return this->value.i[i];
+   case GLSL_TYPE_FLOAT: return (int) this->value.f[i];
+   case GLSL_TYPE_BOOL:  return this->value.b[i] ? 1 : 0;
+   default:              assert(!"Should not get here."); break;
+   }
+
+   /* Must return something to make the compiler happy.  This is clearly an
+    * error case.
+    */
+   return 0;
+}
+
+unsigned
+ir_constant::get_uint_component(unsigned i) const
+{
+   switch (this->type->base_type) {
+   case GLSL_TYPE_UINT:  return this->value.u[i];
+   case GLSL_TYPE_INT:   return this->value.i[i];
+   case GLSL_TYPE_FLOAT: return (unsigned) this->value.f[i];
+   case GLSL_TYPE_BOOL:  return this->value.b[i] ? 1 : 0;
+   default:              assert(!"Should not get here."); break;
+   }
+
+   /* Must return something to make the compiler happy.  This is clearly an
+    * error case.
+    */
+   return 0;
+}
+
 
 ir_dereference_variable::ir_dereference_variable(ir_variable *var)
 {
diff --git a/ir.h b/ir.h
index 102f2f37270d66bdff5dea9e58ac0335316077b2..033d6f2261e9a470a45b077ccd2ae48d1b6130ce 100644 (file)
--- a/ir.h
+++ b/ir.h
@@ -1055,6 +1055,20 @@ public:
       return new ir_constant(this->type, &this->value);
    }
 
+   /**
+    * Get a particular component of a constant as a specific type
+    *
+    * This is useful, for example, to get a value from an integer constant
+    * as a float or bool.  This appears frequently when constructors are
+    * called with all constant parameters.
+    */
+   /*@{*/
+   bool get_bool_component(unsigned i) const;
+   float get_float_component(unsigned i) const;
+   int get_int_component(unsigned i) const;
+   unsigned get_uint_component(unsigned i) const;
+   /*@}*/
+
    /**
     * Value of the constant.
     *