panfrost/midgard: Decode LOD/bias registers
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Tue, 11 Jun 2019 14:41:09 +0000 (07:41 -0700)
committerAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Tue, 11 Jun 2019 15:44:19 +0000 (08:44 -0700)
For constant LODs/biases, we can use an immediate embedded in the
texture (already decoded); for non-constant, we have to use a register
squeezed into the usual immediate field, which is decoded here.

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
src/gallium/drivers/panfrost/midgard/disassemble.c
src/gallium/drivers/panfrost/midgard/midgard.h

index f1139f40b2734f60f57608f71909d3618e1159c8..501846fab1c7e03edfdadf1bb9c57084f67a812d 100644 (file)
@@ -1175,9 +1175,27 @@ print_texture_word(uint32_t *word, unsigned tabs)
                 printf(", ");
         }
 
+        char lod_operand = texture_op_takes_bias(texture->op) ? '+' : '=';
+
         if (texture->lod_register) {
-                /* TODO: Decode */
-                printf("lod/bias/grad reg 0x%X (%X), ", texture->bias, texture->bias_int);
+                midgard_tex_register_select sel;
+                uint8_t raw = texture->bias;
+                memcpy(&sel, &raw, sizeof(raw));
+
+                unsigned c = (sel.component_hi << 1) | sel.component_lo;
+
+                printf("lod %c ", lod_operand);
+                print_texture_reg(sel.full, sel.select, sel.upper);
+                printf(".%c, ", components[c]);
+
+                if (!sel.component_hi)
+                        printf(" /* gradient? */");
+
+                if (texture->bias_int)
+                        printf(" /* bias_int = 0x%X */", texture->bias_int);
+
+                if (sel.zero)
+                        printf(" /* sel.zero = 0x%X */", sel.zero);
         } else if (texture->op == TEXTURE_OP_TEXEL_FETCH) {
                 /* For texel fetch, the int LOD is in the fractional place and
                  * there is no fraction / possibility of bias. We *always* have
index 532734820e945876e8fa0ec4649f7ffcc24098f8..79933973b2522c0fcc678b5dc668fc7098690738 100644 (file)
@@ -489,6 +489,37 @@ __attribute__((__packed__))
 }
 midgard_load_store;
 
+/* 8-bit register selector used in texture ops to select a bias/LOD/gradient
+ * register, shoved into the `bias` field */
+
+typedef struct
+__attribute__((__packed__))
+{
+        /* Combines with component_hi to form 2-bit component select out of
+         * xyzw, as the component for bias/LOD and the starting component of a
+         * gradient vector */
+
+        unsigned component_lo : 1;
+
+        /* Register select between r28/r29 */
+        unsigned select : 1;
+
+        /* For a half-register, selects the upper half */
+        unsigned upper : 1;
+
+        /* Specifies a full-register, clear for a half-register. Mutually
+         * exclusive with upper. */
+        unsigned full : 1;
+
+        /* Higher half of component_lo. Always seen to be set for LOD/bias
+         * and clear for processed gradients, but I'm not sure if that's a
+         * hardware requirement. */
+        unsigned component_hi : 1;
+
+        /* Padding to make this 8-bit */
+        unsigned zero : 3;
+} midgard_tex_register_select;
+
 /* Texture pipeline results are in r28-r29 */
 #define REG_TEX_BASE 28
 
@@ -572,10 +603,14 @@ __attribute__((__packed__))
         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).
+        /* In immediate bias mode, for a normal texture op, this is
+         * texture bias, computed as int(2^8 * frac(biasf)), with
+         * bias_int = floor(bias). For a textureLod, it's that, but
+         * s/bias/lod. For a texel fetch, this is the LOD as-is.
          *
-         * For texel fetch, this is the LOD as is. */
+         * In register mode, this is a midgard_tex_register_select
+         * structure and bias_int is zero */
+
         unsigned bias : 8;
         unsigned bias_int  : 8;