pan/decode: Use GLSL style formats/swizzles
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Tue, 20 Aug 2019 21:34:09 +0000 (14:34 -0700)
committerAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Wed, 21 Aug 2019 15:40:54 +0000 (08:40 -0700)
This dramatically reduces visual clutter: now an entire
attribute/varying record looks something like:

    rgba32f attribute_0[16].bgra;

which is equivalent to the raw structure:

{
   .index = 0,
   .format = MALI_FORMAT_RGBA32F,
   .swizzle = (MALI_CHANNEL_BLUE << 9) | ....,
   .src_offset = 16,
}

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
src/panfrost/pandecode/decode.c
src/panfrost/pandecode/pan_pretty_print.c

index 95f3d25fc01ef626a2832e9161d27344e009e093..11de8494e235c8d3ccef2980bccd868c315edae6 100644 (file)
@@ -29,6 +29,7 @@
 #include <memory.h>
 #include <stdbool.h>
 #include <stdarg.h>
+#include <ctype.h>
 #include "decode.h"
 #include "util/macros.h"
 #include "util/u_math.h"
@@ -431,25 +432,6 @@ static char *pandecode_attr_mode(enum mali_attr_mode mode)
 
 #undef DEFINE_CASE
 
-#define DEFINE_CASE(name) case MALI_CHANNEL_## name: return "MALI_CHANNEL_" #name
-static char *
-pandecode_channel(enum mali_channel channel)
-{
-        switch (channel) {
-                DEFINE_CASE(RED);
-                DEFINE_CASE(GREEN);
-                DEFINE_CASE(BLUE);
-                DEFINE_CASE(ALPHA);
-                DEFINE_CASE(ZERO);
-                DEFINE_CASE(ONE);
-
-        default:
-                pandecode_msg("XXX: invalid channel %X\n", channel);
-                return "";
-        }
-}
-#undef DEFINE_CASE
-
 #define DEFINE_CASE(name) case MALI_WRAP_## name: return "MALI_WRAP_" #name
 static char *
 pandecode_wrap_mode(enum mali_wrap_mode op)
@@ -753,14 +735,118 @@ pandecode_compute_fbd(uint64_t gpu_va, int job_no)
         printf("},\n");
 }
 
+/* Extracts the number of components associated with a Mali format */
+
+static unsigned
+pandecode_format_component_count(enum mali_format fmt)
+{
+        /* Mask out the format class */
+        unsigned top = fmt & 0b11100000;
+
+        switch (top) {
+        case MALI_FORMAT_SNORM:
+        case MALI_FORMAT_UINT:
+        case MALI_FORMAT_UNORM:
+        case MALI_FORMAT_SINT:
+                return ((fmt >> 3) & 3) + 1;
+        default:
+                /* TODO: Validate */
+                return 4;
+        }
+}
+
+/* Extracts a mask of accessed components from a 12-bit Mali swizzle */
+
+static unsigned
+pandecode_access_mask_from_channel_swizzle(unsigned swizzle)
+{
+        unsigned mask = 0;
+        assert(MALI_CHANNEL_RED == 0);
+
+        for (unsigned c = 0; c < 4; ++c) {
+                enum mali_channel chan = (swizzle >> (3*c)) & 0x7;
+
+                if (chan <= MALI_CHANNEL_ALPHA)
+                        mask |= (1 << chan);
+        }
+
+        return mask;
+}
+
+/* Validates that a (format, swizzle) pair is valid, in the sense that the
+ * swizzle doesn't access any components that are undefined in the format.
+ * Returns whether the swizzle is trivial (doesn't do any swizzling) and can be
+ * omitted */
+
+static bool
+pandecode_validate_format_swizzle(enum mali_format fmt, unsigned swizzle)
+{
+        unsigned nr_comp = pandecode_format_component_count(fmt);
+        unsigned access_mask = pandecode_access_mask_from_channel_swizzle(swizzle);
+        unsigned valid_mask = (1 << nr_comp) - 1;
+        unsigned invalid_mask = ~valid_mask;
+
+        if (access_mask & invalid_mask) {
+                pandecode_msg("XXX: invalid components accessed\n");
+                return false;
+        }
+
+        /* Check for the default non-swizzling swizzle so we can suppress
+         * useless printing for the defaults */
+
+        unsigned default_swizzles[4] = {
+                MALI_CHANNEL_RED | (MALI_CHANNEL_ZERO  << 3) | (MALI_CHANNEL_ZERO << 6) | (MALI_CHANNEL_ONE   << 9),
+                MALI_CHANNEL_RED | (MALI_CHANNEL_GREEN << 3) | (MALI_CHANNEL_ZERO << 6) | (MALI_CHANNEL_ONE   << 9),
+                MALI_CHANNEL_RED | (MALI_CHANNEL_GREEN << 3) | (MALI_CHANNEL_BLUE << 6) | (MALI_CHANNEL_ONE   << 9),
+                MALI_CHANNEL_RED | (MALI_CHANNEL_GREEN << 3) | (MALI_CHANNEL_BLUE << 6) | (MALI_CHANNEL_ALPHA << 9)
+        };
+
+        return (swizzle == default_swizzles[nr_comp - 1]);
+}
+
+/* Maps MALI_RGBA32F to rgba32f, etc */
+
 static void
-pandecode_swizzle(unsigned swizzle)
+pandecode_format_short(enum mali_format fmt)
 {
-        pandecode_prop("swizzle = %s | (%s << 3) | (%s << 6) | (%s << 9)",
-                       pandecode_channel((swizzle >> 0) & 0x7),
-                       pandecode_channel((swizzle >> 3) & 0x7),
-                       pandecode_channel((swizzle >> 6) & 0x7),
-                       pandecode_channel((swizzle >> 9) & 0x7));
+        /* We want a type-like format, so cut off the initial MALI_ */
+        char *format = pandecode_format(fmt);
+        format += strlen("MALI_");
+
+        unsigned len = strlen(format);
+        char *lower_format = calloc(1, len + 1);
+
+        for (unsigned i = 0; i < len; ++i)
+                lower_format[i] = tolower(format[i]);
+
+        pandecode_log_cont("%s", lower_format);
+        free(lower_format);
+}
+
+static void
+pandecode_swizzle(unsigned swizzle, enum mali_format format)
+{
+        /* First, do some validation */
+        bool trivial_swizzle = pandecode_validate_format_swizzle(
+                        format, swizzle);
+
+        if (trivial_swizzle)
+                return;
+
+        /* Next, print the swizzle */
+        pandecode_log_cont(".");
+
+        static const char components[] = "rgba01";
+
+        for (unsigned c = 0; c < 4; ++c) {
+                enum mali_channel chan = (swizzle >> (3 * c)) & 0x7;
+
+                if (chan >= MALI_CHANNEL_RESERVED_0) {
+                        pandecode_log("XXX: invalid swizzle channel %d\n", chan);
+                        continue;
+                }
+                pandecode_log_cont("%c", components[chan]);
+        }
 }
 
 static void
@@ -776,6 +862,11 @@ pandecode_rt_format(struct mali_rt_format format)
         pandecode_prop("block = %s",
                        pandecode_mfbd_block_format(format.block));
 
+        /* TODO: Map formats so we can check swizzles and print nicely */
+        pandecode_log("swizzle");
+        pandecode_swizzle(format.swizzle, MALI_RGBA8_UNORM);
+        pandecode_log_cont(",\n");
+
         pandecode_prop("nr_channels = MALI_POSITIVE(%d)",
                        MALI_NEGATIVE(format.nr_channels));
 
@@ -783,8 +874,6 @@ pandecode_rt_format(struct mali_rt_format format)
         pandecode_log_decoded_flags(mfbd_fmt_flag_info, format.flags);
         pandecode_log_cont(",\n");
 
-        pandecode_swizzle(format.swizzle);
-
         /* In theory, the no_preload bit can be cleared to enable MFBD preload,
          * which is a faster hardware-based alternative to the wallpaper method
          * to preserve framebuffer contents across frames. In practice, MFBD
@@ -1370,75 +1459,6 @@ pandecode_midgard_blend_mrt(void *descs, int job_no, int rt_no)
  * want to validate that the combinations specified are self-consistent.
  */
 
-/* Extracts the number of components associated with a Mali format */
-
-static unsigned
-pandecode_format_component_count(enum mali_format fmt)
-{
-        /* Mask out the format class */
-        unsigned top = fmt & 0b11100000;
-
-        switch (top) {
-        case MALI_FORMAT_SNORM:
-        case MALI_FORMAT_UINT:
-        case MALI_FORMAT_UNORM:
-        case MALI_FORMAT_SINT:
-                return ((fmt >> 3) & 3) + 1;
-        default:
-                /* TODO: Validate */
-                return 4;
-        }
-}
-
-/* Extracts a mask of accessed components from a 12-bit Mali swizzle */
-
-static unsigned
-pandecode_access_mask_from_channel_swizzle(unsigned swizzle)
-{
-        unsigned mask = 0;
-        assert(MALI_CHANNEL_RED == 0);
-
-        for (unsigned c = 0; c < 4; ++c) {
-                enum mali_channel chan = (swizzle >> (3*c)) & 0x7;
-
-                if (chan <= MALI_CHANNEL_ALPHA)
-                        mask |= (1 << chan);
-        }
-
-        return mask;
-}
-
-/* Validates that a (format, swizzle) pair is valid, in the sense that the
- * swizzle doesn't access any components that are undefined in the format.
- * Returns whether the swizzle is trivial (doesn't do any swizzling) and can be
- * omitted */
-
-static bool
-pandecode_validate_format_swizzle(enum mali_format fmt, unsigned swizzle)
-{
-        unsigned nr_comp = pandecode_format_component_count(fmt);
-        unsigned access_mask = pandecode_access_mask_from_channel_swizzle(swizzle);
-        unsigned valid_mask = (1 << nr_comp) - 1;
-        unsigned invalid_mask = ~valid_mask;
-
-        if (access_mask & invalid_mask) {
-                pandecode_msg("XXX: invalid components accessed\n");
-                return false;
-        }
-
-        /* Check for the default non-swizzling swizzle so we can suppress
-         * useless printing for the defaults */
-
-        unsigned default_swizzles[4] = {
-                MALI_CHANNEL_RED | (MALI_CHANNEL_ZERO  << 3) | (MALI_CHANNEL_ZERO << 6) | (MALI_CHANNEL_ONE   << 9),
-                MALI_CHANNEL_RED | (MALI_CHANNEL_GREEN << 3) | (MALI_CHANNEL_ZERO << 6) | (MALI_CHANNEL_ONE   << 9),
-                MALI_CHANNEL_RED | (MALI_CHANNEL_GREEN << 3) | (MALI_CHANNEL_BLUE << 6) | (MALI_CHANNEL_ONE   << 9),
-                MALI_CHANNEL_RED | (MALI_CHANNEL_GREEN << 3) | (MALI_CHANNEL_BLUE << 6) | (MALI_CHANNEL_ALPHA << 9)
-        };
-
-        return (swizzle == default_swizzles[nr_comp - 1]);
-}
-
 static int
 pandecode_attribute_meta(int job_no, int count, const struct mali_vertex_tiler_postfix *v, bool varying, char *suffix)
 {
@@ -1491,25 +1511,9 @@ pandecode_attribute_meta(int job_no, int count, const struct mali_vertex_tiler_p
                         }
                 }
 
-                pandecode_log("{\n");
-                pandecode_indent++;
-                pandecode_prop("index = %d", attr_meta->index);
-
                 if (attr_meta->index > max_index)
                         max_index = attr_meta->index;
 
-                /* Check the swizzle/format, and if they match and the swizzle
-                 * is simple enough, we can avoid printing the swizzle since
-                 * it's just noise */
-
-                bool trivial_swizzle = pandecode_validate_format_swizzle(
-                                attr_meta->format, attr_meta->swizzle);
-
-                if (!trivial_swizzle)
-                        pandecode_swizzle(attr_meta->swizzle);
-
-                pandecode_prop("format = %s", pandecode_format(attr_meta->format));
-
                 if (attr_meta->unknown1 != 0x2) {
                         pandecode_msg("XXX: expected unknown1 = 0x2\n");
                         pandecode_prop("unknown1 = 0x%" PRIx64, (u64) attr_meta->unknown1);
@@ -1520,10 +1524,16 @@ pandecode_attribute_meta(int job_no, int count, const struct mali_vertex_tiler_p
                         pandecode_prop("unknown3 = 0x%" PRIx64, (u64) attr_meta->unknown3);
                 }
 
-                pandecode_prop("src_offset = %d", attr_meta->src_offset);
-                pandecode_indent--;
-                pandecode_log("},\n");
+                pandecode_make_indent();
+                pandecode_format_short(attr_meta->format);
+                pandecode_log_cont(" %s_%u", prefix, attr_meta->index);
+
+                if (attr_meta->src_offset)
+                        pandecode_log_cont("[%u]", attr_meta->src_offset);
+
+                pandecode_swizzle(attr_meta->swizzle, attr_meta->format);
 
+                pandecode_log_cont(";\n");
         }
 
         pandecode_indent--;
@@ -2038,8 +2048,11 @@ pandecode_vertex_tiler_postfix_pre(const struct mali_vertex_tiler_postfix *p,
                                         pandecode_log(".format = {\n");
                                         pandecode_indent++;
 
-                                        pandecode_swizzle(f.swizzle);
-                                        pandecode_prop("format = %s", pandecode_format(f.format));
+                                        pandecode_log(".format = ");
+                                        pandecode_format_short(f.format);
+                                        pandecode_swizzle(f.swizzle, f.format);
+                                        pandecode_log_cont(",\n");
+
                                         pandecode_prop("type = %s", pandecode_texture_type(f.type));
                                         pandecode_prop("srgb = %" PRId32, f.srgb);
                                         pandecode_prop("unknown1 = %" PRId32, f.unknown1);
@@ -2048,8 +2061,6 @@ pandecode_vertex_tiler_postfix_pre(const struct mali_vertex_tiler_postfix *p,
                                         pandecode_indent--;
                                         pandecode_log("},\n");
 
-                                        pandecode_swizzle(t->swizzle);
-
                                         if (t->swizzle_zero) {
                                                 /* Shouldn't happen */
                                                 pandecode_msg("XXX: swizzle zero tripped\n");
index 455bc432a9449eca7803aa61c6c589db6bb9f03d..0f4183c48401853fc45543e04f6992f87134dcb4 100644 (file)
@@ -33,7 +33,7 @@
 #define DEFINE_CASE(name) case MALI_## name: return "MALI_" #name
 char *pandecode_format(enum mali_format format)
 {
-        static char unk_format_str[5];
+        static char unk_format_str[10];
 
         switch (format) {
                 DEFINE_CASE(RGB565);
@@ -118,7 +118,7 @@ char *pandecode_format(enum mali_format format)
                 DEFINE_CASE(RGBA8_2);
                 DEFINE_CASE(RGB10_A2_2);
         default:
-                snprintf(unk_format_str, sizeof(unk_format_str), "0x%02x", format);
+                snprintf(unk_format_str, sizeof(unk_format_str), "MALI_0x%02x", format);
                 return unk_format_str;
         }
 }