pan/mdg: Refactor texture op/mode handling
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Fri, 28 Aug 2020 12:35:19 +0000 (08:35 -0400)
committerAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Mon, 31 Aug 2020 11:46:32 +0000 (07:46 -0400)
We reduce the op to 4-bits, such that the derivative mode becomes its
own adjacent parameter. This cleans up handling of texture gathers, but
does not affect functionality.

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6516>

src/panfrost/midgard/disassemble.c
src/panfrost/midgard/helpers.h
src/panfrost/midgard/midgard.h
src/panfrost/midgard/midgard_compile.c
src/panfrost/midgard/midgard_derivatives.c

index ac5179edd35fd4a96575e7d6658befa2eae8677b..5568fa03663f8e7998def57e4563faf58eddca03 100644 (file)
@@ -1293,15 +1293,11 @@ print_texture_format(FILE *fp, int format)
 }
 
 static bool
-midgard_op_has_helpers(unsigned op, bool gather)
+midgard_op_has_helpers(unsigned op)
 {
-        if (gather)
-                return true;
-
         switch (op) {
         case TEXTURE_OP_NORMAL:
-        case TEXTURE_OP_DFDX:
-        case TEXTURE_OP_DFDY:
+        case TEXTURE_OP_DERIVATIVE:
                 return true;
         default:
                 return false;
@@ -1309,30 +1305,14 @@ midgard_op_has_helpers(unsigned op, bool gather)
 }
 
 static void
-print_texture_op(FILE *fp, unsigned op, bool gather)
+print_texture_op(FILE *fp, unsigned op)
 {
-        /* Act like a bare name, like ESSL functions */
-
-        if (gather) {
-                fprintf(fp, "textureGather");
-
-                unsigned component = op >> 4;
-                unsigned bottom = op & 0xF;
-
-                if (bottom != 0x2)
-                        fprintf(fp, "_unk%u", bottom);
-
-                fprintf(fp, ".%c", components[component]);
-                return;
-        }
-
         switch (op) {
                 DEFINE_CASE(TEXTURE_OP_NORMAL, "texture");
                 DEFINE_CASE(TEXTURE_OP_LOD, "textureLod");
                 DEFINE_CASE(TEXTURE_OP_TEXEL_FETCH, "texelFetch");
                 DEFINE_CASE(TEXTURE_OP_BARRIER, "barrier");
-                DEFINE_CASE(TEXTURE_OP_DFDX, "dFdx");
-                DEFINE_CASE(TEXTURE_OP_DFDY, "dFdy");
+                DEFINE_CASE(TEXTURE_OP_DERIVATIVE, "derivative");
 
         default:
                 fprintf(fp, "tex_%X", op);
@@ -1399,16 +1379,38 @@ print_texture_barrier(FILE *fp, uint32_t *word)
 
 #undef DEFINE_CASE
 
+static const char *
+texture_mode(enum mali_texture_mode mode)
+{
+        switch (mode) {
+        case TEXTURE_NORMAL: return "";
+        case TEXTURE_SHADOW: return ".shadow";
+        case TEXTURE_GATHER_X: return ".gatherX";
+        case TEXTURE_GATHER_Y: return ".gatherY";
+        case TEXTURE_GATHER_Z: return ".gatherZ";
+        case TEXTURE_GATHER_W: return ".gatherW";
+        default: return "unk";
+        }
+}
+
+static const char *
+derivative_mode(enum mali_derivative_mode mode)
+{
+        switch (mode) {
+        case TEXTURE_DFDX: return ".x";
+        case TEXTURE_DFDY: return ".y";
+        default: return "unk";
+        }
+}
+
 static void
 print_texture_word(FILE *fp, uint32_t *word, unsigned tabs, unsigned in_reg_base, unsigned out_reg_base)
 {
         midgard_texture_word *texture = (midgard_texture_word *) word;
-
-        midg_stats.helper_invocations |=
-                midgard_op_has_helpers(texture->op, texture->is_gather);
+        midg_stats.helper_invocations |= midgard_op_has_helpers(texture->op);
 
         /* Broad category of texture operation in question */
-        print_texture_op(fp, texture->op, texture->is_gather);
+        print_texture_op(fp, texture->op);
 
         /* Barriers use a dramatically different code path */
         if (texture->op == TEXTURE_OP_BARRIER) {
@@ -1419,14 +1421,16 @@ print_texture_word(FILE *fp, uint32_t *word, unsigned tabs, unsigned in_reg_base
         else if (texture->type == TAG_TEXTURE_4_VTX)
                 fprintf (fp, ".vtx");
 
+        if (texture->op == TEXTURE_OP_DERIVATIVE)
+                fprintf(fp, "%s", derivative_mode(texture->mode));
+        else
+                fprintf(fp, "%s", texture_mode(texture->mode));
+
         /* Specific format in question */
         print_texture_format(fp, texture->format);
 
         /* Instruction "modifiers" parallel the ALU instructions. */
 
-        if (texture->shadow)
-                fprintf(fp, ".shadow");
-
         if (texture->cont)
                 fprintf(fp, ".cont");
 
index 73f82a5aaaf241c8a5df4739718d783baa256947..e0a595c2c3d02d8d29f284fddb497565d5e51fd7 100644 (file)
                 op == midgard_alu_op_fcsel \
         )
 
-#define OP_IS_DERIVATIVE(op) ( \
-                op == TEXTURE_OP_DFDX || \
-                op == TEXTURE_OP_DFDY \
-        )
-
 #define OP_IS_UNSIGNED_CMP(op) ( \
                 op == midgard_alu_op_ult || \
                 op == midgard_alu_op_ule \
index 7d9e7e136143d7b7a202da94e9f9374f1ea83f9f..6308e89e916f7e389127bbfdb30b4342448f88aa 100644 (file)
@@ -632,23 +632,13 @@ midgard_tex_register_select;
 /* Texture pipeline results are in r28-r29 */
 #define REG_TEX_BASE 28
 
-/* Texture opcodes... maybe? */
-#define TEXTURE_OP_NORMAL 0x11          /* texture */
-#define TEXTURE_OP_LOD 0x12             /* textureLod */
-#define TEXTURE_OP_TEXEL_FETCH 0x14     /* texelFetch */
-
-/* Implements barrier() */
-#define TEXTURE_OP_BARRIER 0x0B
-
-/* Computes horizontal and vertical derivatives respectively. Use with a float
- * sampler and a "2D" texture.  Leave texture/sampler IDs as zero; they ought
- * to be ignored. Only works for fp32 on 64-bit at a time, so derivatives of a
- * vec4 require 2 texture ops.  For some reason, the blob computes both X and Y
- * derivatives at the same time and just throws out whichever is unused; it's
- * not known if this is a quirk of the hardware or just of the blob. */
-
-#define TEXTURE_OP_DFDX 0x0D
-#define TEXTURE_OP_DFDY 0x1D
+enum mali_texture_op {
+        TEXTURE_OP_NORMAL = 1,  /* texture */
+        TEXTURE_OP_LOD = 2,     /* textureLod */
+        TEXTURE_OP_TEXEL_FETCH = 4,
+        TEXTURE_OP_BARRIER = 11,
+        TEXTURE_OP_DERIVATIVE = 13
+};
 
 enum mali_sampler_type {
         MALI_SAMPLER_UNK        = 0x0,
@@ -657,15 +647,29 @@ enum mali_sampler_type {
         MALI_SAMPLER_SIGNED     = 0x3, /* isampler */
 };
 
+/* Texture modes */
+enum mali_texture_mode {
+        TEXTURE_NORMAL = 1,
+        TEXTURE_SHADOW = 5,
+        TEXTURE_GATHER_X = 8,
+        TEXTURE_GATHER_Y = 9,
+        TEXTURE_GATHER_Z = 10,
+        TEXTURE_GATHER_W = 11,
+};
+
+enum mali_derivative_mode {
+        TEXTURE_DFDX = 0,
+        TEXTURE_DFDY = 1,
+};
+
 typedef struct
 __attribute__((__packed__))
 {
         unsigned type      : 4;
         unsigned next_type : 4;
 
-        unsigned op  : 6;
-        unsigned shadow    : 1;
-        unsigned is_gather  : 1;
+        enum mali_texture_op op  : 4;
+        unsigned mode : 4;
 
         /* A little obscure, but last is set for the last texture operation in
          * a shader. cont appears to just be last's opposite (?). Yeah, I know,
index 544a707453ff3895eef96d4adfade9f46ac5bbd8..5dcb9c55c748a60576f09fd7c19d2c3315b8df73 100644 (file)
@@ -2065,6 +2065,15 @@ pan_attach_constant_bias(
         return true;
 }
 
+static enum mali_texture_mode
+mdg_texture_mode(nir_tex_instr *instr)
+{
+        if (instr->is_shadow)
+                return TEXTURE_SHADOW;
+        else
+                return TEXTURE_NORMAL;
+}
+
 static void
 emit_texop_native(compiler_context *ctx, nir_tex_instr *instr,
                   unsigned midgard_texop)
@@ -2099,7 +2108,7 @@ emit_texop_native(compiler_context *ctx, nir_tex_instr *instr,
                         .format = midgard_tex_format(instr->sampler_dim),
                         .texture_handle = texture_index,
                         .sampler_handle = sampler_index,
-                        .shadow = instr->is_shadow,
+                        .mode = mdg_texture_mode(instr)
                 }
         };
 
index 29f459418e18a09cc16f85b1abcdddbdaf91b7a2..181759e2ceb176704f82093ea4d468f8321f3f82 100644 (file)
  */
 
 static unsigned
-mir_derivative_op(nir_op op)
+mir_derivative_mode(nir_op op)
 {
         switch (op) {
         case nir_op_fddx:
         case nir_op_fddx_fine:
         case nir_op_fddx_coarse:
-                return TEXTURE_OP_DFDX;
+                return TEXTURE_DFDX;
 
         case nir_op_fddy:
         case nir_op_fddy_fine:
         case nir_op_fddy_coarse:
-                return TEXTURE_OP_DFDY;
+                return TEXTURE_DFDY;
 
         default:
                 unreachable("Invalid derivative op");
@@ -82,8 +82,7 @@ mir_op_computes_derivatives(gl_shader_stage stage, unsigned op)
 
         switch (op) {
         case TEXTURE_OP_NORMAL:
-        case TEXTURE_OP_DFDX:
-        case TEXTURE_OP_DFDY:
+        case TEXTURE_OP_DERIVATIVE:
                 assert(stage == MESA_SHADER_FRAGMENT);
                 return true;
         default:
@@ -106,8 +105,9 @@ midgard_emit_derivatives(compiler_context *ctx, nir_alu_instr *instr)
                 .src = { ~0, nir_src_index(ctx, &instr->src[0].src), ~0, ~0 },
                 .swizzle = SWIZZLE_IDENTITY_4,
                 .src_types = { nir_type_float32, nir_type_float32 },
-                .op = mir_derivative_op(instr->op),
+                .op = TEXTURE_OP_DERIVATIVE,
                 .texture = {
+                        .mode = mir_derivative_mode(instr->op),
                         .format = 2,
                         .in_reg_full = 1,
                         .out_full = 1,
@@ -126,7 +126,7 @@ midgard_lower_derivatives(compiler_context *ctx, midgard_block *block)
 {
         mir_foreach_instr_in_block_safe(block, ins) {
                 if (ins->type != TAG_TEXTURE_4) continue;
-                if (!OP_IS_DERIVATIVE(ins->op)) continue;
+                if (ins->op != TEXTURE_OP_DERIVATIVE) continue;
 
                 /* Check if we need to split */