lima/gpir/sched: Handle more special ops in can_use_complex()
authorConnor Abbott <cwabbott0@gmail.com>
Sat, 27 Jul 2019 18:24:32 +0000 (20:24 +0200)
committerConnor Abbott <cwabbott0@gmail.com>
Sun, 28 Jul 2019 21:38:31 +0000 (23:38 +0200)
We were missing handling for a few other ops that rearrange their
sources somehow in codegen, namely complex2 and select.

This should fix spec@glsl-1.10@execution@built-in-functions@vs-asin-vec3
and possibly other random regressions from the new scheduler which were
supposed to be fixed in the commit right after.

Fixes: 54434fe6706 ("lima/gpir: Rework the scheduler")
Signed-off-by: Connor Abbott <cwabbott0@gmail.com>
Acked-by: Qiang Yu <yuq825@gmail.com>
src/gallium/drivers/lima/ir/gp/scheduler.c

index 69606f22d517c4ae4c0e0e98b56f13484ca1d66f..35925a1af51c8fa65c8ba7fa4f1f2deab8bf81f1 100644 (file)
@@ -1114,13 +1114,32 @@ static bool can_use_complex(gpir_node *node)
       if (succ->type != gpir_node_type_alu)
          continue;
 
+      /* Note: this must be consistent with gpir_codegen_{mul,add}_slot{0,1}
+       */
       gpir_alu_node *alu = gpir_node_to_alu(succ);
-      if (alu->num_child >= 2 && alu->children[1] == node)
-         return false;
-
-      /* complex1 puts its third source in the fourth slot */
-      if (alu->node.op == gpir_op_complex1 && alu->children[2] == node)
+      switch (alu->node.op) {
+      case gpir_op_complex1:
+         /* complex1 puts its third source in the fourth slot */
+         if (alu->children[1] == node || alu->children[2] == node)
+            return false;
+         break;
+      case gpir_op_complex2:
+         /* complex2 has its source duplicated, since it actually takes two
+          * sources but we only ever use it with both sources the same. Hence
+          * its source can never be the complex slot.
+          */
          return false;
+      case gpir_op_select:
+         /* Select has its sources rearranged */
+         if (alu->children[0] == node)
+            return false;
+         break;
+      default:
+         assert(alu->num_child <= 2);
+         if (alu->num_child == 2 && alu->children[1] == node)
+            return false;
+         break;
+      }
    }
 
    return true;