diff options
author | Rob Clark <[email protected]> | 2019-03-16 11:45:16 -0400 |
---|---|---|
committer | Rob Clark <[email protected]> | 2019-03-21 09:13:05 -0400 |
commit | 8eb16ae8bfb1b8a74b86ea57d6b9e467e30bc4f3 (patch) | |
tree | 2f9dd4452ae99590d673f03e1ac1c6c29332a627 | |
parent | 1dffb089f903577602bae49931f3d2a71a1a8420 (diff) |
freedreno/ir3: fix regmask for merged regs
On a6xx+ with half-regs conflicting with full-regs, the legalize pass
needs to set appropriate sync bits, such as (sy), on writes to full regs
that conflict with half regs, and visa-versa.
Signed-off-by: Rob Clark <[email protected]>
-rw-r--r-- | src/freedreno/ir3/ir3.c | 3 | ||||
-rw-r--r-- | src/freedreno/ir3/ir3.h | 13 |
2 files changed, 13 insertions, 3 deletions
diff --git a/src/freedreno/ir3/ir3.c b/src/freedreno/ir3/ir3.c index 9169d2c15f3..23b12a6fc5f 100644 --- a/src/freedreno/ir3/ir3.c +++ b/src/freedreno/ir3/ir3.c @@ -35,6 +35,7 @@ #include "util/u_math.h" #include "instr-a3xx.h" +#include "ir3_compiler.h" /* simple allocator to carve allocations out of an up-front allocated heap, * so that we can free everything easily in one shot. @@ -899,6 +900,8 @@ static struct ir3_register * reg_create(struct ir3 *shader, reg->wrmask = 1; reg->flags = flags; reg->num = num; + if (shader->compiler->gpu_id >= 600) + reg->merged = true; return reg; } diff --git a/src/freedreno/ir3/ir3.h b/src/freedreno/ir3/ir3.h index 4bd7601b8dd..b42524d22ae 100644 --- a/src/freedreno/ir3/ir3.h +++ b/src/freedreno/ir3/ir3.h @@ -98,11 +98,13 @@ struct ir3_register { } flags; + bool merged : 1; /* half-regs conflict with full regs (ie >= a6xx) */ + /* normal registers: * the component is in the low two bits of the reg #, so * rN.x becomes: (N << 2) | x */ - int num; + uint16_t num; union { /* immediate: */ int32_t iim_val; @@ -1426,8 +1428,13 @@ static inline unsigned regmask_idx(struct ir3_register *reg) { unsigned num = (reg->flags & IR3_REG_RELATIV) ? reg->array.offset : reg->num; debug_assert(num < MAX_REG); - if (reg->flags & IR3_REG_HALF) - num += MAX_REG; + if (reg->flags & IR3_REG_HALF) { + if (reg->merged) { + num /= 2; + } else { + num += MAX_REG; + } + } return num; } |