From ba8efeb7fa4a8a1f9b917b6f5ac7df8c2aace52e Mon Sep 17 00:00:00 2001 From: Connor Abbott Date: Fri, 23 Apr 2021 13:05:48 +0200 Subject: [PATCH] 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: --- src/freedreno/ir3/ir3_sched.c | 31 +++++++++++++++++++++++++------ 1 file 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); } }