diff options
author | Matt Turner <mattst88@gmail.com> | 2014-01-24 15:17:08 -0800 |
---|---|---|
committer | Matt Turner <mattst88@gmail.com> | 2014-01-27 21:15:35 -0800 |
commit | 8e2b8bd0e613d1e24860d9572fc16893ad11a2da (patch) | |
tree | 7cd23a5d48b696c1d5ac1c23e5f8bfd2f75b91d9 | |
parent | 57109d57f8c7425f4c6f865f1697a864da27aabd (diff) |
glsl: Set proper swizzle when a channel is missing in vectorizing.
Previously, for example if the x channel was missing from a series of
assignments we were attempting to vectorize, the wrong swizzle mask
would be applied.
a.y = b.y;
a.z = b.z;
a.w = b.w;
would be incorrectly transformed into
a.yzw = b.xyz;
Fixes two transform feedback tests in the ES3 conformance suite.
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=73978
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=73954
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
-rw-r--r-- | src/glsl/opt_vectorize.cpp | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/src/glsl/opt_vectorize.cpp b/src/glsl/opt_vectorize.cpp index 9ca811a8603..ac43a29ce8f 100644 --- a/src/glsl/opt_vectorize.cpp +++ b/src/glsl/opt_vectorize.cpp @@ -170,22 +170,31 @@ void ir_vectorize_visitor::try_vectorize() { if (this->last_assignment && this->channels > 1) { - ir_swizzle_mask mask = {0, 1, 2, 3, channels, 0}; - - visit_tree(this->last_assignment->rhs, rewrite_swizzle, &mask); + ir_swizzle_mask mask = {0, 0, 0, 0, channels, 0}; this->last_assignment->write_mask = 0; - for (unsigned i = 0; i < 4; i++) { + for (unsigned i = 0, j = 0; i < 4; i++) { if (this->assignment[i]) { this->last_assignment->write_mask |= 1 << i; if (this->assignment[i] != this->last_assignment) { this->assignment[i]->remove(); } + + switch (j) { + case 0: mask.x = i; break; + case 1: mask.y = i; break; + case 2: mask.z = i; break; + case 3: mask.w = i; break; + } + + j++; } } + visit_tree(this->last_assignment->rhs, rewrite_swizzle, &mask); + this->progress = true; } clear(); |