freedreno/ir3: fix gpu hang with pre-fs-tex-fetch
[mesa.git] / src / freedreno / ir3 / ir3_sched.c
index a70251374ee2f92c9c2a618f3512c864d2cfa50a..247221d3a03b303aa599009d4789a89670b2c0f7 100644 (file)
@@ -778,18 +778,28 @@ sched_block(struct ir3_sched_ctx *ctx, struct ir3_block *block)
        list_inithead(&block->instr_list);
        list_inithead(&ctx->depth_list);
 
-       /* first a pre-pass to schedule all meta:input instructions
-        * (which need to appear first so that RA knows the register is
-        * occupied), and move remaining to depth sorted list:
+       /* First schedule all meta:input instructions, followed by
+        * tex-prefetch.  We want all of the instructions that load
+        * values into registers before the shader starts to go
+        * before any other instructions.  But in particular we
+        * want inputs to come before prefetches.  This is because
+        * a FS's bary_ij input may not actually be live in the
+        * shader, but it should not be scheduled on top of any
+        * other input (but can be overwritten by a tex prefetch)
+        *
+        * Finally, move all the remaining instructions to the depth-
+        * list
         */
-       list_for_each_entry_safe (struct ir3_instruction, instr, &unscheduled_list, node) {
-               if ((instr->opc == OPC_META_INPUT) ||
-                               (instr->opc == OPC_META_TEX_PREFETCH)) {
+       list_for_each_entry_safe (struct ir3_instruction, instr, &unscheduled_list, node)
+               if (instr->opc == OPC_META_INPUT)
                        schedule(ctx, instr);
-               } else {
-                       ir3_insert_by_depth(instr, &ctx->depth_list);
-               }
-       }
+
+       list_for_each_entry_safe (struct ir3_instruction, instr, &unscheduled_list, node)
+               if (instr->opc == OPC_META_TEX_PREFETCH)
+                       schedule(ctx, instr);
+
+       list_for_each_entry_safe (struct ir3_instruction, instr, &unscheduled_list, node)
+               ir3_insert_by_depth(instr, &ctx->depth_list);
 
        while (!list_is_empty(&ctx->depth_list)) {
                struct ir3_sched_notes notes = {0};