panfrost/midgard: Support negative immediate offsets
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Mon, 10 Jun 2019 20:27:10 +0000 (13:27 -0700)
committerAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Tue, 11 Jun 2019 15:44:19 +0000 (08:44 -0700)
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 <alyssa.rosenzweig@collabora.com>
src/gallium/drivers/panfrost/midgard/disassemble.c
src/gallium/drivers/panfrost/midgard/midgard.h

index c318a13..bf8de2a 100644 (file)
@@ -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);
index 841f6e5..c930623 100644 (file)
@@ -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).