From 839fff846a42e1b0aaa0d22b8a30f7a3513bbb26 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Sun, 23 May 2021 22:50:48 -0400 Subject: [PATCH] agx: Add break/continue support Following Dougall's notes closely. Signed-off-by: Alyssa Rosenzweig Part-of: --- src/asahi/compiler/agx_compile.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/asahi/compiler/agx_compile.c b/src/asahi/compiler/agx_compile.c index c7036c4..d203e3d 100644 --- a/src/asahi/compiler/agx_compile.c +++ b/src/asahi/compiler/agx_compile.c @@ -681,10 +681,40 @@ agx_emit_tex(agx_builder *b, nir_tex_instr *instr) agx_wait(b, 0); } +/* NIR loops are treated as a pair of AGX loops: + * + * do { + * do { + * ... + * } while (0); + * } while (cond); + * + * By manipulating the nesting counter (r0l), we may break out of nested loops, + * so under the model, both break and continue may be implemented as breaks, + * where break breaks out of the outer loop (2 layers) and continue breaks out + * of the inner loop (1 layer). + * + * After manipulating the nesting counter directly, pop_exec #0 must be used to + * flush the update to the execution mask. + */ + static void agx_emit_jump(agx_builder *b, nir_jump_instr *instr) { - unreachable("stub"); + assert (instr->type == nir_jump_break || instr->type == nir_jump_continue); + + /* Break out of either one or two loops */ + unsigned nestings = b->shader->loop_nesting; + + if (instr->type == nir_jump_continue) + nestings += 1; + else if (instr->type == nir_jump_break) + nestings += 2; + + /* Update the counter and flush */ + agx_index r0l = agx_register(0, false); + agx_mov_to(b, r0l, agx_immediate(nestings)); + agx_pop_exec(b, 0); } static void -- 2.7.4