From dd06e6af34ac027e04d69232e0f1d30b4d76c8ca Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Wed, 26 May 2021 19:51:46 -0400 Subject: [PATCH] agx: Implement loops in the simplest way Again, optimizations are possible, but for now go for conformance. Signed-off-by: Alyssa Rosenzweig Part-of: --- src/asahi/compiler/agx_compile.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/asahi/compiler/agx_compile.c b/src/asahi/compiler/agx_compile.c index 8d1f1804683..c7036c42c23 100644 --- a/src/asahi/compiler/agx_compile.c +++ b/src/asahi/compiler/agx_compile.c @@ -793,7 +793,28 @@ emit_if(agx_context *ctx, nir_if *nif) static void emit_loop(agx_context *ctx, nir_loop *nloop) { - unreachable("loops todo"); + /* We only track nesting within the innermost loop, so reset */ + ctx->loop_nesting = 0; + + /* Make room for break/continue nesting (TODO: skip if no divergent CF) */ + agx_builder _b = agx_init_builder(ctx, agx_after_block(ctx->current_block)); + agx_push_exec(&_b, 2); + + /* Emit the body */ + agx_block *start_block = emit_cf_list(ctx, &nloop->body); + + /* Fix up the nesting counter via an always true while_icmp, and branch back + * to start of loop if any lanes are active */ + _b.cursor = agx_after_block(ctx->current_block); + agx_while_icmp(&_b, agx_zero(), agx_zero(), 2, AGX_ICOND_UEQ, false); + agx_jmp_exec_any(&_b, start_block); + agx_pop_exec(&_b, 2); + + /* Update shader-db stats */ + ++ctx->loop_count; + + /* All nested control flow must have finished */ + assert(ctx->loop_nesting == 0); } static agx_block *