util: Add a mapping from VkFormat to PIPE_FORMAT.
[mesa.git] / src / panfrost / midgard / midgard_schedule.c
index 8387bc53ace20a3adfe6da5448f7b5bc2428e279..addd65306d6bbb148826a5684c1f6b4d69890f98 100644 (file)
@@ -24,7 +24,6 @@
 #include "compiler.h"
 #include "midgard_ops.h"
 #include "util/u_memory.h"
-#include "util/register_allocate.h"
 
 /* Scheduling for Midgard is complicated, to say the least. ALU instructions
  * must be grouped into VLIW bundles according to following model:
@@ -370,7 +369,7 @@ mir_adjust_constants(midgard_instruction *ins,
         if (!ins->has_constants)
                 return true;
 
-        if (ins->alu.reg_mode == midgard_reg_mode_16) {
+        if (ins->alu.reg_mode != midgard_reg_mode_32) {
                 /* TODO: 16-bit constant combining */
                 if (pred->constant_count)
                         return false;
@@ -1119,7 +1118,8 @@ find_or_allocate_temp(compiler_context *ctx, unsigned hash)
         return temp;
 }
 
-/* Reassigns numbering to get rid of gaps in the indices */
+/* Reassigns numbering to get rid of gaps in the indices and to prioritize
+ * smaller register classes */
 
 static void
 mir_squeeze_index(compiler_context *ctx)
@@ -1129,8 +1129,18 @@ mir_squeeze_index(compiler_context *ctx)
         /* TODO don't leak old hash_to_temp */
         ctx->hash_to_temp = _mesa_hash_table_u64_create(NULL);
 
+        /* We need to prioritize texture registers on older GPUs so we don't
+         * fail RA trying to assign to work registers r0/r1 when a work
+         * register is already there */
+
+        mir_foreach_instr_global(ctx, ins) {
+                if (ins->type == TAG_TEXTURE_4)
+                        ins->dest = find_or_allocate_temp(ctx, ins->dest);
+        }
+
         mir_foreach_instr_global(ctx, ins) {
-                ins->dest = find_or_allocate_temp(ctx, ins->dest);
+                if (ins->type != TAG_TEXTURE_4)
+                        ins->dest = find_or_allocate_temp(ctx, ins->dest);
 
                 for (unsigned i = 0; i < ARRAY_SIZE(ins->src); ++i)
                         ins->src[i] = find_or_allocate_temp(ctx, ins->src[i]);
@@ -1159,16 +1169,14 @@ v_load_store_scratch(
                         /* For register spilling - to thread local storage */
                         .arg_1 = 0xEA,
                         .arg_2 = 0x1E,
-
-                        /* Splattered across, TODO combine logically */
-                        .varying_parameters = (byte & 0x1FF) << 1,
-                        .address = (byte >> 9)
                 },
 
                 /* If we spill an unspill, RA goes into an infinite loop */
                 .no_spill = true
         };
 
+        ins.constants[0] = byte;
+
        if (is_store) {
                 /* r0 = r26, r1 = r27 */
                 assert(srcdest == SSA_FIXED_REGISTER(26) || srcdest == SSA_FIXED_REGISTER(27));
@@ -1196,10 +1204,21 @@ static void mir_spill_register(
          * spill node. All nodes are equal in spill cost, but we can't spill
          * nodes written to from an unspill */
 
-        for (unsigned i = 0; i < ctx->temp_count; ++i) {
-                lcra_set_node_spill_cost(l, i, 1);
+        unsigned *cost = calloc(ctx->temp_count, sizeof(cost[0]));
+
+        mir_foreach_instr_global(ctx, ins) {
+                if (ins->dest < ctx->temp_count)
+                        cost[ins->dest]++;
+
+                mir_foreach_src(ins, s) {
+                        if (ins->src[s] < ctx->temp_count)
+                                cost[ins->src[s]]++;
+                }
         }
 
+        for (unsigned i = 0; i < ctx->temp_count; ++i)
+                lcra_set_node_spill_cost(l, i, cost[i]);
+
         /* We can't spill any bundles that contain unspills. This could be
          * optimized to allow use of r27 to spill twice per bundle, but if
          * you're at the point of optimizing spilling, it's too late.