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 <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20833>
This commit is contained in:
Alyssa Rosenzweig 2023-01-21 12:35:11 -05:00 committed by Marge Bot
parent 231561d53a
commit 3706da1d1a
3 changed files with 24 additions and 10 deletions

View file

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

View file

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

View file

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