ir_swizzle: Add new constructor, refactor constructors
authorIan Romanick <ian.d.romanick@intel.com>
Fri, 25 Jun 2010 22:25:27 +0000 (15:25 -0700)
committerIan Romanick <ian.d.romanick@intel.com>
Tue, 29 Jun 2010 18:15:26 +0000 (11:15 -0700)
Adds a new constructor that takes an array of component values.  Refactors
the meat of the two constructors to an init_mask method.

src/glsl/ir.cpp
src/glsl/ir.h

index 2756752ba493c3ce8ec196faf41c846ad48247ff..4eb0e9e33ebb8d2b096b73aa88894f2ab95c77a9 100644 (file)
@@ -573,28 +573,40 @@ ir_texture::set_sampler(ir_dereference *sampler)
 }
 
 
-ir_swizzle::ir_swizzle(ir_rvalue *val, unsigned x, unsigned y, unsigned z,
-                      unsigned w, unsigned count)
-   : val(val)
+void
+ir_swizzle::init_mask(const unsigned *comp, unsigned count)
 {
    assert((count >= 1) && (count <= 4));
 
-   const unsigned dup_mask = 0
-      | ((count > 1) ? ((1U << y) & ((1U << x)                        )) : 0)
-      | ((count > 2) ? ((1U << z) & ((1U << x) | (1U << y)            )) : 0)
-      | ((count > 3) ? ((1U << w) & ((1U << x) | (1U << y) | (1U << z))) : 0);
-
-   assert(x <= 3);
-   assert(y <= 3);
-   assert(z <= 3);
-   assert(w <= 3);
+   memset(&this->mask, 0, sizeof(this->mask));
+   this->mask.num_components = count;
+
+   unsigned dup_mask = 0;
+   switch (count) {
+   case 4:
+      assert(comp[3] <= 3);
+      dup_mask |= (1U << comp[3])
+        & ((1U << comp[0]) | (1U << comp[1]) | (1U << comp[2]));
+      this->mask.w = comp[3];
+
+   case 3:
+      assert(comp[2] <= 3);
+      dup_mask |= (1U << comp[2])
+        & ((1U << comp[0]) | (1U << comp[1]));
+      this->mask.z = comp[2];
+
+   case 2:
+      assert(comp[1] <= 3);
+      dup_mask |= (1U << comp[1])
+        & ((1U << comp[0]));
+      this->mask.y = comp[1];
+
+   case 1:
+      assert(comp[0] <= 3);
+      this->mask.x = comp[0];
+   }
 
-   mask.x = x;
-   mask.y = y;
-   mask.z = z;
-   mask.w = w;
-   mask.num_components = count;
-   mask.has_duplicates = dup_mask != 0;
+   this->mask.has_duplicates = dup_mask != 0;
 
    /* Based on the number of elements in the swizzle and the base type
     * (i.e., float, int, unsigned, or bool) of the vector being swizzled,
@@ -603,6 +615,21 @@ ir_swizzle::ir_swizzle(ir_rvalue *val, unsigned x, unsigned y, unsigned z,
    type = glsl_type::get_instance(val->type->base_type, mask.num_components, 1);
 }
 
+ir_swizzle::ir_swizzle(ir_rvalue *val, unsigned x, unsigned y, unsigned z,
+                      unsigned w, unsigned count)
+   : val(val)
+{
+   const unsigned components[4] = { x, y, z, w };
+   this->init_mask(components, count);
+}
+
+ir_swizzle::ir_swizzle(ir_rvalue *val, const unsigned *comp,
+                      unsigned count)
+   : val(val)
+{
+   this->init_mask(comp, count);
+}
+
 ir_swizzle::ir_swizzle(ir_rvalue *val, ir_swizzle_mask mask)
 {
    this->val = val;
index 3d2c7ff5cf56be6ab0a52155ed840e65420c8551..de1124975d22aba6b582f86201e76bf5995a8a6e 100644 (file)
@@ -918,6 +918,9 @@ class ir_swizzle : public ir_rvalue {
 public:
    ir_swizzle(ir_rvalue *, unsigned x, unsigned y, unsigned z, unsigned w,
               unsigned count);
+
+   ir_swizzle(ir_rvalue *val, const unsigned *components, unsigned count);
+
    ir_swizzle(ir_rvalue *val, ir_swizzle_mask mask);
 
    virtual ir_instruction *clone(struct hash_table *) const;
@@ -951,6 +954,14 @@ public:
 
    ir_rvalue *val;
    ir_swizzle_mask mask;
+
+private:
+   /**
+    * Initialize the mask component of a swizzle
+    *
+    * This is used by the \c ir_swizzle constructors.
+    */
+   void init_mask(const unsigned *components, unsigned count);
 };