Browse Source

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 <robdclark@gmail.com>
tags/19.1-branchpoint
Rob Clark 6 years ago
parent
commit
8eb16ae8bf
2 changed files with 13 additions and 3 deletions
  1. 3
    0
      src/freedreno/ir3/ir3.c
  2. 10
    3
      src/freedreno/ir3/ir3.h

+ 3
- 0
src/freedreno/ir3/ir3.c View File

@@ -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;
}


+ 10
- 3
src/freedreno/ir3/ir3.h View File

@@ -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;
}


Loading…
Cancel
Save