summaryrefslogtreecommitdiffstats
path: root/src/glsl/opt_vectorize.cpp
diff options
context:
space:
mode:
authorMatt Turner <mattst88@gmail.com>2014-01-24 15:17:08 -0800
committerMatt Turner <mattst88@gmail.com>2014-01-27 21:15:35 -0800
commit8e2b8bd0e613d1e24860d9572fc16893ad11a2da (patch)
tree7cd23a5d48b696c1d5ac1c23e5f8bfd2f75b91d9 /src/glsl/opt_vectorize.cpp
parent57109d57f8c7425f4c6f865f1697a864da27aabd (diff)
downloadexternal_mesa3d-8e2b8bd0e613d1e24860d9572fc16893ad11a2da.zip
external_mesa3d-8e2b8bd0e613d1e24860d9572fc16893ad11a2da.tar.gz
external_mesa3d-8e2b8bd0e613d1e24860d9572fc16893ad11a2da.tar.bz2
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>
Diffstat (limited to 'src/glsl/opt_vectorize.cpp')
-rw-r--r--src/glsl/opt_vectorize.cpp17
1 files changed, 13 insertions, 4 deletions
diff --git a/src/glsl/opt_vectorize.cpp b/src/glsl/opt_vectorize.cpp
index 9ca811a..ac43a29 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();