summaryrefslogtreecommitdiff
path: root/src/freedreno
diff options
context:
space:
mode:
authorConnor Abbott <cwabbott0@gmail.com>2021-04-23 13:05:48 +0200
committerEmma Anholt <emma@anholt.net>2021-06-10 12:24:06 -0700
commitba8efeb7fa4a8a1f9b917b6f5ac7df8c2aace52e (patch)
tree43da31a7a5f434ffc4b88a02f6da8f711ad6835b /src/freedreno
parent8b15c2f30c40155a56a211c2e1c1b6c5fc0368b9 (diff)
ir3/sched: Make collects count against tex/sfu limits
In a scenario where there are a lot of texture fetches with constant coordinates, this prevents the scheduler from scheduling all the setup instructions after the first group of textures has been scheduled because they are the only non-syncing thing and scheduling them didn't decrease tex_delay. Collects with immed/const sources will turn into moves of those sources, so we should treat them the same. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9842>
Diffstat (limited to 'src/freedreno')
-rw-r--r--src/freedreno/ir3/ir3_sched.c31
1 files changed, 25 insertions, 6 deletions
diff --git a/src/freedreno/ir3/ir3_sched.c b/src/freedreno/ir3/ir3_sched.c
index 2e1cabfcd41..a51399e477d 100644
--- a/src/freedreno/ir3/ir3_sched.c
+++ b/src/freedreno/ir3/ir3_sched.c
@@ -220,6 +220,24 @@ is_outstanding_sfu(struct ir3_instruction *instr, struct ir3_sched_ctx *ctx)
return n->sfu_index >= ctx->first_outstanding_sfu_index;
}
+static unsigned
+cycle_count(struct ir3_instruction *instr)
+{
+ if (instr->opc == OPC_META_COLLECT) {
+ /* Assume that only immed/const sources produce moves */
+ unsigned n = 0;
+ foreach_src(src, instr) {
+ if (src->flags & (IR3_REG_IMMED | IR3_REG_CONST))
+ n++;
+ }
+ return n;
+ } else if (is_meta(instr)) {
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
static void
schedule(struct ir3_sched_ctx *ctx, struct ir3_instruction *instr)
{
@@ -272,17 +290,17 @@ schedule(struct ir3_sched_ctx *ctx, struct ir3_instruction *instr)
dag_prune_head(ctx->dag, &n->dag);
- if (is_meta(instr) && (instr->opc != OPC_META_TEX_PREFETCH))
- return;
+ unsigned cycles = cycle_count(instr);
if (is_sfu(instr)) {
ctx->sfu_delay = 8;
n->sfu_index = ctx->sfu_index++;
- } else if (sched_check_src_cond(instr, is_outstanding_sfu, ctx)) {
+ } else if (!is_meta(instr) &&
+ sched_check_src_cond(instr, is_outstanding_sfu, ctx)) {
ctx->sfu_delay = 0;
ctx->first_outstanding_sfu_index = ctx->sfu_index;
} else if (ctx->sfu_delay > 0) {
- ctx->sfu_delay--;
+ ctx->sfu_delay -= MIN2(cycles, ctx->sfu_delay);
}
if (is_tex_or_prefetch(instr)) {
@@ -295,11 +313,12 @@ schedule(struct ir3_sched_ctx *ctx, struct ir3_instruction *instr)
assert(ctx->remaining_tex > 0);
ctx->remaining_tex--;
n->tex_index = ctx->tex_index++;
- } else if (sched_check_src_cond(instr, is_outstanding_tex_or_prefetch, ctx)) {
+ } else if (!is_meta(instr) &&
+ sched_check_src_cond(instr, is_outstanding_tex_or_prefetch, ctx)) {
ctx->tex_delay = 0;
ctx->first_outstanding_tex_index = ctx->tex_index;
} else if (ctx->tex_delay > 0) {
- ctx->tex_delay--;
+ ctx->tex_delay -= MIN2(cycles, ctx->tex_delay);
}
}