From: Rob Clark Date: Mon, 24 Feb 2020 22:16:15 +0000 (-0800) Subject: freedreno/ir3: don't hide latency when there is none to hide X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=4353b3c1c5ae3927ad7e99b72cdf1ce63023493d;p=mesa.git freedreno/ir3: don't hide latency when there is none to hide Current scheduler thresholds try to ensure there are warps available to switch to when hiding texture fetch latency. But if there is none to hide, we should allow scheduler to use more registers to reduce nops. Signed-off-by: Rob Clark Part-of: --- diff --git a/src/freedreno/ir3/ir3_sched.c b/src/freedreno/ir3/ir3_sched.c index 986c80e4940..d250c1c6264 100644 --- a/src/freedreno/ir3/ir3_sched.c +++ b/src/freedreno/ir3/ir3_sched.c @@ -72,6 +72,11 @@ struct ir3_sched_ctx { struct ir3_instruction *pred; /* current p0.x user, if any */ int live_values; /* estimate of current live values */ bool error; + + unsigned live_threshold_hi; + unsigned live_threshold_lo; + unsigned depth_threshold_hi; + unsigned depth_threshold_lo; }; static bool is_scheduled(struct ir3_instruction *instr) @@ -525,10 +530,10 @@ find_eligible_instr(struct ir3_sched_ctx *ctx, struct ir3_sched_notes *notes, if (le >= 1) { unsigned threshold; - if (ctx->live_values > 4*4) { - threshold = 4; + if (ctx->live_values > ctx->live_threshold_lo) { + threshold = ctx->depth_threshold_lo; } else { - threshold = 6; + threshold = ctx->depth_threshold_hi; } /* Filter out any "shallow" instructions which would otherwise @@ -552,9 +557,9 @@ find_eligible_instr(struct ir3_sched_ctx *ctx, struct ir3_sched_notes *notes, /* if too many live values, prioritize instructions that reduce the * number of live values: */ - if (ctx->live_values > 16*4) { + if (ctx->live_values > ctx->live_threshold_hi) { rank = le; - } else if (ctx->live_values > 4*4) { + } else if (ctx->live_values > ctx->live_threshold_lo) { rank += le; } @@ -763,10 +768,52 @@ sched_block(struct ir3_sched_ctx *ctx, struct ir3_block *block) } } +static bool +has_latency_to_hide(struct ir3 *ir) +{ + foreach_block (block, &ir->block_list) { + foreach_instr (instr, &block->instr_list) { + if (is_tex(instr)) + return true; + + if (is_load(instr)) { + switch (instr->opc) { + case OPC_LDLV: + case OPC_LDL: + case OPC_LDLW: + break; + default: + return true; + } + } + } + } + + return false; +} + +static void +setup_thresholds(struct ir3_sched_ctx *ctx, struct ir3 *ir) +{ + if (has_latency_to_hide(ir)) { + ctx->live_threshold_hi = 16 * 4; + ctx->live_threshold_lo = 4 * 4; + ctx->depth_threshold_hi = 6; + ctx->depth_threshold_lo = 4; + } else { + ctx->live_threshold_hi = 16 * 4; + ctx->live_threshold_lo = 12 * 4; + ctx->depth_threshold_hi = 16; + ctx->depth_threshold_lo = 16; + } +} + int ir3_sched(struct ir3 *ir) { struct ir3_sched_ctx ctx = {0}; + setup_thresholds(&ctx, ir); + ir3_clear_mark(ir); update_use_count(ir);