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>
This commit is contained in:
Matt Turner 2014-01-24 15:17:08 -08:00
parent 57109d57f8
commit 8e2b8bd0e6

View file

@ -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();