summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/glsl/ir.cpp63
-rw-r--r--src/glsl/ir.h11
2 files changed, 56 insertions, 18 deletions
diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp
index 2756752ba49..4eb0e9e33eb 100644
--- a/src/glsl/ir.cpp
+++ b/src/glsl/ir.cpp
@@ -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;
diff --git a/src/glsl/ir.h b/src/glsl/ir.h
index 3d2c7ff5cf5..de1124975d2 100644
--- a/src/glsl/ir.h
+++ b/src/glsl/ir.h
@@ -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);
};