glsl: Make the swizzle-swizzle optimization greedy
authorIan Romanick <ian.d.romanick@intel.com>
Wed, 1 Nov 2017 06:16:38 +0000 (23:16 -0700)
committerIan Romanick <ian.d.romanick@intel.com>
Thu, 9 Nov 2017 02:37:29 +0000 (18:37 -0800)
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>
src/compiler/glsl/opt_swizzle_swizzle.cpp

index 7285474b089524173255efd44cf086833a82923f..40ce268b1a562cd80a0c2af02a84cd27e6796f0e 100644 (file)
@@ -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;
 }