freedreno/ir3: Fix the type of half-float indirect uniform loads.
[mesa.git] / src / freedreno / ir3 / ir3.h
index c0d46eea8f537be5cf460e81bd46cb1cf50c61db..2f5423238e0a6c9fff4b22ec7774bec155326ca1 100644 (file)
@@ -44,7 +44,7 @@ struct ir3_instruction;
 struct ir3_block;
 
 struct ir3_info {
 struct ir3_block;
 
 struct ir3_info {
-       uint32_t gpu_id;
+       void *data;              /* used internally in ir3 assembler */
        uint16_t sizedwords;
        uint16_t instrs_count;   /* expanded to account for rpt's */
        uint16_t nops_count;     /* # of nop instructions, including nopN */
        uint16_t sizedwords;
        uint16_t instrs_count;   /* expanded to account for rpt's */
        uint16_t nops_count;     /* # of nop instructions, including nopN */
@@ -506,6 +506,8 @@ struct ir3_array {
 
        /* Indicates if half-precision */
        bool half;
 
        /* Indicates if half-precision */
        bool half;
+
+       bool unused;
 };
 
 struct ir3_array * ir3_lookup_array(struct ir3 *ir, unsigned id);
 };
 
 struct ir3_array * ir3_lookup_array(struct ir3 *ir, unsigned id);
@@ -554,10 +556,12 @@ block_id(struct ir3_block *block)
 #endif
 }
 
 #endif
 }
 
-struct ir3 * ir3_create(struct ir3_compiler *compiler, gl_shader_stage type);
+struct ir3_shader_variant;
+
+struct ir3 * ir3_create(struct ir3_compiler *compiler, struct ir3_shader_variant *v);
 void ir3_destroy(struct ir3 *shader);
 void ir3_destroy(struct ir3 *shader);
-void * ir3_assemble(struct ir3 *shader,
-               struct ir3_info *info, uint32_t gpu_id);
+
+void * ir3_assemble(struct ir3_shader_variant *v);
 void * ir3_alloc(struct ir3 *shader, int sz);
 
 struct ir3_block * ir3_block_create(struct ir3 *shader);
 void * ir3_alloc(struct ir3 *shader, int sz);
 
 struct ir3_block * ir3_block_create(struct ir3 *shader);
@@ -627,19 +631,6 @@ bool ir3_valid_flags(struct ir3_instruction *instr, unsigned n, unsigned flags);
                set_foreach ((__instr)->uses, __entry) \
                        if ((__use = (void *)__entry->key))
 
                set_foreach ((__instr)->uses, __entry) \
                        if ((__use = (void *)__entry->key))
 
-#define MAX_ARRAYS 16
-
-/* comp:
- *   0 - x
- *   1 - y
- *   2 - z
- *   3 - w
- */
-static inline uint32_t regid(int num, int comp)
-{
-       return (num << 2) | (comp & 0x3);
-}
-
 static inline uint32_t reg_num(struct ir3_register *reg)
 {
        return reg->num >> 2;
 static inline uint32_t reg_num(struct ir3_register *reg)
 {
        return reg->num >> 2;
@@ -650,10 +641,6 @@ static inline uint32_t reg_comp(struct ir3_register *reg)
        return reg->num & 0x3;
 }
 
        return reg->num & 0x3;
 }
 
-#define INVALID_REG      regid(63, 0)
-#define VALIDREG(r)      ((r) != INVALID_REG)
-#define CONDREG(r, val)  COND(VALIDREG(r), (val))
-
 static inline bool is_flow(struct ir3_instruction *instr)
 {
        return (opc_cat(instr->opc) == 0);
 static inline bool is_flow(struct ir3_instruction *instr)
 {
        return (opc_cat(instr->opc) == 0);
@@ -1242,6 +1229,8 @@ static inline bool __is_false_dep(struct ir3_instruction *instr, unsigned n)
 /* iterators for arrays: */
 #define foreach_array(__array, __list) \
        list_for_each_entry(struct ir3_array, __array, __list, node)
 /* iterators for arrays: */
 #define foreach_array(__array, __list) \
        list_for_each_entry(struct ir3_array, __array, __list, node)
+#define foreach_array_safe(__array, __list) \
+       list_for_each_entry_safe(struct ir3_array, __array, __list, node)
 
 /* Check if condition is true for any src instruction.
  */
 
 /* Check if condition is true for any src instruction.
  */
@@ -1420,14 +1409,14 @@ create_uniform(struct ir3_block *block, unsigned n)
 }
 
 static inline struct ir3_instruction *
 }
 
 static inline struct ir3_instruction *
-create_uniform_indirect(struct ir3_block *block, int n,
+create_uniform_indirect(struct ir3_block *block, int n, type_t type,
                struct ir3_instruction *address)
 {
        struct ir3_instruction *mov;
 
        mov = ir3_instr_create(block, OPC_MOV);
                struct ir3_instruction *address)
 {
        struct ir3_instruction *mov;
 
        mov = ir3_instr_create(block, OPC_MOV);
-       mov->cat1.src_type = TYPE_U32;
-       mov->cat1.dst_type = TYPE_U32;
+       mov->cat1.src_type = type;
+       mov->cat1.dst_type = type;
        __ssa_dst(mov);
        ir3_reg_create(mov, 0, IR3_REG_CONST | IR3_REG_RELATIV)->array.offset = n;
 
        __ssa_dst(mov);
        ir3_reg_create(mov, 0, IR3_REG_CONST | IR3_REG_RELATIV)->array.offset = n;
 
@@ -1657,9 +1646,9 @@ INSTR1(SQRT)
 
 /* cat5 instructions: */
 INSTR1(DSX)
 
 /* cat5 instructions: */
 INSTR1(DSX)
-INSTR1(DSXPP_1)
+INSTR1(DSXPP_MACRO)
 INSTR1(DSY)
 INSTR1(DSY)
-INSTR1(DSYPP_1)
+INSTR1(DSYPP_MACRO)
 INSTR1F(3D, DSX)
 INSTR1F(3D, DSY)
 INSTR1(RGETPOS)
 INSTR1F(3D, DSX)
 INSTR1F(3D, DSY)
 INSTR1(RGETPOS)
@@ -1675,7 +1664,7 @@ ir3_SAM(struct ir3_block *block, opc_t opc, type_t type,
        sam->flags |= flags;
        __ssa_dst(sam)->wrmask = wrmask;
        if (flags & IR3_INSTR_S2EN) {
        sam->flags |= flags;
        __ssa_dst(sam)->wrmask = wrmask;
        if (flags & IR3_INSTR_S2EN) {
-               __ssa_src(sam, samp_tex, IR3_REG_HALF);
+               __ssa_src(sam, samp_tex, (flags & IR3_INSTR_B) ? 0 : IR3_REG_HALF);
        }
        if (src0) {
                __ssa_src(sam, src0, 0);
        }
        if (src0) {
                __ssa_src(sam, src0, 0);
@@ -1751,113 +1740,37 @@ INSTR0(FENCE)
 INSTR0(META_TEX_PREFETCH);
 
 /* ************************************************************************* */
 INSTR0(META_TEX_PREFETCH);
 
 /* ************************************************************************* */
-/* split this out or find some helper to use.. like main/bitset.h.. */
-
-#include <string.h>
-#include "util/bitset.h"
-
-#define MAX_REG 256
-
-typedef BITSET_DECLARE(regmaskstate_t, 2 * MAX_REG);
-
-typedef struct {
-       bool mergedregs;
-       regmaskstate_t mask;
-} regmask_t;
-
-static inline bool
-__regmask_get(regmask_t *regmask, struct ir3_register *reg, unsigned n)
-{
-       if (regmask->mergedregs) {
-               /* a6xx+ case, with merged register file, we track things in terms
-                * of half-precision registers, with a full precisions register
-                * using two half-precision slots:
-                */
-               if (reg->flags & IR3_REG_HALF) {
-                       return BITSET_TEST(regmask->mask, n);
-               } else {
-                       n *= 2;
-                       return BITSET_TEST(regmask->mask, n) ||
-                               BITSET_TEST(regmask->mask, n+1);
-               }
-       } else {
-               /* pre a6xx case, with separate register file for half and full
-                * precision:
-                */
-               if (reg->flags & IR3_REG_HALF)
-                       n += MAX_REG;
-               return BITSET_TEST(regmask->mask, n);
-       }
-}
-
-static inline void
-__regmask_set(regmask_t *regmask, struct ir3_register *reg, unsigned n)
-{
-       if (regmask->mergedregs) {
-               /* a6xx+ case, with merged register file, we track things in terms
-                * of half-precision registers, with a full precisions register
-                * using two half-precision slots:
-                */
-               if (reg->flags & IR3_REG_HALF) {
-                       BITSET_SET(regmask->mask, n);
-               } else {
-                       n *= 2;
-                       BITSET_SET(regmask->mask, n);
-                       BITSET_SET(regmask->mask, n+1);
-               }
-       } else {
-               /* pre a6xx case, with separate register file for half and full
-                * precision:
-                */
-               if (reg->flags & IR3_REG_HALF)
-                       n += MAX_REG;
-               BITSET_SET(regmask->mask, n);
-       }
-}
-
-static inline void regmask_init(regmask_t *regmask, bool mergedregs)
-{
-       memset(&regmask->mask, 0, sizeof(regmask->mask));
-       regmask->mergedregs = mergedregs;
-}
+#include "regmask.h"
 
 static inline void regmask_set(regmask_t *regmask, struct ir3_register *reg)
 {
 
 static inline void regmask_set(regmask_t *regmask, struct ir3_register *reg)
 {
+       bool half = reg->flags & IR3_REG_HALF;
        if (reg->flags & IR3_REG_RELATIV) {
                for (unsigned i = 0; i < reg->size; i++)
        if (reg->flags & IR3_REG_RELATIV) {
                for (unsigned i = 0; i < reg->size; i++)
-                       __regmask_set(regmask, reg, reg->array.offset + i);
+                       __regmask_set(regmask, half, reg->array.offset + i);
        } else {
                for (unsigned mask = reg->wrmask, n = reg->num; mask; mask >>= 1, n++)
                        if (mask & 1)
        } else {
                for (unsigned mask = reg->wrmask, n = reg->num; mask; mask >>= 1, n++)
                        if (mask & 1)
-                               __regmask_set(regmask, reg, n);
+                               __regmask_set(regmask, half, n);
        }
 }
 
        }
 }
 
-static inline void regmask_or(regmask_t *dst, regmask_t *a, regmask_t *b)
-{
-       assert(dst->mergedregs == a->mergedregs);
-       assert(dst->mergedregs == b->mergedregs);
-
-       for (unsigned i = 0; i < ARRAY_SIZE(dst->mask); i++)
-               dst->mask[i] = a->mask[i] | b->mask[i];
-}
-
 static inline bool regmask_get(regmask_t *regmask,
                struct ir3_register *reg)
 {
 static inline bool regmask_get(regmask_t *regmask,
                struct ir3_register *reg)
 {
+       bool half = reg->flags & IR3_REG_HALF;
        if (reg->flags & IR3_REG_RELATIV) {
                for (unsigned i = 0; i < reg->size; i++)
        if (reg->flags & IR3_REG_RELATIV) {
                for (unsigned i = 0; i < reg->size; i++)
-                       if (__regmask_get(regmask, reg, reg->array.offset + i))
+                       if (__regmask_get(regmask, half, reg->array.offset + i))
                                return true;
        } else {
                for (unsigned mask = reg->wrmask, n = reg->num; mask; mask >>= 1, n++)
                        if (mask & 1)
                                return true;
        } else {
                for (unsigned mask = reg->wrmask, n = reg->num; mask; mask >>= 1, n++)
                        if (mask & 1)
-                               if (__regmask_get(regmask, reg, n))
+                               if (__regmask_get(regmask, half, n))
                                        return true;
        }
        return false;
 }
                                        return true;
        }
        return false;
 }
-
 /* ************************************************************************* */
 
 #endif /* IR3_H_ */
 /* ************************************************************************* */
 
 #endif /* IR3_H_ */