freedreno/ir3: fix varying packing vs. tex sharp edge

We probably need to rethink how we detect which instruction first
defines higher register classes.  But for now, this at least fixes
the symptom.

Signed-off-by: Rob Clark <robdclark@gmail.com>
This commit is contained in:
Rob Clark 2019-02-14 09:46:06 -05:00
parent 52bdb043af
commit c0d6be11d6

View file

@ -503,8 +503,8 @@ get_definer(struct ir3_ra_ctx *ctx, struct ir3_instruction *instr,
*sz = MAX2(*sz, dsz);
debug_assert(instr->opc == OPC_META_FO);
*off = MAX2(*off, instr->fo.off);
if (instr->opc == OPC_META_FO)
*off = MAX2(*off, instr->fo.off);
d = dd;
}
@ -531,8 +531,36 @@ ra_block_find_definers(struct ir3_ra_ctx *ctx, struct ir3_block *block)
} else if (instr->regs[0]->flags & IR3_REG_ARRAY) {
id->cls = total_class_count;
} else {
/* and the normal case: */
id->defn = get_definer(ctx, instr, &id->sz, &id->off);
id->cls = size_to_class(id->sz, is_half(id->defn), is_high(id->defn));
/* this is a bit of duct-tape.. if we have a scenario like:
*
* sam (f32)(x) out.x, ...
* sam (f32)(x) out.y, ...
*
* Then the fanout/split meta instructions for the two different
* tex instructions end up grouped as left/right neighbors. The
* upshot is that in when you get_definer() on one of the meta:fo's
* you get definer as the first sam with sz=2, but when you call
* get_definer() on the either of the sam's you get itself as the
* definer with sz=1.
*
* (We actually avoid this scenario exactly, the neighbor links
* prevent one of the output mov's from being eliminated, so this
* hack should be enough. But probably we need to rethink how we
* find the "defining" instruction.)
*
* TODO how do we figure out offset properly...
*/
if (id->defn != instr) {
struct ir3_ra_instr_data *did = &ctx->instrd[id->defn->ip];
if (did->sz < id->sz) {
did->sz = id->sz;
did->cls = id->cls;
}
}
}
}
}