summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
authorAlyssa Rosenzweig <[email protected]>2019-06-10 13:27:10 -0700
committerAlyssa Rosenzweig <[email protected]>2019-06-11 08:44:19 -0700
commit6c18ae33bc9fa6c1b2f3f75a23f3b1bc00f90e7d (patch)
treedd86e7bc7f3f7b29fedb96475b3af0b9a7399ffc /src/gallium
parent4d8157f12da54e1b9274465f68b0819deeb5e63a (diff)
panfrost/midgard: Support negative immediate offsets
It's not at all clear why this work for texelFetch but not texture. Maybe the top bits are dual-purpose on other texturing ops...? Signed-off-by: Alyssa Rosenzweig <[email protected]>
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/drivers/panfrost/midgard/disassemble.c20
-rw-r--r--src/gallium/drivers/panfrost/midgard/midgard.h16
2 files changed, 20 insertions, 16 deletions
diff --git a/src/gallium/drivers/panfrost/midgard/disassemble.c b/src/gallium/drivers/panfrost/midgard/disassemble.c
index c318a13c28c..bf8de2a2b61 100644
--- a/src/gallium/drivers/panfrost/midgard/disassemble.c
+++ b/src/gallium/drivers/panfrost/midgard/disassemble.c
@@ -1131,6 +1131,18 @@ print_texture_word(uint32_t *word, unsigned tabs)
printf(", ");
} else if (texture->offset_x || texture->offset_y || texture->offset_z) {
+ /* Only select ops allow negative immediate offsets, verify */
+
+ bool neg_x = texture->offset_x < 0;
+ bool neg_y = texture->offset_y < 0;
+ bool neg_z = texture->offset_z < 0;
+ bool any_neg = neg_x || neg_y || neg_z;
+
+ if (any_neg && texture->op != TEXTURE_OP_TEXEL_FETCH)
+ printf("/* invalid negative */ ");
+
+ /* Regardless, just print the immediate offset */
+
printf(" + <%d, %d, %d>, ",
texture->offset_x,
texture->offset_y,
@@ -1171,22 +1183,14 @@ print_texture_word(uint32_t *word, unsigned tabs)
texture->unknown3 ||
texture->unknown4 ||
texture->unknownA ||
- texture->unknownB ||
texture->unknown8) {
printf("// unknown2 = 0x%x\n", texture->unknown2);
printf("// unknown3 = 0x%x\n", texture->unknown3);
printf("// unknown4 = 0x%x\n", texture->unknown4);
printf("// unknownA = 0x%x\n", texture->unknownA);
- printf("// unknownB = 0x%x\n", texture->unknownB);
printf("// unknown8 = 0x%x\n", texture->unknown8);
}
- if (texture->offset_unknown4 ||
- texture->offset_unknown8) {
- printf("// offset_unknown4 = 0x%x\n", texture->offset_unknown4);
- printf("// offset_unknown8 = 0x%x\n", texture->offset_unknown8);
- }
-
/* Don't blow up */
if (texture->unknown7 != 0x1)
printf("// (!) unknown7 = %d\n", texture->unknown7);
diff --git a/src/gallium/drivers/panfrost/midgard/midgard.h b/src/gallium/drivers/panfrost/midgard/midgard.h
index 841f6e5241b..c9306230872 100644
--- a/src/gallium/drivers/panfrost/midgard/midgard.h
+++ b/src/gallium/drivers/panfrost/midgard/midgard.h
@@ -561,15 +561,15 @@ __attribute__((__packed__))
/* 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_y : 3;
- unsigned offset_unknown8 : 1;
- unsigned offset_z : 3;
+ * reason. The range in register mode is [-8, 7].
+ *
+ * In immediate mode, for texel fethces the range is the full [-8, 7],
+ * but for normal texturing the top bit must be zero and a register
+ * used instead. It's not clear where this limitated is from. */
- unsigned unknownB : 1;
+ signed offset_x : 4;
+ signed offset_y : 4;
+ signed offset_z : 4;
/* Texture bias or LOD, depending on whether it is executed in a
* fragment/vertex shader respectively. Compute as int(2^8 * biasf).