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 <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18813>
This commit is contained in:
Alyssa Rosenzweig
2022-09-25 20:07:26 -04:00
parent 056280a4a1
commit cef13f8ab1
3 changed files with 19 additions and 7 deletions

View File

@@ -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;

View File

@@ -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 */

View File

@@ -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
};
}