pan/bi: Index out constants in instructions
We rewrite BIR_INDEX_CONSTANT (and _ZERO) to preassigned constant ports when assign uniform_const for the bundle. There are a lot of issues raised here, unfortunately, and the implementation here is woefully incomplete with a nasty hack for loads... nevertheless, it's somewhere to start. Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4276>
This commit is contained in:
parent
d2d0de962e
commit
fc0b49bb2c
|
@ -71,12 +71,100 @@ struct bi_registers {
|
|||
bool read_port3;
|
||||
|
||||
/* Packed uniform/constant */
|
||||
unsigned uniform_constant;
|
||||
uint8_t uniform_constant;
|
||||
|
||||
/* Whether writes are actually for the last instruction */
|
||||
bool first_instruction;
|
||||
};
|
||||
|
||||
/* The uniform/constant slot allows loading a contiguous 64-bit immediate or
|
||||
* pushed uniform per bundle. Figure out which one we need in the bundle (the
|
||||
* scheduler needs to ensure we only have one type per bundle), validate
|
||||
* everything, and rewrite away the register/uniform indices to use 3-bit
|
||||
* sources directly. */
|
||||
|
||||
static unsigned
|
||||
bi_lookup_constant(bi_clause *clause, uint64_t cons)
|
||||
{
|
||||
for (unsigned i = 0; i < clause->constant_count; ++i) {
|
||||
/* Only check top 60-bits since that's what's actually embedded
|
||||
* in the clause, the bottom 4-bits are bundle-inline */
|
||||
|
||||
if ((cons >> 4) == (clause->constants[i] >> 4))
|
||||
return i;
|
||||
}
|
||||
|
||||
unreachable("Invalid constant accessed");
|
||||
}
|
||||
|
||||
static unsigned
|
||||
bi_constant_field(unsigned idx)
|
||||
{
|
||||
assert(idx <= 5);
|
||||
|
||||
const unsigned values[] = {
|
||||
4, 5, 6, 7, 2, 3
|
||||
};
|
||||
|
||||
return values[idx] << 4;
|
||||
}
|
||||
|
||||
static bool
|
||||
bi_assign_uniform_constant_single(
|
||||
struct bi_registers *regs,
|
||||
bi_clause *clause,
|
||||
bi_instruction *ins, bool assigned, bool fast_zero)
|
||||
{
|
||||
if (!ins)
|
||||
return assigned;
|
||||
|
||||
bi_foreach_src(ins, s) {
|
||||
if (ins->src[s] & BIR_INDEX_CONSTANT) {
|
||||
/* TODO: lo/hi matching? */
|
||||
uint64_t cons = ins->constant.u64;
|
||||
unsigned idx = bi_lookup_constant(clause, cons);
|
||||
unsigned f = bi_constant_field(idx) | (cons & 0xF);
|
||||
|
||||
if (assigned && regs->uniform_constant != f)
|
||||
unreachable("Mismatched uniform/const field: imm");
|
||||
|
||||
regs->uniform_constant = f;
|
||||
ins->src[s] = BIR_INDEX_PASS | BIFROST_SRC_CONST_LO;
|
||||
assigned = true;
|
||||
} else if (ins->src[s] & BIR_INDEX_ZERO && (ins->type == BI_LOAD_UNIFORM || ins->type == BI_LOAD_VAR)) {
|
||||
/* XXX: HACK UNTIL WE HAVE HI MATCHING DUE TO OVERFLOW XXX */
|
||||
ins->src[s] = BIR_INDEX_PASS | BIFROST_SRC_CONST_HI;
|
||||
} else if (ins->src[s] & BIR_INDEX_ZERO && !fast_zero) {
|
||||
/* FMAs have a fast zero port, ADD needs to use the
|
||||
* uniform/const port's special 0 mode handled here */
|
||||
unsigned f = 0;
|
||||
|
||||
if (assigned && regs->uniform_constant != f)
|
||||
unreachable("Mismatched uniform/const field: 0");
|
||||
|
||||
regs->uniform_constant = f;
|
||||
ins->src[s] = BIR_INDEX_PASS | BIFROST_SRC_CONST_LO;
|
||||
assigned = true;
|
||||
} else if (s & BIR_INDEX_UNIFORM) {
|
||||
unreachable("Push uniforms not implemented yet");
|
||||
}
|
||||
}
|
||||
|
||||
return assigned;
|
||||
}
|
||||
|
||||
static void
|
||||
bi_assign_uniform_constant(
|
||||
bi_clause *clause,
|
||||
struct bi_registers *regs,
|
||||
bi_bundle bundle)
|
||||
{
|
||||
bool assigned =
|
||||
bi_assign_uniform_constant_single(regs, clause, bundle.fma, false, true);
|
||||
|
||||
bi_assign_uniform_constant_single(regs, clause, bundle.add, assigned, false);
|
||||
}
|
||||
|
||||
/* Assigns a port for reading, before anything is written */
|
||||
|
||||
static void
|
||||
|
@ -279,29 +367,6 @@ bi_get_src_reg_port(struct bi_registers *regs, unsigned src)
|
|||
unreachable("Tried to access register with no port");
|
||||
}
|
||||
|
||||
static enum bifrost_packed_src
|
||||
bi_get_src_const(struct bi_registers *regs, unsigned constant)
|
||||
{
|
||||
if (regs->uniform_constant & (1 << 7))
|
||||
unreachable("Tried to get constant but loading uniforms");
|
||||
|
||||
unsigned loc = (regs->uniform_constant >> 4) & 0x7;
|
||||
|
||||
if (loc != 0)
|
||||
unreachable("TODO: constants in clauses");
|
||||
|
||||
unsigned lo = regs->uniform_constant & 0xF;
|
||||
|
||||
if (lo == 0) {
|
||||
if (constant != 0)
|
||||
unreachable("Tried to load !0 in 0 slot");
|
||||
|
||||
return BIFROST_SRC_CONST_LO;
|
||||
} else {
|
||||
unreachable("Special slot is not a fixed immediate");
|
||||
}
|
||||
}
|
||||
|
||||
static enum bifrost_packed_src
|
||||
bi_get_src(bi_instruction *ins, struct bi_registers *regs, unsigned s, bool is_fma)
|
||||
{
|
||||
|
@ -311,12 +376,8 @@ bi_get_src(bi_instruction *ins, struct bi_registers *regs, unsigned s, bool is_f
|
|||
return bi_get_src_reg_port(regs, src);
|
||||
else if (src & BIR_INDEX_ZERO && is_fma)
|
||||
return BIFROST_SRC_STAGE;
|
||||
else if (src & BIR_INDEX_ZERO)
|
||||
return bi_get_src_const(regs, 0);
|
||||
else if (src & BIR_INDEX_PASS)
|
||||
return src & ~BIR_INDEX_PASS;
|
||||
else if (src & BIR_INDEX_CONSTANT)
|
||||
return bi_get_src_const(regs, 0); /*TODO ins->constant.u64 */
|
||||
else
|
||||
unreachable("Unknown src");
|
||||
}
|
||||
|
@ -538,6 +599,7 @@ static struct bi_packed_bundle
|
|||
bi_pack_bundle(bi_clause *clause, bi_bundle bundle, bi_bundle prev, bool first_bundle)
|
||||
{
|
||||
struct bi_registers regs = bi_assign_ports(bundle, prev);
|
||||
bi_assign_uniform_constant(clause, ®s, bundle);
|
||||
regs.first_instruction = first_bundle;
|
||||
|
||||
uint64_t reg = bi_pack_registers(regs);
|
||||
|
|
Loading…
Reference in New Issue