diff options
author | Alyssa Rosenzweig <[email protected]> | 2019-06-10 10:15:28 -0700 |
---|---|---|
committer | Alyssa Rosenzweig <[email protected]> | 2019-06-11 08:44:18 -0700 |
commit | b0396d6dda46e16ef4e3549fafc37818668697f7 (patch) | |
tree | 6041c13859d34e3bc490105247b914bdfbd61a8e | |
parent | ed1c48e91d0d43e2e796e904d6093f2474a1e00d (diff) |
panfrost/midgard: Print texture offsets
This patch identifies the two modes of offsets in a texture instruction
(immediate and register, disambiguated by the bit-once-known-as
"has_offset") and implements disassembly for both.
Signed-off-by: Alyssa Rosenzweig <[email protected]>
-rw-r--r-- | src/gallium/drivers/panfrost/midgard/disassemble.c | 68 | ||||
-rw-r--r-- | src/gallium/drivers/panfrost/midgard/midgard.h | 24 |
2 files changed, 56 insertions, 36 deletions
diff --git a/src/gallium/drivers/panfrost/midgard/disassemble.c b/src/gallium/drivers/panfrost/midgard/disassemble.c index 9e744f6b287..9796eaa2d09 100644 --- a/src/gallium/drivers/panfrost/midgard/disassemble.c +++ b/src/gallium/drivers/panfrost/midgard/disassemble.c @@ -1007,6 +1007,16 @@ print_texture_reg(bool full, bool select, bool upper) } static void +print_texture_reg_triple(unsigned triple) +{ + bool full = triple & 1; + bool select = triple & 2; + bool upper = triple & 4; + + print_texture_reg(full, select, upper); +} + +static void print_texture_format(int format) { /* Act like a modifier */ @@ -1072,9 +1082,6 @@ print_texture_word(uint32_t *word, unsigned tabs) /* Second set are modifiers which take an extra argument each */ - if (texture->has_offset) - printf(".offset"); - if (texture->bias) printf(".bias"); @@ -1093,10 +1100,35 @@ print_texture_word(uint32_t *word, unsigned tabs) print_texture_reg(/*texture->in_reg_full*/true, texture->in_reg_select, texture->in_reg_upper); print_swizzle_vec4(texture->in_reg_swizzle, false, false); - /* TODO: can offsets be full words? */ - if (texture->has_offset) { - print_texture_reg(false, texture->offset_reg_select, texture->offset_reg_upper); - printf(", "); + /* There is *always* an offset attached. Of + * course, that offset is just immediate #0 for a + * GLES call that doesn't take an offset. If there + * is a non-negative non-zero offset, this is + * specified in immediate offset mode, with the + * values in the offset_* fields as immediates. If + * this is a negative offset, we instead switch to + * a register offset mode, where the offset_* + * fields become register triplets */ + + if (texture->offset_register) { + printf(" + "); + print_texture_reg_triple(texture->offset_x); + + /* I've never seen them different than this */ + if (texture->offset_y != 2) + printf(" /* y = %d */", texture->offset_y); + + if (texture->offset_z != 1) + printf(" /* z = %d */", texture->offset_z); + + printf(","); + } else if (texture->offset_x || texture->offset_y || texture->offset_z) { + printf(" + <%d, %d, %d>, ", + texture->offset_x, + texture->offset_y, + texture->offset_z); + } else { + printf(","); } if (texture->bias) @@ -1123,28 +1155,10 @@ print_texture_word(uint32_t *word, unsigned tabs) printf("// unknown9 = 0x%x\n", texture->unknown9); } - /* Similarly, if no offset is applied, these are zero. If an offset - * -is- applied, or gradients are used, etc, these are nonzero but - * largely unknown still. */ - - if (texture->offset_unknown1 || - texture->offset_reg_select || - texture->offset_reg_upper || - texture->offset_unknown4 || - texture->offset_unknown5 || - texture->offset_unknown6 || - texture->offset_unknown7 || - texture->offset_unknown8 || - texture->offset_unknown9) { - printf("// offset_unknown1 = 0x%x\n", texture->offset_unknown1); - printf("// offset_reg_select = 0x%x\n", texture->offset_reg_select); - printf("// offset_reg_upper = 0x%x\n", texture->offset_reg_upper); + if (texture->offset_unknown4 || + texture->offset_unknown8) { printf("// offset_unknown4 = 0x%x\n", texture->offset_unknown4); - printf("// offset_unknown5 = 0x%x\n", texture->offset_unknown5); - printf("// offset_unknown6 = 0x%x\n", texture->offset_unknown6); - printf("// offset_unknown7 = 0x%x\n", texture->offset_unknown7); printf("// offset_unknown8 = 0x%x\n", texture->offset_unknown8); - printf("// offset_unknown9 = 0x%x\n", texture->offset_unknown9); } /* Don't blow up */ diff --git a/src/gallium/drivers/panfrost/midgard/midgard.h b/src/gallium/drivers/panfrost/midgard/midgard.h index 5d38f3f5483..68e969ccf9c 100644 --- a/src/gallium/drivers/panfrost/midgard/midgard.h +++ b/src/gallium/drivers/panfrost/midgard/midgard.h @@ -498,7 +498,12 @@ __attribute__((__packed__)) unsigned last : 1; unsigned format : 5; - unsigned has_offset : 1; + + /* Is a register used to specify an offset? If set, use the + * offset_reg_* fields to encode this, duplicated for each of the + * components. If clear, there is implcitly always an immediate offst + * specificed in offset_imm_* */ + unsigned offset_register : 1; /* Like in Bifrost */ unsigned filter : 1; @@ -526,17 +531,18 @@ __attribute__((__packed__)) unsigned unknownA : 4; - unsigned offset_unknown1 : 1; - unsigned offset_reg_select : 1; - unsigned offset_reg_upper : 1; + /* Each offset field is either an immediate (range 0-7) or, in the case of X, a + * register full / select / upper triplet to select the offset vector + * register in register mode. In register mode, Y=2 and Z=1 for some + * reason. The range in register mode is [-8, 7] */ + + unsigned offset_x : 3; unsigned offset_unknown4 : 1; - unsigned offset_unknown5 : 1; - unsigned offset_unknown6 : 1; - unsigned offset_unknown7 : 1; + unsigned offset_y : 3; unsigned offset_unknown8 : 1; - unsigned offset_unknown9 : 1; + unsigned offset_z : 3; - unsigned unknownB : 3; + unsigned unknownB : 1; /* Texture bias or LOD, depending on whether it is executed in a * fragment/vertex shader respectively. Compute as int(2^8 * biasf). |