summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRob Clark <[email protected]>2019-03-16 11:45:16 -0400
committerRob Clark <[email protected]>2019-03-21 09:13:05 -0400
commit8eb16ae8bfb1b8a74b86ea57d6b9e467e30bc4f3 (patch)
tree2f9dd4452ae99590d673f03e1ac1c6c29332a627
parent1dffb089f903577602bae49931f3d2a71a1a8420 (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.c3
-rw-r--r--src/freedreno/ir3/ir3.h13
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;
}