From 3706da1d1a493504f18d28ae9893e94eedf42f07 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Sat, 21 Jan 2023 12:35:11 -0500 Subject: [PATCH] agx: Support uniform registers as LODs This will avoid regressing moves when we lower sampler LOD bias. Corresponding disassembler change: https://github.com/dougallj/applegpu/pull/22 Signed-off-by: Alyssa Rosenzweig Part-of: --- src/asahi/compiler/agx_compiler.h | 2 ++ src/asahi/compiler/agx_optimizer.c | 5 +++-- src/asahi/compiler/agx_pack.c | 27 +++++++++++++++++++-------- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/asahi/compiler/agx_compiler.h b/src/asahi/compiler/agx_compiler.h index 496c136f64d..dbebfe3ea5d 100644 --- a/src/asahi/compiler/agx_compiler.h +++ b/src/asahi/compiler/agx_compiler.h @@ -274,6 +274,8 @@ enum agx_convert { enum agx_lod_mode { AGX_LOD_MODE_AUTO_LOD = 0, + AGX_LOD_MODE_AUTO_LOD_BIAS_UNIFORM = 1, + AGX_LOD_MODE_LOD_MIN_UNIFORM = 2, AGX_LOD_MODE_AUTO_LOD_BIAS = 5, AGX_LOD_MODE_LOD_MIN = 6, AGX_LOD_MODE_LOD_GRAD = 4, diff --git a/src/asahi/compiler/agx_optimizer.c b/src/asahi/compiler/agx_optimizer.c index 6f5a23fd9da..7e30475beb6 100644 --- a/src/asahi/compiler/agx_optimizer.c +++ b/src/asahi/compiler/agx_optimizer.c @@ -192,8 +192,9 @@ agx_optimizer_copyprop(agx_instr **defs, agx_instr *I) * low-half of the uniform file. */ if (def->src[0].type == AGX_INDEX_UNIFORM && - (I->op == AGX_OPCODE_TEXTURE_LOAD || - I->op == AGX_OPCODE_TEXTURE_SAMPLE || + (((I->op == AGX_OPCODE_TEXTURE_LOAD || + I->op == AGX_OPCODE_TEXTURE_SAMPLE) && + s != 1) || (I->op == AGX_OPCODE_DEVICE_LOAD && (s != 0 || def->src[0].value >= 256)) || (I->op == AGX_OPCODE_DEVICE_STORE && diff --git a/src/asahi/compiler/agx_pack.c b/src/asahi/compiler/agx_pack.c index 2272ea40dc5..29fa12d29d0 100644 --- a/src/asahi/compiler/agx_pack.c +++ b/src/asahi/compiler/agx_pack.c @@ -94,15 +94,25 @@ agx_pack_sample_compare_offset(agx_index index) } static unsigned -agx_pack_lod(agx_index index) +agx_pack_lod(agx_index index, unsigned *lod_mode) { - /* Immediate zero */ - if (index.type == AGX_INDEX_IMMEDIATE && index.value == 0) + /* For automatic LOD, the LOD field is unused. Assert as much. */ + if ((*lod_mode) == AGX_LOD_MODE_AUTO_LOD) { + assert(index.type == AGX_INDEX_IMMEDIATE); + assert(index.value == 0); return 0; + } - /* Otherwise must be registers. Type implicitly specified by LOD mode. */ - assert(index.type == AGX_INDEX_REGISTER); - assert(index.value < 0x100); + if (index.type == AGX_INDEX_UNIFORM) { + /* Translate LOD mode from register mode to uniform mode */ + assert(((*lod_mode) & BITFIELD_BIT(2)) && "must start as reg mode"); + *lod_mode = (*lod_mode) & ~BITFIELD_BIT(2); + assert(index.value < 0x200); + } else { + /* Otherwise must be registers */ + assert(index.type == AGX_INDEX_REGISTER); + assert(index.value < 0x100); + } return index.value; } @@ -577,13 +587,14 @@ agx_pack_instr(struct util_dynarray *emission, struct util_dynarray *fixups, bool Rt, Ct, St; unsigned Tt; + enum agx_lod_mode lod_mode = I->lod_mode; unsigned R = agx_pack_memory_reg(I->dest[0], &Rt); unsigned C = agx_pack_sample_coords(I->src[0], &Ct); unsigned T = agx_pack_texture(I->src[2], &Tt); unsigned S = agx_pack_sampler(I->src[3], &St); unsigned O = agx_pack_sample_compare_offset(I->src[4]); - unsigned D = agx_pack_lod(I->src[1]); + unsigned D = agx_pack_lod(I->src[1], &lod_mode); unsigned U = 0; // TODO: what is sampler ureg? unsigned q1 = I->shadow; @@ -609,7 +620,7 @@ agx_pack_instr(struct util_dynarray *emission, struct util_dynarray *fixups, (((uint64_t)Tt) << 38) | (((uint64_t)(I->dim & BITFIELD_MASK(3))) << 40) | (((uint64_t)q3) << 43) | (((uint64_t)I->mask) << 48) | - (((uint64_t)I->lod_mode) << 52) | + (((uint64_t)lod_mode) << 52) | (((uint64_t)(S & BITFIELD_MASK(6))) << 56) | (((uint64_t)St) << 62) | (((uint64_t)I->scoreboard) << 63);