diff options
Diffstat (limited to 'src/glsl')
-rw-r--r-- | src/glsl/ir.cpp | 63 | ||||
-rw-r--r-- | src/glsl/ir.h | 11 |
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); }; |