summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Romanick <ian.d.romanick@intel.com>2017-10-31 23:16:38 -0700
committerIan Romanick <ian.d.romanick@intel.com>2017-11-08 18:37:29 -0800
commitc858abb14f8e96fca880d1ae85874f9c084397b7 (patch)
tree1be853161f163bd91b917557439dd5ec0e32d946
parentae1fd09c1d5cad98c9c5e92fbc32ec5af79d210c (diff)
glsl: Make the swizzle-swizzle optimization greedy
If there is a long sequence of swizzled swizzles, compact all of them down to a single swizzle. Signed-off-by: Ian Romanick <ian.d.romanick@intel.com> Reviewed-by: <thomashelland90@gmail.com>
-rw-r--r--src/compiler/glsl/opt_swizzle_swizzle.cpp59
1 files changed, 29 insertions, 30 deletions
diff --git a/src/compiler/glsl/opt_swizzle_swizzle.cpp b/src/compiler/glsl/opt_swizzle_swizzle.cpp
index 7285474b089..40ce268b1a5 100644
--- a/src/compiler/glsl/opt_swizzle_swizzle.cpp
+++ b/src/compiler/glsl/opt_swizzle_swizzle.cpp
@@ -23,8 +23,7 @@
/**
* \file opt_swizzle_swizzle.cpp
- *
- * Eliminates the second swizzle in a swizzle chain.
+ * Compact a sequence of swizzled swizzles into a single swizzle.
*/
#include "ir.h"
@@ -51,34 +50,34 @@ public:
ir_visitor_status
ir_swizzle_swizzle_visitor::visit_enter(ir_swizzle *ir)
{
- int mask2[4];
-
- ir_swizzle *swiz2 = ir->val->as_swizzle();
- if (!swiz2)
- return visit_continue;
-
- memset(&mask2, 0, sizeof(mask2));
- if (swiz2->mask.num_components >= 1)
- mask2[0] = swiz2->mask.x;
- if (swiz2->mask.num_components >= 2)
- mask2[1] = swiz2->mask.y;
- if (swiz2->mask.num_components >= 3)
- mask2[2] = swiz2->mask.z;
- if (swiz2->mask.num_components >= 4)
- mask2[3] = swiz2->mask.w;
-
- if (ir->mask.num_components >= 1)
- ir->mask.x = mask2[ir->mask.x];
- if (ir->mask.num_components >= 2)
- ir->mask.y = mask2[ir->mask.y];
- if (ir->mask.num_components >= 3)
- ir->mask.z = mask2[ir->mask.z];
- if (ir->mask.num_components >= 4)
- ir->mask.w = mask2[ir->mask.w];
-
- ir->val = swiz2->val;
-
- this->progress = true;
+ ir_swizzle *swiz2;
+
+ while ((swiz2 = ir->val->as_swizzle()) != NULL) {
+ int mask2[4];
+
+ memset(&mask2, 0, sizeof(mask2));
+ if (swiz2->mask.num_components >= 1)
+ mask2[0] = swiz2->mask.x;
+ if (swiz2->mask.num_components >= 2)
+ mask2[1] = swiz2->mask.y;
+ if (swiz2->mask.num_components >= 3)
+ mask2[2] = swiz2->mask.z;
+ if (swiz2->mask.num_components >= 4)
+ mask2[3] = swiz2->mask.w;
+
+ if (ir->mask.num_components >= 1)
+ ir->mask.x = mask2[ir->mask.x];
+ if (ir->mask.num_components >= 2)
+ ir->mask.y = mask2[ir->mask.y];
+ if (ir->mask.num_components >= 3)
+ ir->mask.z = mask2[ir->mask.z];
+ if (ir->mask.num_components >= 4)
+ ir->mask.w = mask2[ir->mask.w];
+
+ ir->val = swiz2->val;
+
+ this->progress = true;
+ }
return visit_continue;
}