aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRob Clark <[email protected]>2019-02-14 09:46:06 -0500
committerRob Clark <[email protected]>2019-02-16 16:26:14 -0500
commitc0d6be11d6bce38c014524b2a7bf0c8fcebccece (patch)
tree400f85298bc5e0bed94795a969f0ff8357181c5f /src
parent52bdb043af952691b560118ca99e341527560e13 (diff)
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 <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/freedreno/ir3/ir3_ra.c32
1 files changed, 30 insertions, 2 deletions
diff --git a/src/freedreno/ir3/ir3_ra.c b/src/freedreno/ir3/ir3_ra.c
index f951acd5eef..a9e1894a350 100644
--- a/src/freedreno/ir3/ir3_ra.c
+++ b/src/freedreno/ir3/ir3_ra.c
@@ -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;
+ }
+ }
}
}
}