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 <alyssa.rosenzweig@collabora.com>
This commit is contained in:
Alyssa Rosenzweig 2019-06-10 10:15:28 -07:00
parent ed1c48e91d
commit b0396d6dda
2 changed files with 58 additions and 38 deletions

View file

@ -1006,6 +1006,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)
{
@ -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 */

View file

@ -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;
unsigned offset_unknown4 : 1;
unsigned offset_unknown5 : 1;
unsigned offset_unknown6 : 1;
unsigned offset_unknown7 : 1;
unsigned offset_unknown8 : 1;
unsigned offset_unknown9 : 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 unknownB : 3;
unsigned offset_x : 3;
unsigned offset_unknown4 : 1;
unsigned offset_y : 3;
unsigned offset_unknown8 : 1;
unsigned offset_z : 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).