/*
 * Copyright (C) 2017-2019 Alyssa Rosenzweig
 * Copyright (C) 2017-2019 Connor Abbott
 * Copyright (C) 2019 Collabora, Ltd.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include <midgard_pack.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <stdbool.h>
#include <stdarg.h>
#include <ctype.h>
#include "decode.h"
#include "util/macros.h"
#include "util/u_math.h"

#include "midgard/disassemble.h"
#include "bifrost/disassemble.h"

#include "pan_encoder.h"

static void pandecode_swizzle(unsigned swizzle, enum mali_format format);

#define MEMORY_PROP(obj, p) {\
        if (obj->p) { \
                char *a = pointer_as_memory_reference(obj->p); \
                pandecode_prop("%s = %s", #p, a); \
                free(a); \
        } \
}

#define MEMORY_PROP_DIR(obj, p) {\
        if (obj.p) { \
                char *a = pointer_as_memory_reference(obj.p); \
                pandecode_prop("%s = %s", #p, a); \
                free(a); \
        } \
}

#define DUMP_UNPACKED(T, var, ...) { \
        pandecode_log(__VA_ARGS__); \
        pan_print(pandecode_dump_stream, T, var, (pandecode_indent + 1) * 2); \
}

#define DUMP_CL(T, cl, ...) {\
        pan_unpack(cl, T, temp); \
        DUMP_UNPACKED(T, temp, __VA_ARGS__); \
}

#define DUMP_SECTION(A, S, cl, ...) { \
        pan_section_unpack(cl, A, S, temp); \
        pandecode_log(__VA_ARGS__); \
        pan_section_print(pandecode_dump_stream, A, S, temp, (pandecode_indent + 1) * 2); \
}

#define MAP_ADDR(T, addr, cl) \
        const uint8_t *cl = 0; \
        { \
                struct pandecode_mapped_memory *mapped_mem = pandecode_find_mapped_gpu_mem_containing(addr); \
                cl = pandecode_fetch_gpu_mem(mapped_mem, addr, MALI_ ## T ## _LENGTH); \
        }

#define DUMP_ADDR(T, addr, ...) {\
        MAP_ADDR(T, addr, cl) \
        DUMP_CL(T, cl, __VA_ARGS__); \
}

FILE *pandecode_dump_stream;

/* Semantic logging type.
 *
 * Raw: for raw messages to be printed as is.
 * Message: for helpful information to be commented out in replays.
 * Property: for properties of a struct
 *
 * Use one of pandecode_log, pandecode_msg, or pandecode_prop as syntax sugar.
 */

enum pandecode_log_type {
        PANDECODE_RAW,
        PANDECODE_MESSAGE,
        PANDECODE_PROPERTY
};

#define pandecode_log(...)  pandecode_log_typed(PANDECODE_RAW,      __VA_ARGS__)
#define pandecode_msg(...)  pandecode_log_typed(PANDECODE_MESSAGE,  __VA_ARGS__)
#define pandecode_prop(...) pandecode_log_typed(PANDECODE_PROPERTY, __VA_ARGS__)

unsigned pandecode_indent = 0;

static void
pandecode_make_indent(void)
{
        for (unsigned i = 0; i < pandecode_indent; ++i)
                fprintf(pandecode_dump_stream, "  ");
}

static void
pandecode_log_typed(enum pandecode_log_type type, const char *format, ...)
{
        va_list ap;

        pandecode_make_indent();

        if (type == PANDECODE_MESSAGE)
                fprintf(pandecode_dump_stream, "// ");
        else if (type == PANDECODE_PROPERTY)
                fprintf(pandecode_dump_stream, ".");

        va_start(ap, format);
        vfprintf(pandecode_dump_stream, format, ap);
        va_end(ap);

        if (type == PANDECODE_PROPERTY)
                fprintf(pandecode_dump_stream, ",\n");
}

static void
pandecode_log_cont(const char *format, ...)
{
        va_list ap;

        va_start(ap, format);
        vfprintf(pandecode_dump_stream, format, ap);
        va_end(ap);
}

/* To check for memory safety issues, validates that the given pointer in GPU
 * memory is valid, containing at least sz bytes. The goal is to eliminate
 * GPU-side memory bugs (NULL pointer dereferences, buffer overflows, or buffer
 * overruns) by statically validating pointers.
 */

static void
pandecode_validate_buffer(mali_ptr addr, size_t sz)
{
        if (!addr) {
                pandecode_msg("XXX: null pointer deref");
                return;
        }

        /* Find a BO */

        struct pandecode_mapped_memory *bo =
                pandecode_find_mapped_gpu_mem_containing(addr);

        if (!bo) {
                pandecode_msg("XXX: invalid memory dereference\n");
                return;
        }

        /* Bounds check */

        unsigned offset = addr - bo->gpu_va;
        unsigned total = offset + sz;

        if (total > bo->length) {
                pandecode_msg("XXX: buffer overrun. "
                                "Chunk of size %zu at offset %d in buffer of size %zu. "
                                "Overrun by %zu bytes. \n",
                                sz, offset, bo->length, total - bo->length);
                return;
        }
}

struct pandecode_flag_info {
        u64 flag;
        const char *name;
};

static void
pandecode_log_decoded_flags(const struct pandecode_flag_info *flag_info,
                            u64 flags)
{
        bool decodable_flags_found = false;

        for (int i = 0; flag_info[i].name; i++) {
                if ((flags & flag_info[i].flag) != flag_info[i].flag)
                        continue;

                if (!decodable_flags_found) {
                        decodable_flags_found = true;
                } else {
                        pandecode_log_cont(" | ");
                }

                pandecode_log_cont("%s", flag_info[i].name);

                flags &= ~flag_info[i].flag;
        }

        if (decodable_flags_found) {
                if (flags)
                        pandecode_log_cont(" | 0x%" PRIx64, flags);
        } else {
                pandecode_log_cont("0x%" PRIx64, flags);
        }
}

#define FLAG_INFO(flag) { MALI_MFBD_FORMAT_##flag, "MALI_MFBD_FORMAT_" #flag }
static const struct pandecode_flag_info mfbd_fmt_flag_info[] = {
        FLAG_INFO(SRGB),
        {}
};
#undef FLAG_INFO

#define FLAG_INFO(flag) { MALI_AFBC_##flag, "MALI_AFBC_" #flag }
static const struct pandecode_flag_info afbc_fmt_flag_info[] = {
        FLAG_INFO(YTR),
        {}
};
#undef FLAG_INFO

#define FLAG_INFO(flag) { MALI_EXTRA_##flag, "MALI_EXTRA_" #flag }
static const struct pandecode_flag_info mfbd_extra_flag_hi_info[] = {
        FLAG_INFO(PRESENT),
        {}
};
#undef FLAG_INFO

#define FLAG_INFO(flag) { MALI_EXTRA_##flag, "MALI_EXTRA_" #flag }
static const struct pandecode_flag_info mfbd_extra_flag_lo_info[] = {
        FLAG_INFO(ZS),
        {}
};
#undef FLAG_INFO

#define FLAG_INFO(flag) { MALI_MFBD_##flag, "MALI_MFBD_" #flag }
static const struct pandecode_flag_info mfbd_flag_info [] = {
        FLAG_INFO(DEPTH_WRITE),
        FLAG_INFO(EXTRA),
        {}
};
#undef FLAG_INFO

/* Midgard's tiler descriptor is embedded within the
 * larger FBD */

static void
pandecode_midgard_tiler_descriptor(
                const struct mali_midgard_tiler_packed *tp,
                const struct mali_midgard_tiler_weights_packed *wp,
                unsigned width,
                unsigned height,
                bool is_fragment,
                bool has_hierarchy)
{
        pan_unpack(tp, MIDGARD_TILER, t);
        DUMP_UNPACKED(MIDGARD_TILER, t, "Tiler:\n");

        MEMORY_PROP_DIR(t, polygon_list);

        /* The body is offset from the base of the polygon list */
        //assert(t->polygon_list_body > t->polygon_list);
        unsigned body_offset = t.polygon_list_body - t.polygon_list;

        /* It needs to fit inside the reported size */
        //assert(t->polygon_list_size >= body_offset);

        /* Now that we've sanity checked, we'll try to calculate the sizes
         * ourselves for comparison */

        unsigned ref_header = panfrost_tiler_header_size(width, height, t.hierarchy_mask, has_hierarchy);
        unsigned ref_size = panfrost_tiler_full_size(width, height, t.hierarchy_mask, has_hierarchy);

        if (!((ref_header == body_offset) && (ref_size == t.polygon_list_size))) {
                pandecode_msg("XXX: bad polygon list size (expected %d / 0x%x)\n",
                                ref_header, ref_size);
                pandecode_prop("polygon_list_size = 0x%x", t.polygon_list_size);
                pandecode_msg("body offset %d\n", body_offset);
        }

        /* The tiler heap has a start and end specified -- it should be
         * identical to what we have in the BO. The exception is if tiling is
         * disabled. */

        MEMORY_PROP_DIR(t, heap_start);
        assert(t.heap_end >= t.heap_start);

        unsigned heap_size = t.heap_end - t.heap_start;

        /* Tiling is enabled with a special flag */
        unsigned hierarchy_mask = t.hierarchy_mask & MALI_MIDGARD_TILER_HIERARCHY_MASK;
        unsigned tiler_flags = t.hierarchy_mask ^ hierarchy_mask;

        bool tiling_enabled = hierarchy_mask;

        if (tiling_enabled) {
                /* We should also have no other flags */
                if (tiler_flags)
                        pandecode_msg("XXX: unexpected tiler %X\n", tiler_flags);
        } else {
                /* When tiling is disabled, we should have that flag and no others */

                if (tiler_flags != MALI_MIDGARD_TILER_DISABLED) {
                        pandecode_msg("XXX: unexpected tiler flag %X, expected MALI_MIDGARD_TILER_DISABLED\n",
                                        tiler_flags);
                }

                /* We should also have an empty heap */
                if (heap_size) {
                        pandecode_msg("XXX: tiler heap size %d given, expected empty\n",
                                        heap_size);
                }

                /* Disabled tiling is used only for clear-only jobs, which are
                 * purely FRAGMENT, so we should never see this for
                 * non-FRAGMENT descriptors. */

                if (!is_fragment)
                        pandecode_msg("XXX: tiler disabled for non-FRAGMENT job\n");
        }

        /* We've never seen weights used in practice, but we know from the
         * kernel these fields is there */

        pan_unpack(wp, MIDGARD_TILER_WEIGHTS, w);
        bool nonzero_weights = false;

        nonzero_weights |= w.weight0 != 0x0;
        nonzero_weights |= w.weight1 != 0x0;
        nonzero_weights |= w.weight2 != 0x0;
        nonzero_weights |= w.weight3 != 0x0;
        nonzero_weights |= w.weight4 != 0x0;
        nonzero_weights |= w.weight5 != 0x0;
        nonzero_weights |= w.weight6 != 0x0;
        nonzero_weights |= w.weight7 != 0x0;

        if (nonzero_weights)
                DUMP_UNPACKED(MIDGARD_TILER_WEIGHTS, w, "Tiler Weights:\n");
}

/* TODO: The Bifrost tiler is not understood at all yet */

static void
pandecode_bifrost_tiler_descriptor(const struct mali_framebuffer *fb)
{
        pandecode_log(".tiler = {\n");
        pandecode_indent++;

        MEMORY_PROP(fb, tiler_meta);

        for (int i = 0; i < 16; i++) {
                if (fb->zeros[i] != 0) {
                        pandecode_msg("XXX: tiler descriptor zero %d tripped, value %x\n",
                                      i, fb->zeros[i]);
                }
        }

        pandecode_log("},\n");

        pandecode_indent--;
        pandecode_log("}\n");

}

/* Information about the framebuffer passed back for
 * additional analysis */

struct pandecode_fbd {
        unsigned width;
        unsigned height;
        unsigned rt_count;
        bool has_extra;
};

static struct pandecode_fbd
pandecode_sfbd(uint64_t gpu_va, int job_no, bool is_fragment, unsigned gpu_id)
{
        struct pandecode_mapped_memory *mem = pandecode_find_mapped_gpu_mem_containing(gpu_va);
        const void *PANDECODE_PTR_VAR(s, mem, (mali_ptr) gpu_va);

        struct pandecode_fbd info = {
                .has_extra = false,
                .rt_count = 1
        };

        pandecode_log("Single-Target Framebuffer:\n");
        pandecode_indent++;

        DUMP_SECTION(SINGLE_TARGET_FRAMEBUFFER, LOCAL_STORAGE, s, "Local Storage:\n");
        pan_section_unpack(s, SINGLE_TARGET_FRAMEBUFFER, PARAMETERS, p);
        DUMP_UNPACKED(SINGLE_TARGET_FRAMEBUFFER_PARAMETERS, p, "Parameters:\n");

        const void *t = pan_section_ptr(s, SINGLE_TARGET_FRAMEBUFFER, TILER);
        const void *w = pan_section_ptr(s, SINGLE_TARGET_FRAMEBUFFER, TILER_WEIGHTS);

        bool has_hierarchy = !(gpu_id == 0x0720 || gpu_id == 0x0820 || gpu_id == 0x0830);
        pandecode_midgard_tiler_descriptor(t, w, p.bound_max_x + 1, p.bound_max_y + 1, is_fragment, has_hierarchy);

        pandecode_indent--;

        /* Dummy unpack of the padding section to make sure all words are 0.
         * No need to call print here since the section is supposed to be empty.
         */
        pan_section_unpack(s, SINGLE_TARGET_FRAMEBUFFER, PADDING_1, padding1);
        pan_section_unpack(s, SINGLE_TARGET_FRAMEBUFFER, PADDING_2, padding2);
        pandecode_log("\n");

        return info;
}

static void
pandecode_compute_fbd(uint64_t gpu_va, int job_no)
{
        struct pandecode_mapped_memory *mem = pandecode_find_mapped_gpu_mem_containing(gpu_va);
        const struct mali_local_storage_packed *PANDECODE_PTR_VAR(s, mem, (mali_ptr) gpu_va);
        DUMP_CL(LOCAL_STORAGE, s, "Local Storage:\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_R == 0);

        for (unsigned c = 0; c < 4; ++c) {
                enum mali_channel chan = (swizzle >> (3*c)) & 0x7;

                if (chan <= MALI_CHANNEL_A)
                        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_R | (MALI_CHANNEL_0  << 3) | (MALI_CHANNEL_0 << 6) | (MALI_CHANNEL_1   << 9),
                MALI_CHANNEL_R | (MALI_CHANNEL_G << 3) | (MALI_CHANNEL_0 << 6) | (MALI_CHANNEL_1   << 9),
                MALI_CHANNEL_R | (MALI_CHANNEL_G << 3) | (MALI_CHANNEL_B << 6) | (MALI_CHANNEL_1   << 9),
                MALI_CHANNEL_R | (MALI_CHANNEL_G << 3) | (MALI_CHANNEL_B << 6) | (MALI_CHANNEL_A << 9)
        };

        return (swizzle == default_swizzles[nr_comp - 1]);
}

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_1) {
                        pandecode_log("XXX: invalid swizzle channel %d\n", chan);
                        continue;
                }
                pandecode_log_cont("%c", components[chan]);
        }
}

static void
pandecode_rt_format(struct mali_rt_format format)
{
        pandecode_log(".format = {\n");
        pandecode_indent++;

        pandecode_prop("unk1 = 0x%" PRIx32, format.unk1);
        pandecode_prop("unk2 = 0x%" PRIx32, format.unk2);
        pandecode_prop("unk3 = 0x%" PRIx32, format.unk3);
        pandecode_prop("unk4 = 0x%" PRIx32, format.unk4);

        pandecode_prop("block = %s", mali_block_format_as_str(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)",
                       (format.nr_channels + 1));

        pandecode_log(".flags = ");
        pandecode_log_decoded_flags(mfbd_fmt_flag_info, format.flags);
        pandecode_log_cont(",\n");

        pandecode_prop("msaa = %s", mali_msaa_as_str(format.msaa));

        /* 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
         * preload is buggy on Midgard, and so this is a chicken bit. If this
         * bit isn't set, most likely something broke unrelated to preload */

        if (!format.no_preload) {
                pandecode_msg("XXX: buggy MFBD preload enabled - chicken bit should be clear\n");
                pandecode_prop("no_preload = 0x%" PRIx32, format.no_preload);
        }

        if (format.zero)
                pandecode_prop("zero = 0x%" PRIx32, format.zero);

        pandecode_indent--;
        pandecode_log("},\n");
}

static void
pandecode_render_target(uint64_t gpu_va, unsigned job_no, const struct mali_framebuffer *fb)
{
        pandecode_log("struct mali_render_target rts_list_%"PRIx64"_%d[] = {\n", gpu_va, job_no);
        pandecode_indent++;

        for (int i = 0; i < (fb->rt_count_1 + 1); i++) {
                mali_ptr rt_va = gpu_va + i * sizeof(struct mali_render_target);
                struct pandecode_mapped_memory *mem =
                        pandecode_find_mapped_gpu_mem_containing(rt_va);
                const struct mali_render_target *PANDECODE_PTR_VAR(rt, mem, (mali_ptr) rt_va);

                pandecode_log("{\n");
                pandecode_indent++;

                pandecode_rt_format(rt->format);

                if (rt->format.block == MALI_BLOCK_FORMAT_AFBC) {
                        pandecode_log(".afbc = {\n");
                        pandecode_indent++;

                        char *a = pointer_as_memory_reference(rt->afbc.metadata);
                        pandecode_prop("metadata = %s", a);
                        free(a);

                        pandecode_prop("stride = %d", rt->afbc.stride);

                        pandecode_log(".flags = ");
                        pandecode_log_decoded_flags(afbc_fmt_flag_info, rt->afbc.flags);
                        pandecode_log_cont(",\n");

                        pandecode_indent--;
                        pandecode_log("},\n");
                } else if (rt->afbc.metadata || rt->afbc.stride || rt->afbc.flags) {
                        pandecode_msg("XXX: AFBC disabled but AFBC field set (0x%lX, 0x%x, 0x%x)\n",
                                        rt->afbc.metadata,
                                        rt->afbc.stride,
                                        rt->afbc.flags);
                }

                MEMORY_PROP(rt, framebuffer);
                pandecode_prop("framebuffer_stride = %d", rt->framebuffer_stride);

                if (rt->layer_stride)
                        pandecode_prop("layer_stride = %d", rt->layer_stride);

                if (rt->clear_color_1 | rt->clear_color_2 | rt->clear_color_3 | rt->clear_color_4) {
                        pandecode_prop("clear_color_1 = 0x%" PRIx32, rt->clear_color_1);
                        pandecode_prop("clear_color_2 = 0x%" PRIx32, rt->clear_color_2);
                        pandecode_prop("clear_color_3 = 0x%" PRIx32, rt->clear_color_3);
                        pandecode_prop("clear_color_4 = 0x%" PRIx32, rt->clear_color_4);
                }

                if (rt->zero1 || rt->zero2) {
                        pandecode_msg("XXX: render target zeros tripped\n");
                        pandecode_prop("zero1 = 0x%" PRIx64, rt->zero1);
                        pandecode_prop("zero2 = 0x%" PRIx32, rt->zero2);
                }

                pandecode_indent--;
                pandecode_log("},\n");
        }

        pandecode_indent--;
        pandecode_log("};\n");
}

static struct pandecode_fbd
pandecode_mfbd_bfr(uint64_t gpu_va, int job_no, bool is_fragment, bool is_compute, bool is_bifrost)
{
        struct pandecode_mapped_memory *mem = pandecode_find_mapped_gpu_mem_containing(gpu_va);
        const struct mali_framebuffer *PANDECODE_PTR_VAR(fb, mem, (mali_ptr) gpu_va);

        struct pandecode_fbd info;

        if (is_bifrost && fb->msaa.sample_locations) {
                /* The blob stores all possible sample locations in a single buffer
                 * allocated on startup, and just switches the pointer when switching
                 * MSAA state. For now, we just put the data into the cmdstream, but we
                 * should do something like what the blob does with a real driver.
                 *
                 * There seem to be 32 slots for sample locations, followed by another
                 * 16. The second 16 is just the center location followed by 15 zeros
                 * in all the cases I've identified (maybe shader vs. depth/color
                 * samples?).
                 */

                struct pandecode_mapped_memory *smem = pandecode_find_mapped_gpu_mem_containing(fb->msaa.sample_locations);

                const u16 *PANDECODE_PTR_VAR(samples, smem, fb->msaa.sample_locations);

                pandecode_log("uint16_t sample_locations_%d[] = {\n", job_no);
                pandecode_indent++;

                for (int i = 0; i < 32 + 16; i++) {
                        pandecode_log("%d, %d,\n", samples[2 * i], samples[2 * i + 1]);
                }

                pandecode_indent--;
                pandecode_log("};\n");
        }
 
        pandecode_log("struct mali_framebuffer framebuffer_%"PRIx64"_%d = {\n", gpu_va, job_no);
        pandecode_indent++;

        if (is_bifrost) {
                pandecode_log(".msaa = {\n");
                pandecode_indent++;

                if (fb->msaa.sample_locations)
                        pandecode_prop("sample_locations = sample_locations_%d", job_no);
                else
                        pandecode_msg("XXX: sample_locations missing\n");

                if (fb->msaa.zero1 || fb->msaa.zero2 || fb->msaa.zero4) {
                        pandecode_msg("XXX: multisampling zero tripped\n");
                        pandecode_prop("zero1 = %" PRIx64, fb->msaa.zero1);
                        pandecode_prop("zero2 = %" PRIx64, fb->msaa.zero2);
                        pandecode_prop("zero4 = %" PRIx64, fb->msaa.zero4);
                }

                pandecode_indent--;
                pandecode_log("},\n");
        } else {
                struct mali_local_storage_packed ls = fb->shared_memory;
                DUMP_CL(LOCAL_STORAGE, &ls, "Local Storage:\n");
        }

        info.width = fb->width1 + 1;
        info.height = fb->height1 + 1;
        info.rt_count = fb->rt_count_1 + 1;

        pandecode_prop("width1 = MALI_POSITIVE(%d)", fb->width1 + 1);
        pandecode_prop("height1 = MALI_POSITIVE(%d)", fb->height1 + 1);
        pandecode_prop("width2 = MALI_POSITIVE(%d)", fb->width2 + 1);
        pandecode_prop("height2 = MALI_POSITIVE(%d)", fb->height2 + 1);

        pandecode_prop("unk1 = 0x%x", fb->unk1);
        pandecode_prop("unk2 = 0x%x", fb->unk2);
        pandecode_prop("rt_count_1 = MALI_POSITIVE(%d)", fb->rt_count_1 + 1);
        pandecode_prop("rt_count_2 = %d", fb->rt_count_2);

        pandecode_log(".mfbd_flags = ");
        pandecode_log_decoded_flags(mfbd_flag_info, fb->mfbd_flags);
        pandecode_log_cont(",\n");

        if (fb->clear_stencil)
                pandecode_prop("clear_stencil = 0x%x", fb->clear_stencil);

        if (fb->clear_depth)
                pandecode_prop("clear_depth = %f", fb->clear_depth);

        if (!is_compute)
                if (is_bifrost)
                        pandecode_bifrost_tiler_descriptor(fb);
                else {
                        const struct mali_midgard_tiler_packed t = fb->tiler;
                        const struct mali_midgard_tiler_weights_packed w = fb->tiler_weights;
                        pandecode_midgard_tiler_descriptor(&t, &w, fb->width1 + 1, fb->height1 + 1, is_fragment, true);
                }
        else
                pandecode_msg("XXX: skipping compute MFBD, fixme\n");

        if (fb->zero3 || fb->zero4) {
                pandecode_msg("XXX: framebuffer zeros tripped\n");
                pandecode_prop("zero3 = 0x%" PRIx32, fb->zero3);
                pandecode_prop("zero4 = 0x%" PRIx32, fb->zero4);
        }

        pandecode_indent--;
        pandecode_log("};\n");

        gpu_va += sizeof(struct mali_framebuffer);

        info.has_extra = (fb->mfbd_flags & MALI_MFBD_EXTRA) && is_fragment;

        if (info.has_extra) {
                mem = pandecode_find_mapped_gpu_mem_containing(gpu_va);
                const struct mali_framebuffer_extra *PANDECODE_PTR_VAR(fbx, mem, (mali_ptr) gpu_va);

                pandecode_log("struct mali_framebuffer_extra fb_extra_%"PRIx64"_%d = {\n", gpu_va, job_no);
                pandecode_indent++;

                MEMORY_PROP(fbx, checksum);

                if (fbx->checksum_stride)
                        pandecode_prop("checksum_stride = %d", fbx->checksum_stride);

                pandecode_log(".flags_hi = ");
                pandecode_log_decoded_flags(mfbd_extra_flag_hi_info, fbx->flags_hi);
                pandecode_log_cont(",\n");

                pandecode_log(".flags_lo = ");
                pandecode_log_decoded_flags(mfbd_extra_flag_lo_info, fbx->flags_lo);
                pandecode_log_cont(",\n");

                pandecode_prop("zs_block = %s", mali_block_format_as_str(fbx->zs_block));
                pandecode_prop("zs_samples = MALI_POSITIVE(%u)", fbx->zs_samples + 1);

                if (fbx->zs_block == MALI_BLOCK_FORMAT_AFBC) {
                        pandecode_log(".ds_afbc = {\n");
                        pandecode_indent++;

                        MEMORY_PROP_DIR(fbx->ds_afbc, depth_stencil_afbc_metadata);
                        pandecode_prop("depth_stencil_afbc_stride = %d",
                                       fbx->ds_afbc.depth_stencil_afbc_stride);
                        MEMORY_PROP_DIR(fbx->ds_afbc, depth_stencil);

                        pandecode_log(".flags = ");
                        pandecode_log_decoded_flags(afbc_fmt_flag_info, fbx->ds_afbc.flags);
                        pandecode_log_cont(",\n");

                        if (fbx->ds_afbc.padding) {
                                pandecode_msg("XXX: Depth/stencil AFBC zeros tripped\n");
                                pandecode_prop("padding = 0x%" PRIx64, fbx->ds_afbc.padding);
                        }

                        pandecode_indent--;
                        pandecode_log("},\n");
                } else {
                        pandecode_log(".ds_linear = {\n");
                        pandecode_indent++;

                        if (fbx->ds_linear.depth) {
                                MEMORY_PROP_DIR(fbx->ds_linear, depth);
                                pandecode_prop("depth_stride = %d",
                                               fbx->ds_linear.depth_stride);
                                pandecode_prop("depth_layer_stride = %d",
                                               fbx->ds_linear.depth_layer_stride);
                        } else if (fbx->ds_linear.depth_stride || fbx->ds_linear.depth_layer_stride) {
                                pandecode_msg("XXX: depth stride zero tripped %d %d\n", fbx->ds_linear.depth_stride, fbx->ds_linear.depth_layer_stride);
                        }

                        if (fbx->ds_linear.stencil) {
                                MEMORY_PROP_DIR(fbx->ds_linear, stencil);
                                pandecode_prop("stencil_stride = %d",
                                               fbx->ds_linear.stencil_stride);
                                pandecode_prop("stencil_layer_stride = %d",
                                               fbx->ds_linear.stencil_layer_stride);
                        } else if (fbx->ds_linear.stencil_stride || fbx->ds_linear.stencil_layer_stride) {
                                pandecode_msg("XXX: stencil stride zero tripped %d %d\n", fbx->ds_linear.stencil_stride, fbx->ds_linear.stencil_layer_stride);
                        }

                        if (fbx->ds_linear.depth_stride_zero ||
                            fbx->ds_linear.stencil_stride_zero) {
                                pandecode_msg("XXX: Depth/stencil zeros tripped\n");
                                pandecode_prop("depth_stride_zero = 0x%x",
                                               fbx->ds_linear.depth_stride_zero);
                                pandecode_prop("stencil_stride_zero = 0x%x",
                                               fbx->ds_linear.stencil_stride_zero);
                        }

                        pandecode_indent--;
                        pandecode_log("},\n");
                }

                if (fbx->clear_color_1 | fbx->clear_color_2) {
                        pandecode_prop("clear_color_1 = 0x%" PRIx32, fbx->clear_color_1);
                        pandecode_prop("clear_color_2 = 0x%" PRIx32, fbx->clear_color_2);
                }

                if (fbx->zero3) {
                        pandecode_msg("XXX: fb_extra zeros tripped\n");
                        pandecode_prop("zero3 = 0x%" PRIx64, fbx->zero3);
                }

                pandecode_indent--;
                pandecode_log("};\n");

                gpu_va += sizeof(struct mali_framebuffer_extra);
        }

        if (is_fragment)
                pandecode_render_target(gpu_va, job_no, fb);

        return info;
}

static void
pandecode_attributes(const struct pandecode_mapped_memory *mem,
                            mali_ptr addr, int job_no, char *suffix,
                            int count, bool varying, enum mali_job_type job_type)
{
        char *prefix = varying ? "Varying" : "Attribute";
        assert(addr);

        if (!count) {
                pandecode_msg("warn: No %s records\n", prefix);
                return;
        }

        MAP_ADDR(ATTRIBUTE_BUFFER, addr, cl);

        for (int i = 0; i < count; ++i) {
                pan_unpack(cl + i * MALI_ATTRIBUTE_BUFFER_LENGTH, ATTRIBUTE_BUFFER, temp);
                DUMP_UNPACKED(ATTRIBUTE_BUFFER, temp, "%s:\n", prefix);

                if (temp.type != MALI_ATTRIBUTE_TYPE_1D_NPOT_DIVISOR)
                        continue;

                pan_unpack(cl + (i + 1) * MALI_ATTRIBUTE_BUFFER_LENGTH,
                           ATTRIBUTE_BUFFER_CONTINUATION_NPOT, temp2);
                pan_print(pandecode_dump_stream, ATTRIBUTE_BUFFER_CONTINUATION_NPOT,
                          temp2, (pandecode_indent + 1) * 2);
        }
}

static mali_ptr
pandecode_shader_address(const char *name, mali_ptr ptr)
{
        /* TODO: Decode flags */
        mali_ptr shader_ptr = ptr & ~15;

        char *a = pointer_as_memory_reference(shader_ptr);
        pandecode_prop("%s = (%s) | %d", name, a, (int) (ptr & 15));
        free(a);

        return shader_ptr;
}

/* Decodes a Bifrost blend constant. See the notes in bifrost_blend_rt */

static unsigned
decode_bifrost_constant(u16 constant)
{
        float lo = (float) (constant & 0xFF);
        float hi = (float) (constant >> 8);

        return (hi / 255.0) + (lo / 65535.0);
}

static mali_ptr
pandecode_bifrost_blend(void *descs, int job_no, int rt_no)
{
        struct bifrost_blend_rt *b =
                ((struct bifrost_blend_rt *) descs) + rt_no;

        pandecode_log("struct bifrost_blend_rt blend_rt_%d_%d = {\n", job_no, rt_no);
        pandecode_indent++;

        pandecode_prop("flags = 0x%" PRIx16, b->flags);
        pandecode_prop("constant = 0x%" PRIx8 " /* %f */",
                       b->constant, decode_bifrost_constant(b->constant));

        /* TODO figure out blend shader enable bit */
        DUMP_CL(BLEND_EQUATION, &b->equation, "Equation:\n");

        pandecode_prop("unk2 = 0x%" PRIx16, b->unk2);
        pandecode_prop("index = 0x%" PRIx16, b->index);

        pandecode_log(".format = %s", mali_format_as_str(b->format));
        pandecode_swizzle(b->swizzle, b->format);
        pandecode_log_cont(",\n");

        pandecode_prop("swizzle = 0x%" PRIx32, b->swizzle);
        pandecode_prop("format = 0x%" PRIx32, b->format);

        if (b->zero1) {
                pandecode_msg("XXX: pandecode_bifrost_blend zero1 tripped\n");
                pandecode_prop("zero1 = 0x%" PRIx32, b->zero1);
        }

        pandecode_log(".shader_type = ");
        switch(b->shader_type) {
        case BIFROST_BLEND_F16:
                pandecode_log_cont("BIFROST_BLEND_F16");
                break;
        case BIFROST_BLEND_F32:
                pandecode_log_cont("BIFROST_BLEND_F32");
                break;
        case BIFROST_BLEND_I32:
                pandecode_log_cont("BIFROST_BLEND_I32");
                break;
        case BIFROST_BLEND_U32:
                pandecode_log_cont("BIFROST_BLEND_U32");
                break;
        case BIFROST_BLEND_I16:
                pandecode_log_cont("BIFROST_BLEND_I16");
                break;
        case BIFROST_BLEND_U16:
                pandecode_log_cont("BIFROST_BLEND_U16");
                break;
        }
        pandecode_log_cont(",\n");

        if (b->zero2) {
                pandecode_msg("XXX: pandecode_bifrost_blend zero2 tripped\n");
                pandecode_prop("zero2 = 0x%" PRIx32, b->zero2);
        }

        pandecode_prop("shader = 0x%" PRIx32, b->shader);

        pandecode_indent--;
        pandecode_log("},\n");

        return 0;
}

static mali_ptr
pandecode_midgard_blend(union midgard_blend *blend, bool is_shader)
{
        /* constant/equation is in a union */
        if (!blend->shader)
                return 0;

        pandecode_log(".blend = {\n");
        pandecode_indent++;

        if (is_shader) {
                pandecode_shader_address("shader", blend->shader);
        } else {
                DUMP_CL(BLEND_EQUATION, &blend->equation, "Equation:\n");
                pandecode_prop("constant = %f", blend->constant);
        }

        pandecode_indent--;
        pandecode_log("},\n");

        /* Return blend shader to disassemble if present */
        return is_shader ? (blend->shader & ~0xF) : 0;
}

static mali_ptr
pandecode_midgard_blend_mrt(void *descs, int job_no, int rt_no)
{
        struct midgard_blend_rt *b =
                ((struct midgard_blend_rt *) descs) + rt_no;

        /* Flags determine presence of blend shader */
        bool is_shader = b->flags.opaque[0] & 0x2;

        pandecode_log("struct midgard_blend_rt blend_rt_%d_%d = {\n", job_no, rt_no);
        pandecode_indent++;

        DUMP_CL(BLEND_FLAGS, &b->flags, "Flags:\n");

        union midgard_blend blend = b->blend;
        mali_ptr shader = pandecode_midgard_blend(&blend, is_shader);

        pandecode_indent--;
        pandecode_log("};\n");

        return shader;
}

/* Attributes and varyings have descriptor records, which contain information
 * about their format and ordering with the attribute/varying buffers. We'll
 * want to validate that the combinations specified are self-consistent.
 */

static int
pandecode_attribute_meta(int count, mali_ptr attribute, bool varying, char *suffix)
{
        for (int i = 0; i < count; ++i, attribute += MALI_ATTRIBUTE_LENGTH)
                DUMP_ADDR(ATTRIBUTE, attribute, "%s:\n", varying ? "Varying" : "Attribute");

        return count;
}

/* return bits [lo, hi) of word */
static u32
bits(u32 word, u32 lo, u32 hi)
{
        if (hi - lo >= 32)
                return word; // avoid undefined behavior with the shift

        return (word >> lo) & ((1 << (hi - lo)) - 1);
}

static void
pandecode_vertex_tiler_prefix(struct mali_vertex_tiler_prefix *p, int job_no, bool graphics)
{
        /* Decode invocation_count. See the comment before the definition of
         * invocation_count for an explanation.
         */
        struct mali_invocation_packed invocation_packed = p->invocation;
        pan_unpack(&invocation_packed, INVOCATION, invocation);

        unsigned size_x = bits(invocation.invocations, 0, invocation.size_y_shift) + 1;
        unsigned size_y = bits(invocation.invocations, invocation.size_y_shift, invocation.size_z_shift) + 1;
        unsigned size_z = bits(invocation.invocations, invocation.size_z_shift, invocation.workgroups_x_shift) + 1;

        unsigned groups_x = bits(invocation.invocations, invocation.workgroups_x_shift, invocation.workgroups_y_shift) + 1;
        unsigned groups_y = bits(invocation.invocations, invocation.workgroups_y_shift, invocation.workgroups_z_shift) + 1;
        unsigned groups_z = bits(invocation.invocations, invocation.workgroups_z_shift, 32) + 1;

        /* Even though we have this decoded, we want to ensure that the
         * representation is "unique" so we don't lose anything by printing only
         * the final result. More specifically, we need to check that we were
         * passed something in canonical form, since the definition per the
         * hardware is inherently not unique. How? Well, take the resulting
         * decode and pack it ourselves! If it is bit exact with what we
         * decoded, we're good to go. */

        struct mali_invocation_packed ref;
        panfrost_pack_work_groups_compute(&ref, groups_x, groups_y, groups_z, size_x, size_y, size_z, graphics);

        if (memcmp(&ref, &invocation_packed, sizeof(ref))) {
                pandecode_msg("XXX: non-canonical workgroups packing\n");
                DUMP_UNPACKED(INVOCATION, invocation, "Invocation:\n")
        }

        /* Regardless, print the decode */
        pandecode_log("Invocation (%d, %d, %d) x (%d, %d, %d)\n",
                      size_x, size_y, size_z,
                      groups_x, groups_y, groups_z);

        struct mali_primitive_packed prim_packed = p->primitive;
        pan_unpack(&prim_packed, PRIMITIVE, primitive);
        DUMP_UNPACKED(PRIMITIVE, primitive, "Primitive:\n");

        /* Validate an index buffer is present if we need one. TODO: verify
         * relationship between invocation_count and index_count */

        if (primitive.indices) {
                /* Grab the size */
                unsigned size = (primitive.index_type == MALI_INDEX_TYPE_UINT32) ?
                        sizeof(uint32_t) : primitive.index_type;

                /* Ensure we got a size, and if so, validate the index buffer
                 * is large enough to hold a full set of indices of the given
                 * size */

                if (!size)
                        pandecode_msg("XXX: index size missing\n");
                else
                        pandecode_validate_buffer(primitive.indices, primitive.index_count * size);
        } else if (primitive.index_type)
                pandecode_msg("XXX: unexpected index size\n");
}

static void
pandecode_uniform_buffers(mali_ptr pubufs, int ubufs_count, int job_no)
{
        struct pandecode_mapped_memory *umem = pandecode_find_mapped_gpu_mem_containing(pubufs);
        uint64_t *PANDECODE_PTR_VAR(ubufs, umem, pubufs);

        for (int i = 0; i < ubufs_count; i++) {
                unsigned size = (ubufs[i] & ((1 << 10) - 1)) * 16;
                mali_ptr addr = (ubufs[i] >> 10) << 2;

                pandecode_validate_buffer(addr, size);

                char *ptr = pointer_as_memory_reference(addr);
                pandecode_log("ubuf_%d[%u] = %s;\n", i, size, ptr);
                free(ptr);
        }

        pandecode_log("\n");
}

static void
pandecode_uniforms(mali_ptr uniforms, unsigned uniform_count)
{
        pandecode_validate_buffer(uniforms, uniform_count * 16);

        char *ptr = pointer_as_memory_reference(uniforms);
        pandecode_log("vec4 uniforms[%u] = %s;\n", uniform_count, ptr);
        free(ptr);
}

static const char *
shader_type_for_job(unsigned type)
{
        switch (type) {
        case MALI_JOB_TYPE_VERTEX:  return "VERTEX";
        case MALI_JOB_TYPE_TILER:   return "FRAGMENT";
        case MALI_JOB_TYPE_COMPUTE: return "COMPUTE";
        default: return "UNKNOWN";
        }
}

static unsigned shader_id = 0;

static struct midgard_disasm_stats
pandecode_shader_disassemble(mali_ptr shader_ptr, int shader_no, int type,
                             bool is_bifrost, unsigned gpu_id)
{
        struct pandecode_mapped_memory *mem = pandecode_find_mapped_gpu_mem_containing(shader_ptr);
        uint8_t *PANDECODE_PTR_VAR(code, mem, shader_ptr);

        /* Compute maximum possible size */
        size_t sz = mem->length - (shader_ptr - mem->gpu_va);

        /* Print some boilerplate to clearly denote the assembly (which doesn't
         * obey indentation rules), and actually do the disassembly! */

        pandecode_log_cont("\n\n");

        struct midgard_disasm_stats stats;

        if (is_bifrost) {
                disassemble_bifrost(pandecode_dump_stream, code, sz, true);

                /* TODO: Extend stats to Bifrost */
                stats.texture_count = -128;
                stats.sampler_count = -128;
                stats.attribute_count = -128;
                stats.varying_count = -128;
                stats.uniform_count = -128;
                stats.uniform_buffer_count = -128;
                stats.work_count = -128;

                stats.instruction_count = 0;
                stats.bundle_count = 0;
                stats.quadword_count = 0;
                stats.helper_invocations = false;
        } else {
                stats = disassemble_midgard(pandecode_dump_stream,
                                code, sz, gpu_id,
                                type == MALI_JOB_TYPE_TILER ?
                                MESA_SHADER_FRAGMENT : MESA_SHADER_VERTEX);
        }

        unsigned nr_threads =
                (stats.work_count <= 4) ? 4 :
                (stats.work_count <= 8) ? 2 :
                1;

        pandecode_log_cont("shader%d - MESA_SHADER_%s shader: "
                "%u inst, %u bundles, %u quadwords, "
                "%u registers, %u threads, 0 loops, 0:0 spills:fills\n\n\n",
                shader_id++,
                shader_type_for_job(type),
                stats.instruction_count, stats.bundle_count, stats.quadword_count,
                stats.work_count, nr_threads);

        return stats;
}

static void
pandecode_texture_payload(mali_ptr payload,
                          enum mali_texture_dimension dim,
                          enum mali_texture_layout layout,
                          bool manual_stride,
                          uint8_t levels,
                          uint16_t depth,
                          uint16_t array_size,
                          struct pandecode_mapped_memory *tmem)
{
        pandecode_log(".payload = {\n");
        pandecode_indent++;

        /* A bunch of bitmap pointers follow.
         * We work out the correct number,
         * based on the mipmap/cubemap
         * properties, but dump extra
         * possibilities to futureproof */

        int bitmap_count = levels + 1;

        /* Miptree for each face */
        if (dim == MALI_TEXTURE_DIMENSION_CUBE)
                bitmap_count *= 6;

        /* Array of layers */
        bitmap_count *= depth;

        /* Array of textures */
        bitmap_count *= array_size;

        /* Stride for each element */
        if (manual_stride)
                bitmap_count *= 2;

        mali_ptr *pointers_and_strides = pandecode_fetch_gpu_mem(tmem,
                payload, sizeof(mali_ptr) * bitmap_count);
        for (int i = 0; i < bitmap_count; ++i) {
                /* How we dump depends if this is a stride or a pointer */

                if (manual_stride && (i & 1)) {
                        /* signed 32-bit snuck in as a 64-bit pointer */
                        uint64_t stride_set = pointers_and_strides[i];
                        uint32_t clamped_stride = stride_set;
                        int32_t stride = clamped_stride;
                        assert(stride_set == clamped_stride);
                        pandecode_log("(mali_ptr) %d /* stride */, \n", stride);
                } else {
                        char *a = pointer_as_memory_reference(pointers_and_strides[i]);
                        pandecode_log("%s, \n", a);
                        free(a);
                }
        }

        pandecode_indent--;
        pandecode_log("},\n");
}

static void
pandecode_texture(mali_ptr u,
                struct pandecode_mapped_memory *tmem,
                unsigned job_no, unsigned tex)
{
        struct pandecode_mapped_memory *mapped_mem = pandecode_find_mapped_gpu_mem_containing(u);
        const uint8_t *cl = pandecode_fetch_gpu_mem(mapped_mem, u, MALI_MIDGARD_TEXTURE_LENGTH);

        pan_unpack(cl, MIDGARD_TEXTURE, temp);
        DUMP_UNPACKED(MIDGARD_TEXTURE, temp, "Texture:\n")

        pandecode_indent++;
        pandecode_texture_payload(u + MALI_MIDGARD_TEXTURE_LENGTH,
                        temp.dimension, temp.texel_ordering, temp.manual_stride,
                        temp.levels, temp.depth, temp.array_size, mapped_mem);
        pandecode_indent--;
}

static void
pandecode_bifrost_texture(
                const void *cl,
                unsigned job_no,
                unsigned tex)
{
        pan_unpack(cl, BIFROST_TEXTURE, temp);
        DUMP_UNPACKED(BIFROST_TEXTURE, temp, "Texture:\n")

        struct pandecode_mapped_memory *tmem = pandecode_find_mapped_gpu_mem_containing(temp.surfaces);
        pandecode_indent++;
        pandecode_texture_payload(temp.surfaces, temp.dimension, temp.texel_ordering,
                                  true, temp.levels, 1, 1, tmem);
        pandecode_indent--;
}

/* For shader properties like texture_count, we have a claimed property in the shader_meta, and the actual Truth from static analysis (this may just be an upper limit). We validate accordingly */

static void
pandecode_shader_prop(const char *name, unsigned claim, signed truth, bool fuzzy)
{
        /* Nothing to do */
        if (claim == truth)
                return;

        if (fuzzy && (truth < 0))
                pandecode_msg("XXX: fuzzy %s, claimed %d, expected %d\n", name, claim, truth);

        if ((truth >= 0) && !fuzzy) {
                pandecode_msg("%s: expected %s = %d, claimed %u\n",
                                (truth < claim) ? "warn" : "XXX",
                                name, truth, claim);
        } else if ((claim > -truth) && !fuzzy) {
                pandecode_msg("XXX: expected %s <= %u, claimed %u\n",
                                name, -truth, claim);
        } else if (fuzzy && (claim < truth))
                pandecode_msg("XXX: expected %s >= %u, claimed %u\n",
                                name, truth, claim);

        pandecode_log(".%s = %" PRId16, name, claim);

        if (fuzzy)
                pandecode_log_cont(" /* %u used */", truth);

        pandecode_log_cont(",\n");
}

static void
pandecode_blend_shader_disassemble(mali_ptr shader, int job_no, int job_type,
                                   bool is_bifrost, unsigned gpu_id)
{
        struct midgard_disasm_stats stats =
                pandecode_shader_disassemble(shader, job_no, job_type, is_bifrost, gpu_id);

        bool has_texture = (stats.texture_count > 0);
        bool has_sampler = (stats.sampler_count > 0);
        bool has_attribute = (stats.attribute_count > 0);
        bool has_varying = (stats.varying_count > 0);
        bool has_uniform = (stats.uniform_count > 0);
        bool has_ubo = (stats.uniform_buffer_count > 0);

        if (has_texture || has_sampler)
                pandecode_msg("XXX: blend shader accessing textures\n");

        if (has_attribute || has_varying)
                pandecode_msg("XXX: blend shader accessing interstage\n");

        if (has_uniform || has_ubo)
                pandecode_msg("XXX: blend shader accessing uniforms\n");
}

static void
pandecode_textures(mali_ptr textures, unsigned texture_count, int job_no, bool is_bifrost)
{
        struct pandecode_mapped_memory *mmem = pandecode_find_mapped_gpu_mem_containing(textures);

        if (!mmem)
                return;

        pandecode_log("Textures (%"PRIx64"):\n", textures);

        if (is_bifrost) {
                const void *cl = pandecode_fetch_gpu_mem(mmem,
                                textures, MALI_BIFROST_TEXTURE_LENGTH *
                                texture_count);

                for (unsigned tex = 0; tex < texture_count; ++tex) {
                        pandecode_bifrost_texture(cl +
                                        MALI_BIFROST_TEXTURE_LENGTH * tex,
                                        job_no, tex);
                }
        } else {
                mali_ptr *PANDECODE_PTR_VAR(u, mmem, textures);

                for (int tex = 0; tex < texture_count; ++tex) {
                        mali_ptr *PANDECODE_PTR_VAR(u, mmem, textures + tex * sizeof(mali_ptr));
                        char *a = pointer_as_memory_reference(*u);
                        pandecode_log("%s,\n", a);
                        free(a);
                }

                /* Now, finally, descend down into the texture descriptor */
                for (unsigned tex = 0; tex < texture_count; ++tex) {
                        mali_ptr *PANDECODE_PTR_VAR(u, mmem, textures + tex * sizeof(mali_ptr));
                        struct pandecode_mapped_memory *tmem = pandecode_find_mapped_gpu_mem_containing(*u);
                        if (tmem)
                                pandecode_texture(*u, tmem, job_no, tex);
                }
        }
}

static void
pandecode_samplers(mali_ptr samplers, unsigned sampler_count, int job_no, bool is_bifrost)
{
        for (int i = 0; i < sampler_count; ++i) {
                if (is_bifrost) {
                        DUMP_ADDR(BIFROST_SAMPLER, samplers + (MALI_BIFROST_SAMPLER_LENGTH * i), "Sampler:\n");
                } else {
                        DUMP_ADDR(MIDGARD_SAMPLER, samplers + (MALI_MIDGARD_SAMPLER_LENGTH * i), "Sampler:\n");
                }
        }
}

static void
pandecode_vertex_tiler_postfix_pre(
                const struct MALI_DRAW *p,
                int job_no, enum mali_job_type job_type,
                char *suffix, bool is_bifrost, unsigned gpu_id)
{
        struct pandecode_mapped_memory *attr_mem;

        struct pandecode_fbd fbd_info = {
                /* Default for Bifrost */
                .rt_count = 1
        };

        if (is_bifrost)
                pandecode_compute_fbd(p->shared & ~1, job_no);
        else if (p->shared & MALI_MFBD)
                fbd_info = pandecode_mfbd_bfr((u64) ((uintptr_t) p->shared) & FBD_MASK, job_no, false, job_type == MALI_JOB_TYPE_COMPUTE, false);
        else if (job_type == MALI_JOB_TYPE_COMPUTE)
                pandecode_compute_fbd((u64) (uintptr_t) p->shared, job_no);
        else
                fbd_info = pandecode_sfbd((u64) (uintptr_t) p->shared, job_no, false, gpu_id);

        int varying_count = 0, attribute_count = 0, uniform_count = 0, uniform_buffer_count = 0;
        int texture_count = 0, sampler_count = 0;

        if (p->state) {
                struct pandecode_mapped_memory *smem = pandecode_find_mapped_gpu_mem_containing(p->state);
                uint32_t *cl = pandecode_fetch_gpu_mem(smem, p->state, MALI_STATE_LENGTH);

                /* Disassemble ahead-of-time to get stats. Initialize with
                 * stats for the missing-shader case so we get validation
                 * there, too */

                struct midgard_disasm_stats info = {
                        .texture_count = 0,
                        .sampler_count = 0,
                        .attribute_count = 0,
                        .varying_count = 0,
                        .work_count = 1,

                        .uniform_count = -128,
                        .uniform_buffer_count = 0
                };

                pan_unpack(cl, STATE, state);

                if (state.shader.shader & ~0xF)
                        info = pandecode_shader_disassemble(state.shader.shader & ~0xF, job_no, job_type, is_bifrost, gpu_id);

                DUMP_UNPACKED(STATE, state, "State:\n");
                pandecode_indent++;

                /* Save for dumps */
                attribute_count = state.shader.attribute_count;
                varying_count = state.shader.varying_count;
                texture_count = state.shader.texture_count;
                sampler_count = state.shader.sampler_count;

                fprintf(pandecode_dump_stream, "  Properties\n");
                if (is_bifrost) {
                        pan_unpack(&state.properties, BIFROST_PROPERTIES, bi_props);
                        DUMP_UNPACKED(BIFROST_PROPERTIES, bi_props, "Properties:\n");

                        uniform_count = state.preload.uniform_count;
                        uniform_buffer_count = bi_props.uniform_buffer_count;
                } else {
                        pan_unpack(&state.properties, MIDGARD_PROPERTIES, midg_props);
                        DUMP_UNPACKED(MIDGARD_PROPERTIES, midg_props, "Properties:\n")

                        uniform_count = midg_props.uniform_count;
                        uniform_buffer_count = midg_props.uniform_buffer_count;
                }

                pandecode_shader_prop("texture_count", texture_count, info.texture_count, false);
                pandecode_shader_prop("sampler_count", sampler_count, info.sampler_count, false);
                pandecode_shader_prop("attribute_count", attribute_count, info.attribute_count, false);
                pandecode_shader_prop("varying_count", varying_count, info.varying_count, false);

                if (is_bifrost) {
                        uint32_t opaque = state.preload.uniform_count << 15
                                | state.preload.untyped;

                        switch (job_type) {
                        case MALI_JOB_TYPE_VERTEX:
                                DUMP_CL(PRELOAD_VERTEX, &opaque, "Preload:\n");
                                break;
                        case MALI_JOB_TYPE_TILER:
                                DUMP_CL(PRELOAD_FRAGMENT, &opaque, "Preload:\n");
                                break;
                        case MALI_JOB_TYPE_COMPUTE:
                                DUMP_CL(PRELOAD_COMPUTE, &opaque, "Preload:\n");
                                break;
                        default:
                                DUMP_CL(PRELOAD, &opaque, "Preload:\n");
                                break;
                        }
                }

                if (!is_bifrost) {
                        /* TODO: Blend shaders routing/disasm */
                        union midgard_blend blend;
                        memcpy(&blend, &state.sfbd_blend, sizeof(blend));
                        mali_ptr shader = pandecode_midgard_blend(&blend, state.multisample_misc.sfbd_blend_shader);
                        if (shader & ~0xF)
                                pandecode_blend_shader_disassemble(shader, job_no, job_type, false, gpu_id);
                }
                pandecode_indent--;
                pandecode_msg("\n");

                /* MRT blend fields are used whenever MFBD is used, with
                 * per-RT descriptors */

                if (job_type == MALI_JOB_TYPE_TILER && (is_bifrost || p->shared & MALI_MFBD)) {
                        void* blend_base = ((void *) cl) + MALI_STATE_LENGTH;

                        for (unsigned i = 0; i < fbd_info.rt_count; i++) {
                                mali_ptr shader = 0;

                                if (is_bifrost)
                                        shader = pandecode_bifrost_blend(blend_base, job_no, i);
                                else
                                        shader = pandecode_midgard_blend_mrt(blend_base, job_no, i);

                                if (shader & ~0xF)
                                        pandecode_blend_shader_disassemble(shader, job_no, job_type, false, gpu_id);

                        }
                }
        } else
                pandecode_msg("XXX: missing shader descriptor\n");

        if (p->viewport)
                DUMP_ADDR(VIEWPORT, p->viewport, "Viewport:\n");

        unsigned max_attr_index = 0;

        if (p->attributes)
                max_attr_index = pandecode_attribute_meta(attribute_count, p->attributes, false, suffix);

        if (p->attribute_buffers) {
                attr_mem = pandecode_find_mapped_gpu_mem_containing(p->attribute_buffers);
                pandecode_attributes(attr_mem, p->attribute_buffers, job_no, suffix, max_attr_index, false, job_type);
        }

        if (p->varyings) {
                varying_count = pandecode_attribute_meta(varying_count, p->varyings, true, suffix);
        }

        if (p->varying_buffers) {
                attr_mem = pandecode_find_mapped_gpu_mem_containing(p->varying_buffers);
                pandecode_attributes(attr_mem, p->varying_buffers, job_no, suffix, varying_count, true, job_type);
        }

        if (p->uniform_buffers) {
                if (uniform_buffer_count)
                        pandecode_uniform_buffers(p->uniform_buffers, uniform_buffer_count, job_no);
                else
                        pandecode_msg("warn: UBOs specified but not referenced\n");
        } else if (uniform_buffer_count)
                pandecode_msg("XXX: UBOs referenced but not specified\n");

        /* We don't want to actually dump uniforms, but we do need to validate
         * that the counts we were given are sane */

        if (p->push_uniforms) {
                if (uniform_count)
                        pandecode_uniforms(p->push_uniforms, uniform_count);
                else
                        pandecode_msg("warn: Uniforms specified but not referenced\n");
        } else if (uniform_count)
                pandecode_msg("XXX: Uniforms referenced but not specified\n");

        if (p->textures)
                pandecode_textures(p->textures, texture_count, job_no, is_bifrost);

        if (p->samplers)
                pandecode_samplers(p->samplers, sampler_count, job_no, is_bifrost);
}

static void
pandecode_bifrost_tiler_heap(mali_ptr gpu_va, int job_no)
{
        struct pandecode_mapped_memory *mem = pandecode_find_mapped_gpu_mem_containing(gpu_va);
        pan_unpack(PANDECODE_PTR(mem, gpu_va, void), BIFROST_TILER_HEAP, h);
        DUMP_UNPACKED(BIFROST_TILER_HEAP, h, "Bifrost Tiler Heap:\n");
}

static void
pandecode_bifrost_tiler(mali_ptr gpu_va, int job_no)
{
        struct pandecode_mapped_memory *mem = pandecode_find_mapped_gpu_mem_containing(gpu_va);
        pan_unpack(PANDECODE_PTR(mem, gpu_va, void), BIFROST_TILER, t);

        pandecode_bifrost_tiler_heap(t.heap, job_no);

        DUMP_UNPACKED(BIFROST_TILER, t, "Bifrost Tiler:\n");
        pandecode_indent++;
        if (t.hierarchy_mask != 0xa &&
            t.hierarchy_mask != 0x14 &&
            t.hierarchy_mask != 0x28 &&
            t.hierarchy_mask != 0x50 &&
            t.hierarchy_mask != 0xa0)
                pandecode_prop("XXX: Unexpected hierarchy_mask (not 0xa, 0x14, 0x28, 0x50 or 0xa0)!");

        pandecode_indent--;
}

static void
pandecode_primitive_size(union midgard_primitive_size u, bool constant)
{
        if (u.pointer == 0x0)
                return;

        pandecode_log(".primitive_size = {\n");
        pandecode_indent++;

        if (constant) {
                pandecode_prop("constant = %f", u.constant);
        } else {
                MEMORY_PROP((&u), pointer);
        }

        pandecode_indent--;
        pandecode_log("},\n");
}

static int
pandecode_vertex_job_bfr(const struct mali_job_descriptor_header *h,
                                const struct pandecode_mapped_memory *mem,
                                mali_ptr payload, int job_no, unsigned gpu_id)
{
        struct bifrost_payload_vertex *PANDECODE_PTR_VAR(v, mem, payload);

        struct mali_draw_packed draw_packed;
        memcpy(&draw_packed, &v->postfix, sizeof(draw_packed));
        pan_unpack(&draw_packed, DRAW, draw);
        pandecode_vertex_tiler_postfix_pre(&draw, job_no, h->job_type, "", true, gpu_id);

        pandecode_vertex_tiler_prefix(&v->prefix, job_no, false);
        DUMP_CL(DRAW, &draw_packed, "Draw:\n");

        return sizeof(*v);
}

static int
pandecode_tiler_job_bfr(const struct mali_job_descriptor_header *h,
                               const struct pandecode_mapped_memory *mem,
                               mali_ptr payload, int job_no, unsigned gpu_id)
{
        struct bifrost_payload_tiler *PANDECODE_PTR_VAR(t, mem, payload);

        struct mali_draw_packed draw_packed;
        memcpy(&draw_packed, &t->postfix, sizeof(draw_packed));
        pan_unpack(&draw_packed, DRAW, draw);
        pandecode_vertex_tiler_postfix_pre(&draw, job_no, h->job_type, "", true, gpu_id);
        pandecode_bifrost_tiler(t->tiler_meta, job_no);

        pandecode_vertex_tiler_prefix(&t->prefix, job_no, false);

        /* TODO: gl_PointSize on Bifrost */
        pandecode_primitive_size(t->primitive_size, true);

        if (t->zero1 || t->zero2 || t->zero3 || t->zero4 || t->zero5
            || t->zero6) {
                pandecode_msg("XXX: tiler only zero tripped\n");
                pandecode_prop("zero1 = 0x%" PRIx64, t->zero1);
                pandecode_prop("zero2 = 0x%" PRIx64, t->zero2);
                pandecode_prop("zero3 = 0x%" PRIx64, t->zero3);
                pandecode_prop("zero4 = 0x%" PRIx64, t->zero4);
                pandecode_prop("zero5 = 0x%" PRIx64, t->zero5);
                pandecode_prop("zero6 = 0x%" PRIx64, t->zero6);
        }

        DUMP_CL(DRAW, &draw_packed, "Draw:\n");

        return sizeof(*t);
}

static int
pandecode_vertex_or_tiler_job_mdg(const struct mali_job_descriptor_header *h,
                const struct pandecode_mapped_memory *mem,
                mali_ptr payload, int job_no, unsigned gpu_id)
{
        struct midgard_payload_vertex_tiler *PANDECODE_PTR_VAR(v, mem, payload);
        bool is_graphics = (h->job_type == MALI_JOB_TYPE_VERTEX) || (h->job_type == MALI_JOB_TYPE_TILER);

        struct mali_draw_packed draw_packed;
        memcpy(&draw_packed, &v->postfix, sizeof(draw_packed));
        pan_unpack(&draw_packed, DRAW, draw);
        pandecode_vertex_tiler_postfix_pre(&draw, job_no, h->job_type, "", false, gpu_id);

        pandecode_vertex_tiler_prefix(&v->prefix, job_no, is_graphics);
        DUMP_CL(DRAW, &draw_packed, "Draw:\n");

        struct mali_primitive_packed prim_packed = v->prefix.primitive;
        pan_unpack(&prim_packed, PRIMITIVE, primitive);

        pandecode_primitive_size(v->primitive_size, primitive.point_size_array == 0);

        return sizeof(*v);
}

static int
pandecode_fragment_job(const struct pandecode_mapped_memory *mem,
                              mali_ptr payload, int job_no,
                              bool is_bifrost, unsigned gpu_id)
{
        const struct mali_payload_fragment *PANDECODE_PTR_VAR(s, mem, payload);

        bool is_mfbd = s->framebuffer & MALI_MFBD;

        if (!is_mfbd && is_bifrost)
                pandecode_msg("XXX: Bifrost fragment must use MFBD\n");

        struct pandecode_fbd info;

        if (is_mfbd)
                info = pandecode_mfbd_bfr(s->framebuffer & FBD_MASK, job_no, true, false, is_bifrost);
        else
                info = pandecode_sfbd(s->framebuffer & FBD_MASK, job_no, true, gpu_id);

        /* Compute the tag for the tagged pointer. This contains the type of
         * FBD (MFBD/SFBD), and in the case of an MFBD, information about which
         * additional structures follow the MFBD header (an extra payload or
         * not, as well as a count of render targets) */

        unsigned expected_tag = is_mfbd ? MALI_MFBD : 0;

        if (is_mfbd) {
                if (info.has_extra)
                        expected_tag |= MALI_MFBD_TAG_EXTRA;

                expected_tag |= (MALI_POSITIVE(info.rt_count) << 2);
        }

        if ((s->min_tile_coord | s->max_tile_coord) & ~(MALI_X_COORD_MASK | MALI_Y_COORD_MASK)) {
                pandecode_msg("XXX: unexpected tile coordinate bits\n");
                pandecode_prop("min_tile_coord = 0x%X\n", s->min_tile_coord);
                pandecode_prop("max_tile_coord = 0x%X\n", s->max_tile_coord);
        }

        /* Extract tile coordinates */

        unsigned min_x = MALI_TILE_COORD_X(s->min_tile_coord) << MALI_TILE_SHIFT;
        unsigned min_y = MALI_TILE_COORD_Y(s->min_tile_coord) << MALI_TILE_SHIFT;

        unsigned max_x = (MALI_TILE_COORD_X(s->max_tile_coord) + 1) << MALI_TILE_SHIFT;
        unsigned max_y = (MALI_TILE_COORD_Y(s->max_tile_coord) + 1) << MALI_TILE_SHIFT;

        /* For the max, we also want the floored (rather than ceiled) version for checking */

        unsigned max_x_f = (MALI_TILE_COORD_X(s->max_tile_coord)) << MALI_TILE_SHIFT;
        unsigned max_y_f = (MALI_TILE_COORD_Y(s->max_tile_coord)) << MALI_TILE_SHIFT;

        /* Validate the coordinates are well-ordered */

        if (min_x == max_x)
                pandecode_msg("XXX: empty X coordinates (%u = %u)\n", min_x, max_x);
        else if (min_x > max_x)
                pandecode_msg("XXX: misordered X coordinates (%u > %u)\n", min_x, max_x);

        if (min_y == max_y)
                pandecode_msg("XXX: empty X coordinates (%u = %u)\n", min_x, max_x);
        else if (min_y > max_y)
                pandecode_msg("XXX: misordered X coordinates (%u > %u)\n", min_x, max_x);

        /* Validate the coordinates fit inside the framebuffer. We use floor,
         * rather than ceil, for the max coordinates, since the tile
         * coordinates for something like an 800x600 framebuffer will actually
         * resolve to 800x608, which would otherwise trigger a Y-overflow */

        if ((min_x > info.width) || (max_x_f > info.width))
                pandecode_msg("XXX: tile coordinates overflow in X direction\n");

        if ((min_y > info.height) || (max_y_f > info.height))
                pandecode_msg("XXX: tile coordinates overflow in Y direction\n");

        /* After validation, we print */

        pandecode_log("fragment (%u, %u) ... (%u, %u)\n\n", min_x, min_y, max_x, max_y);

        /* The FBD is a tagged pointer */

        unsigned tag = (s->framebuffer & ~FBD_MASK);

        if (tag != expected_tag)
                pandecode_msg("XXX: expected FBD tag %X but got %X\n", expected_tag, tag);

        return sizeof(*s);
}

/* Entrypoint to start tracing. jc_gpu_va is the GPU address for the first job
 * in the chain; later jobs are found by walking the chain. Bifrost is, well,
 * if it's bifrost or not. GPU ID is the more finegrained ID (at some point, we
 * might wish to combine this with the bifrost parameter) because some details
 * are model-specific even within a particular architecture. Minimal traces
 * *only* examine the job descriptors, skipping printing entirely if there is
 * no faults, and only descends into the payload if there are faults. This is
 * useful for looking for faults without the overhead of invasive traces. */

void
pandecode_jc(mali_ptr jc_gpu_va, bool bifrost, unsigned gpu_id, bool minimal)
{
        pandecode_dump_file_open();

        struct mali_job_descriptor_header *h;
        unsigned job_descriptor_number = 0;

        do {
                struct pandecode_mapped_memory *mem =
                        pandecode_find_mapped_gpu_mem_containing(jc_gpu_va);

                void *payload;

                h = PANDECODE_PTR(mem, jc_gpu_va, struct mali_job_descriptor_header);

                mali_ptr payload_ptr = jc_gpu_va + sizeof(*h);
                payload = pandecode_fetch_gpu_mem(mem, payload_ptr, 64);

                int job_no = job_descriptor_number++;

                /* If the job is good to go, skip it in minimal mode */
                if (minimal && (h->exception_status == 0x0 || h->exception_status == 0x1))
                        continue;

                pandecode_log("struct mali_job_descriptor_header job_%"PRIx64"_%d = {\n", jc_gpu_va, job_no);
                pandecode_indent++;

                pandecode_prop("job_type = %s", mali_job_type_as_str(h->job_type));

                if (h->job_descriptor_size)
                        pandecode_prop("job_descriptor_size = %d", h->job_descriptor_size);

                if (h->exception_status && h->exception_status != 0x1)
                        pandecode_prop("exception_status = %x (source ID: 0x%x access: %s exception: 0x%x)",
                                       h->exception_status,
                                       (h->exception_status >> 16) & 0xFFFF,
                                       mali_exception_access_as_str((h->exception_status >> 8) & 0x3),
                                       h->exception_status  & 0xFF);

                if (h->first_incomplete_task)
                        pandecode_prop("first_incomplete_task = %d", h->first_incomplete_task);

                if (h->fault_pointer)
                        pandecode_prop("fault_pointer = 0x%" PRIx64, h->fault_pointer);

                if (h->job_barrier)
                        pandecode_prop("job_barrier = %d", h->job_barrier);

                pandecode_prop("job_index = %d", h->job_index);

                if (h->unknown_flags)
                        pandecode_prop("unknown_flags = %d", h->unknown_flags);

                if (h->job_dependency_index_1)
                        pandecode_prop("job_dependency_index_1 = %d", h->job_dependency_index_1);

                if (h->job_dependency_index_2)
                        pandecode_prop("job_dependency_index_2 = %d", h->job_dependency_index_2);

                pandecode_indent--;
                pandecode_log("};\n");

                switch (h->job_type) {
                case MALI_JOB_TYPE_WRITE_VALUE: {
                        struct mali_payload_write_value *s = payload;
                        pandecode_log("struct mali_payload_write_value payload_%"PRIx64"_%d = {\n", payload_ptr, job_no);
                        pandecode_indent++;
                        MEMORY_PROP(s, address);

                        if (s->value_descriptor != MALI_WRITE_VALUE_ZERO) {
                                pandecode_msg("XXX: unknown value descriptor\n");
                                pandecode_prop("value_descriptor = 0x%" PRIX32, s->value_descriptor);
                        }

                        if (s->reserved) {
                                pandecode_msg("XXX: set value tripped\n");
                                pandecode_prop("reserved = 0x%" PRIX32, s->reserved);
                        }

                        pandecode_prop("immediate = 0x%" PRIX64, s->immediate);
                        pandecode_indent--;
                        pandecode_log("};\n");

                        break;
                }

                case MALI_JOB_TYPE_TILER:
                case MALI_JOB_TYPE_VERTEX:
                case MALI_JOB_TYPE_COMPUTE:
                        if (bifrost) {
                                if (h->job_type == MALI_JOB_TYPE_TILER)
                                        pandecode_tiler_job_bfr(h, mem, payload_ptr, job_no, gpu_id);
                                else
                                        pandecode_vertex_job_bfr(h, mem, payload_ptr, job_no, gpu_id);
                        } else
                                pandecode_vertex_or_tiler_job_mdg(h, mem, payload_ptr, job_no, gpu_id);

                        break;

                case MALI_JOB_TYPE_FRAGMENT:
                        pandecode_fragment_job(mem, payload_ptr, job_no, bifrost, gpu_id);
                        break;

                default:
                        break;
                }
        } while ((jc_gpu_va = h->next_job));

        pandecode_map_read_write();
}
