pan/midgard: Add mir_upper_override helper
[mesa.git] / src / panfrost / midgard / compiler.h
index eb0464e6a49f45f9ba2d64970ca9de8b8b4f885c..92712dde92b69c429f86933c1ea2afb4e400e089 100644 (file)
@@ -78,7 +78,7 @@ typedef struct midgard_branch {
  * emitted before the register allocation pass.
  */
 
-#define MIR_SRC_COUNT 3
+#define MIR_SRC_COUNT 4
 #define MIR_VEC_COMPONENTS 16
 
 typedef struct midgard_instruction {
@@ -89,7 +89,7 @@ typedef struct midgard_instruction {
 
         /* Instruction arguments represented as block-local SSA
          * indices, rather than registers. ~0 means unused. */
-        unsigned src[3];
+        unsigned src[MIR_SRC_COUNT];
         unsigned dest;
 
         /* vec16 swizzle, unpacked, per source */
@@ -121,15 +121,16 @@ typedef struct midgard_instruction {
         uint16_t mask;
 
         /* For ALU ops only: set to true to invert (bitwise NOT) the
-         * destination of an integer-out op. Not imeplemented in hardware but
+         * destination of an integer-out op. Not implemented in hardware but
          * allows more optimizations */
 
         bool invert;
 
         /* Hint for the register allocator not to spill the destination written
-         * from this instruction (because it is a spill/unspill node itself) */
+         * from this instruction (because it is a spill/unspill node itself).
+         * Bitmask of spilled classes */
 
-        bool no_spill;
+        unsigned no_spill;
 
         /* Generic hint for intra-pass use */
         bool hint;
@@ -197,6 +198,9 @@ typedef struct midgard_block {
          * simple bit fields, but for us, liveness is a vector idea. */
         uint16_t *live_in;
         uint16_t *live_out;
+
+        /* Indicates this is a fixed-function fragment epilogue block */
+        bool epilogue;
 } midgard_block;
 
 typedef struct midgard_bundle {
@@ -223,6 +227,9 @@ typedef struct compiler_context {
         /* Is internally a blend shader? Depends on stage == FRAGMENT */
         bool is_blend;
 
+        /* Render target number for a keyed blend shader. Depends on is_blend */
+        unsigned blend_rt;
+
         /* Tracking for blend constant patching */
         int blend_constant_offset;
 
@@ -527,6 +534,7 @@ uint16_t mir_to_bytemask(midgard_reg_mode mode, unsigned mask);
 uint16_t mir_bytemask(midgard_instruction *ins);
 uint16_t mir_round_bytemask_down(uint16_t mask, midgard_reg_mode mode);
 void mir_set_bytemask(midgard_instruction *ins, uint16_t bytemask);
+unsigned mir_upper_override(midgard_instruction *ins);
 
 /* MIR printing */
 
@@ -551,7 +559,7 @@ v_mov(unsigned src, unsigned dest)
         midgard_instruction ins = {
                 .type = TAG_ALU_4,
                 .mask = 0xF,
-                .src = { SSA_UNUSED, src, SSA_UNUSED },
+                .src = { ~0, src, ~0, ~0 },
                 .swizzle = SWIZZLE_IDENTITY,
                 .dest = dest,
                 .alu = {
@@ -565,6 +573,14 @@ v_mov(unsigned src, unsigned dest)
         return ins;
 }
 
+/* Broad types of register classes so we can handle special
+ * registers */
+
+#define REG_CLASS_WORK          0
+#define REG_CLASS_LDST          1
+#define REG_CLASS_TEXR          3
+#define REG_CLASS_TEXW          4
+
 /* Like a move, but to thread local storage! */
 
 static inline midgard_instruction
@@ -581,7 +597,7 @@ v_load_store_scratch(
                 .type = TAG_LOAD_STORE_4,
                 .mask = mask,
                 .dest = ~0,
-                .src = { ~0, ~0, ~0 },
+                .src = { ~0, ~0, ~0, ~0 },
                 .swizzle = SWIZZLE_IDENTITY_4,
                 .load_store = {
                         .op = is_store ? midgard_op_st_int4 : midgard_op_ld_int4,
@@ -592,18 +608,23 @@ v_load_store_scratch(
                 },
 
                 /* If we spill an unspill, RA goes into an infinite loop */
-                .no_spill = true
+                .no_spill = (1 << REG_CLASS_WORK)
         };
 
         ins.constants[0] = byte;
 
         if (is_store) {
-                /* r0 = r26, r1 = r27 */
-                assert(srcdest == SSA_FIXED_REGISTER(26) || srcdest == SSA_FIXED_REGISTER(27));
                 ins.src[0] = srcdest;
-        } else {
+
+                /* Ensure we are tightly swizzled so liveness analysis is
+                 * correct */
+
+                for (unsigned i = 0; i < 4; ++i) {
+                        if (!(mask & (1 << i)))
+                                ins.swizzle[0][i] = COMPONENT_X;
+                }
+        } else
                 ins.dest = srcdest;
-        }
 
         return ins;
 }
@@ -626,14 +647,6 @@ mir_has_arg(midgard_instruction *ins, unsigned arg)
 
 void schedule_program(compiler_context *ctx);
 
-/* Broad types of register classes so we can handle special
- * registers */
-
-#define REG_CLASS_WORK          0
-#define REG_CLASS_LDST          1
-#define REG_CLASS_TEXR          3
-#define REG_CLASS_TEXW          4
-
 void mir_ra(compiler_context *ctx);
 void mir_squeeze_index(compiler_context *ctx);
 void mir_lower_special_reads(compiler_context *ctx);
@@ -643,9 +656,7 @@ void mir_invalidate_liveness(compiler_context *ctx);
 bool mir_is_live_after(compiler_context *ctx, midgard_block *block, midgard_instruction *start, int src);
 
 void mir_create_pipeline_registers(compiler_context *ctx);
-
-void
-midgard_promote_uniforms(compiler_context *ctx, unsigned promoted_count);
+void midgard_promote_uniforms(compiler_context *ctx);
 
 midgard_instruction *
 emit_ubo_read(
@@ -694,5 +705,6 @@ bool midgard_opt_fuse_src_invert(compiler_context *ctx, midgard_block *block);
 bool midgard_opt_fuse_dest_invert(compiler_context *ctx, midgard_block *block);
 bool midgard_opt_csel_invert(compiler_context *ctx, midgard_block *block);
 bool midgard_opt_promote_fmov(compiler_context *ctx, midgard_block *block);
+bool midgard_opt_drop_cmp_invert(compiler_context *ctx, midgard_block *block);
 
 #endif