freedreno/ir3: Pre-color GS header and primitive ID
[mesa.git] / src / freedreno / ir3 / ir3.h
index 161e78e0febb8bd7d66b4607664547392b7be7e8..34447c2cc2b0f4bb55cec700e4e82945731e8f21 100644 (file)
@@ -31,6 +31,7 @@
 
 #include "util/bitscan.h"
 #include "util/list.h"
+#include "util/set.h"
 #include "util/u_debug.h"
 
 #include "instr-a3xx.h"
@@ -498,8 +499,7 @@ struct ir3_block {
        struct ir3_instruction *condition;
        struct ir3_block *successors[2];
 
-       unsigned predecessors_count;
-       struct ir3_block **predecessors;
+       struct set *predecessors;     /* set of ir3_block */
 
        uint16_t start_ip, end_ip;
 
@@ -614,6 +614,18 @@ static inline bool is_nop(struct ir3_instruction *instr)
        return instr->opc == OPC_NOP;
 }
 
+static inline bool is_same_type_reg(struct ir3_register *reg1,
+               struct ir3_register *reg2)
+{
+       unsigned type_reg1 = (reg1->flags & (IR3_REG_HIGH | IR3_REG_HALF));
+       unsigned type_reg2 = (reg2->flags & (IR3_REG_HIGH | IR3_REG_HALF));
+
+       if (type_reg1 ^ type_reg2)
+               return false;
+       else
+               return true;
+}
+
 /* Is it a non-transformative (ie. not type changing) mov?  This can
  * also include absneg.s/absneg.f, which for the most part can be
  * treated as a mov (single src argument).
@@ -631,6 +643,10 @@ static inline bool is_same_type_mov(struct ir3_instruction *instr)
        case OPC_ABSNEG_S:
                if (instr->flags & IR3_INSTR_SAT)
                        return false;
+               /* If the type of dest reg and src reg are different,
+                * it shouldn't be considered as same type mov */
+               if (!is_same_type_reg(instr->regs[0], instr->regs[1]))
+                       return false;
                break;
        default:
                return false;
@@ -861,6 +877,41 @@ static inline bool ir3_cat2_int(opc_t opc)
        }
 }
 
+static inline bool ir3_cat2_float(opc_t opc)
+{
+       switch (opc) {
+       case OPC_ADD_F:
+       case OPC_MIN_F:
+       case OPC_MAX_F:
+       case OPC_MUL_F:
+       case OPC_SIGN_F:
+       case OPC_CMPS_F:
+       case OPC_ABSNEG_F:
+       case OPC_CMPV_F:
+       case OPC_FLOOR_F:
+       case OPC_CEIL_F:
+       case OPC_RNDNE_F:
+       case OPC_RNDAZ_F:
+       case OPC_TRUNC_F:
+               return true;
+
+       default:
+               return false;
+       }
+}
+
+static inline bool ir3_cat3_float(opc_t opc)
+{
+       switch (opc) {
+       case OPC_MAD_F16:
+       case OPC_MAD_F32:
+       case OPC_SEL_F16:
+       case OPC_SEL_F32:
+               return true;
+       default:
+               return false;
+       }
+}
 
 /* map cat2 instruction to valid abs/neg flags: */
 static inline unsigned ir3_cat2_absneg(opc_t opc)
@@ -1030,8 +1081,7 @@ void ir3_a6xx_fixup_atomic_dests(struct ir3 *ir, struct ir3_shader_variant *so);
 
 /* register assignment: */
 struct ir3_ra_reg_set * ir3_ra_alloc_reg_set(struct ir3_compiler *compiler);
-int ir3_ra(struct ir3 *ir3, gl_shader_stage type,
-               bool frag_coord, bool frag_face);
+int ir3_ra(struct ir3_shader_variant *v, struct ir3_instruction **precolor, unsigned nprecolor);
 
 /* legalize: */
 void ir3_legalize(struct ir3 *ir, bool *has_ssbo, bool *need_pixlod, int *max_bary);
@@ -1243,6 +1293,8 @@ INSTR0(BR)
 INSTR0(JUMP)
 INSTR1(KILL)
 INSTR0(END)
+INSTR0(CHSH)
+INSTR0(CHMASK)
 
 /* cat2 instructions, most 2 src but some 1 src: */
 INSTR2(ADD_F)
@@ -1355,10 +1407,12 @@ ir3_SAM(struct ir3_block *block, opc_t opc, type_t type,
 
 /* cat6 instructions: */
 INSTR2(LDLV)
-INSTR2(LDG)
-INSTR2(LDL)
+INSTR3(LDG)
+INSTR3(LDL)
+INSTR3(LDLW)
 INSTR3(STG)
 INSTR3(STL)
+INSTR3(STLW)
 INSTR1(RESINFO)
 INSTR1(RESFMT)
 INSTR2(ATOMIC_ADD)