pan/midgard: Represent ld/st offset unpacked
This simplifies manipulation of the offsets dramatically, fixing some UBO access related bugs. Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
This commit is contained in:
parent
1798f6bfc3
commit
bc9a7d0699
|
@ -517,7 +517,6 @@ bool mir_special_index(compiler_context *ctx, unsigned idx);
|
||||||
unsigned mir_use_count(compiler_context *ctx, unsigned value);
|
unsigned mir_use_count(compiler_context *ctx, unsigned value);
|
||||||
bool mir_is_written_before(compiler_context *ctx, midgard_instruction *ins, unsigned node);
|
bool mir_is_written_before(compiler_context *ctx, midgard_instruction *ins, unsigned node);
|
||||||
uint16_t mir_bytemask_of_read_components(midgard_instruction *ins, unsigned node);
|
uint16_t mir_bytemask_of_read_components(midgard_instruction *ins, unsigned node);
|
||||||
unsigned mir_ubo_shift(midgard_load_store_op op);
|
|
||||||
midgard_reg_mode mir_typesize(midgard_instruction *ins);
|
midgard_reg_mode mir_typesize(midgard_instruction *ins);
|
||||||
midgard_reg_mode mir_srcsize(midgard_instruction *ins, unsigned i);
|
midgard_reg_mode mir_srcsize(midgard_instruction *ins, unsigned i);
|
||||||
unsigned mir_bytes_for_mode(midgard_reg_mode mode);
|
unsigned mir_bytes_for_mode(midgard_reg_mode mode);
|
||||||
|
|
|
@ -1141,11 +1141,8 @@ emit_ubo_read(
|
||||||
{
|
{
|
||||||
/* TODO: half-floats */
|
/* TODO: half-floats */
|
||||||
|
|
||||||
midgard_instruction ins = m_ld_ubo_int4(dest, offset);
|
midgard_instruction ins = m_ld_ubo_int4(dest, 0);
|
||||||
|
ins.constants[0] = offset;
|
||||||
/* TODO: Don't split */
|
|
||||||
ins.load_store.varying_parameters = (offset & 0x7F) << 3;
|
|
||||||
ins.load_store.address = offset >> 7;
|
|
||||||
mir_set_intr_mask(instr, &ins, true);
|
mir_set_intr_mask(instr, &ins, true);
|
||||||
|
|
||||||
if (indirect_offset) {
|
if (indirect_offset) {
|
||||||
|
|
|
@ -388,6 +388,14 @@ emit_binary_bundle(compiler_context *ctx,
|
||||||
mir_pack_ldst_mask(bundle->instructions[i]);
|
mir_pack_ldst_mask(bundle->instructions[i]);
|
||||||
|
|
||||||
mir_pack_swizzle_ldst(bundle->instructions[i]);
|
mir_pack_swizzle_ldst(bundle->instructions[i]);
|
||||||
|
|
||||||
|
/* Apply a constant offset */
|
||||||
|
unsigned offset = bundle->instructions[i]->constants[0];
|
||||||
|
|
||||||
|
if (offset) {
|
||||||
|
bundle->instructions[i]->load_store.varying_parameters |= (offset & 0x7F) << 3;
|
||||||
|
bundle->instructions[i]->load_store.address |= (offset >> 7);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(¤t64, &bundle->instructions[0]->load_store, sizeof(current64));
|
memcpy(¤t64, &bundle->instructions[0]->load_store, sizeof(current64));
|
||||||
|
|
|
@ -1169,16 +1169,14 @@ v_load_store_scratch(
|
||||||
/* For register spilling - to thread local storage */
|
/* For register spilling - to thread local storage */
|
||||||
.arg_1 = 0xEA,
|
.arg_1 = 0xEA,
|
||||||
.arg_2 = 0x1E,
|
.arg_2 = 0x1E,
|
||||||
|
|
||||||
/* Splattered across, TODO combine logically */
|
|
||||||
.varying_parameters = (byte & 0x1FF) << 1,
|
|
||||||
.address = (byte >> 9)
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/* If we spill an unspill, RA goes into an infinite loop */
|
/* If we spill an unspill, RA goes into an infinite loop */
|
||||||
.no_spill = true
|
.no_spill = true
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ins.constants[0] = byte;
|
||||||
|
|
||||||
if (is_store) {
|
if (is_store) {
|
||||||
/* r0 = r26, r1 = r27 */
|
/* r0 = r26, r1 = r27 */
|
||||||
assert(srcdest == SSA_FIXED_REGISTER(26) || srcdest == SSA_FIXED_REGISTER(27));
|
assert(srcdest == SSA_FIXED_REGISTER(26) || srcdest == SSA_FIXED_REGISTER(27));
|
||||||
|
|
|
@ -478,25 +478,6 @@ mir_bytemask_of_read_components(midgard_instruction *ins, unsigned node)
|
||||||
return mask;
|
return mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned
|
|
||||||
mir_ubo_shift(midgard_load_store_op op)
|
|
||||||
{
|
|
||||||
switch (op) {
|
|
||||||
case midgard_op_ld_ubo_char:
|
|
||||||
return 0;
|
|
||||||
case midgard_op_ld_ubo_char2:
|
|
||||||
return 1;
|
|
||||||
case midgard_op_ld_ubo_char4:
|
|
||||||
return 2;
|
|
||||||
case midgard_op_ld_ubo_short4:
|
|
||||||
return 3;
|
|
||||||
case midgard_op_ld_ubo_int4:
|
|
||||||
return 4;
|
|
||||||
default:
|
|
||||||
unreachable("Invalid op");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Register allocation occurs after instruction scheduling, which is fine until
|
/* Register allocation occurs after instruction scheduling, which is fine until
|
||||||
* we start needing to spill registers and therefore insert instructions into
|
* we start needing to spill registers and therefore insert instructions into
|
||||||
* an already-scheduled program. We don't have to be terribly efficient about
|
* an already-scheduled program. We don't have to be terribly efficient about
|
||||||
|
|
|
@ -36,22 +36,6 @@
|
||||||
* program so we allow that many registers through at minimum, to prevent
|
* program so we allow that many registers through at minimum, to prevent
|
||||||
* spilling. If we spill anyway, I mean, it's a lose-lose at that point. */
|
* spilling. If we spill anyway, I mean, it's a lose-lose at that point. */
|
||||||
|
|
||||||
static unsigned
|
|
||||||
mir_ubo_offset(midgard_instruction *ins)
|
|
||||||
{
|
|
||||||
assert(ins->type == TAG_LOAD_STORE_4);
|
|
||||||
assert(OP_IS_UBO_READ(ins->load_store.op));
|
|
||||||
|
|
||||||
/* Grab the offset as the hw understands it */
|
|
||||||
unsigned lo = ins->load_store.varying_parameters >> 7;
|
|
||||||
unsigned hi = ins->load_store.address;
|
|
||||||
unsigned raw = ((hi << 3) | lo);
|
|
||||||
|
|
||||||
/* Account for the op's shift */
|
|
||||||
unsigned shift = mir_ubo_shift(ins->load_store.op);
|
|
||||||
return (raw << shift);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
midgard_promote_uniforms(compiler_context *ctx, unsigned promoted_count)
|
midgard_promote_uniforms(compiler_context *ctx, unsigned promoted_count)
|
||||||
{
|
{
|
||||||
|
@ -59,8 +43,8 @@ midgard_promote_uniforms(compiler_context *ctx, unsigned promoted_count)
|
||||||
if (ins->type != TAG_LOAD_STORE_4) continue;
|
if (ins->type != TAG_LOAD_STORE_4) continue;
|
||||||
if (!OP_IS_UBO_READ(ins->load_store.op)) continue;
|
if (!OP_IS_UBO_READ(ins->load_store.op)) continue;
|
||||||
|
|
||||||
/* Get the offset. TODO: can we promote unaligned access? */
|
/* TODO: promote unaligned access via swizzle? */
|
||||||
unsigned off = mir_ubo_offset(ins);
|
unsigned off = ins->constants[0];
|
||||||
if (off & 0xF) continue;
|
if (off & 0xF) continue;
|
||||||
|
|
||||||
unsigned address = off / 16;
|
unsigned address = off / 16;
|
||||||
|
|
Loading…
Reference in New Issue