From cef13f8ab19a6261b9fa5065864fbb9ceecdbf7d Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Sun, 25 Sep 2022 20:07:26 -0400 Subject: [PATCH] agx: Handle uniforms passed to COLLECT It's useful to be able to copyprop uniform registers into COLLECT. That requires handling of uniform registers in the parallel copy lowering, which isn't too hard to add. Signed-off-by: Alyssa Rosenzweig Part-of: --- src/asahi/compiler/agx_compiler.h | 3 ++- src/asahi/compiler/agx_lower_parallel_copy.c | 18 +++++++++++++----- src/asahi/compiler/agx_register_allocate.c | 5 ++++- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/asahi/compiler/agx_compiler.h b/src/asahi/compiler/agx_compiler.h index f676002d8a5..f04fcc6f187 100644 --- a/src/asahi/compiler/agx_compiler.h +++ b/src/asahi/compiler/agx_compiler.h @@ -769,8 +769,9 @@ struct agx_copy { /* Base register destination of the copy */ unsigned dest; - /* Base register source of the copy */ + /* Base register source (or uniform base) of the copy */ unsigned src; + bool is_uniform; /* Size of the copy */ enum agx_size size; diff --git a/src/asahi/compiler/agx_lower_parallel_copy.c b/src/asahi/compiler/agx_lower_parallel_copy.c index dab85ed95ad..1300cdb0a50 100644 --- a/src/asahi/compiler/agx_lower_parallel_copy.c +++ b/src/asahi/compiler/agx_lower_parallel_copy.c @@ -40,22 +40,31 @@ * We only handles register-register copies, not general agx_index sources. This * suffices for its internal use for register allocation. */ +static agx_index +copy_src(const struct agx_copy *copy) +{ + if (copy->is_uniform) + return agx_uniform(copy->src, copy->size); + else + return agx_register(copy->src, copy->size); +} static void do_copy(agx_builder *b, const struct agx_copy *copy) { - agx_mov_to(b, agx_register(copy->dest, copy->size), - agx_register(copy->src, copy->size)); + agx_mov_to(b, agx_register(copy->dest, copy->size), copy_src(copy)); } static void do_swap(agx_builder *b, const struct agx_copy *copy) { + assert(!copy->is_uniform && "cannot swap uniform with GPR"); + if (copy->dest == copy->src) return; agx_index x = agx_register(copy->dest, copy->size); - agx_index y = agx_register(copy->src, copy->size); + agx_index y = copy_src(copy); agx_xor_to(b, x, x, y); agx_xor_to(b, y, x, y); @@ -92,8 +101,7 @@ entry_blocked(struct agx_copy *entry, struct copy_ctx *ctx) static bool is_real(struct agx_copy *entry) { - /* TODO: Allow immediates in agx_copy */ - return true; + return !entry->is_uniform; } /* TODO: Generalize to other bit sizes */ diff --git a/src/asahi/compiler/agx_register_allocate.c b/src/asahi/compiler/agx_register_allocate.c index 7d318b1ef59..b18b05a8122 100644 --- a/src/asahi/compiler/agx_register_allocate.c +++ b/src/asahi/compiler/agx_register_allocate.c @@ -382,9 +382,12 @@ agx_ra(agx_context *ctx) if (agx_is_null(ins->src[i])) continue; assert(ins->src[i].size == ins->dest[0].size); + bool is_uniform = ins->src[i].type == AGX_INDEX_UNIFORM; + copies[n++] = (struct agx_copy) { .dest = base + (i * width), - .src = agx_index_to_reg(ssa_to_reg, ins->src[i]) , + .is_uniform = is_uniform, + .src = is_uniform ? ins->src[i].value : agx_index_to_reg(ssa_to_reg, ins->src[i]), .size = ins->src[i].size }; }