X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fpanfrost%2Flib%2Fdecode.c;h=f0bf60287d8120607763455a5a12f343fb740f66;hb=2425bac8fee69db464adfe24a0fcb38737f28b4f;hp=6d13333d83a3de2b3cbf6a3a1f05a179493e22a8;hpb=32dbc80979e18d119105e46cb37c4bc9890fb6a9;p=mesa.git diff --git a/src/panfrost/lib/decode.c b/src/panfrost/lib/decode.c index 6d13333d83a..f0bf60287d8 100644 --- a/src/panfrost/lib/decode.c +++ b/src/panfrost/lib/decode.c @@ -61,12 +61,18 @@ static void pandecode_swizzle(unsigned swizzle, enum mali_format format); fprintf(pandecode_dump_stream, "%s\n", title); \ struct MALI_ ## T temp; \ MALI_ ## T ## _unpack((const uint8_t *) cl, &temp); \ - MALI_ ## T ## _print(pandecode_dump_stream, &temp, 0); \ + MALI_ ## T ## _print(pandecode_dump_stream, &temp, indent * 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(title, T, addr, indent) {\ - struct pandecode_mapped_memory *mapped_mem = pandecode_find_mapped_gpu_mem_containing(addr); \ - const uint8_t *cl = pandecode_fetch_gpu_mem(mapped_mem, addr, MALI_ ## T ## _LENGTH); \ + MAP_ADDR(T, addr, cl) \ DUMP_CL(title, T, cl, indent); \ } @@ -202,17 +208,6 @@ pandecode_log_decoded_flags(const struct pandecode_flag_info *flag_info, } } -#define FLAG_INFO(flag) { MALI_##flag, "MALI_" #flag } -static const struct pandecode_flag_info gl_enable_flag_info[] = { - FLAG_INFO(OCCLUSION_QUERY), - FLAG_INFO(OCCLUSION_PRECISE), - FLAG_INFO(FRONT_CCW_TOP), - FLAG_INFO(CULL_FACE_FRONT), - FLAG_INFO(CULL_FACE_BACK), - {} -}; -#undef FLAG_INFO - #define FLAG_INFO(flag) { MALI_CLEAR_##flag, "MALI_CLEAR_" #flag } static const struct pandecode_flag_info clear_flag_info[] = { FLAG_INFO(FAST), @@ -222,39 +217,6 @@ static const struct pandecode_flag_info clear_flag_info[] = { }; #undef FLAG_INFO -#define FLAG_INFO(flag) { MALI_MASK_##flag, "MALI_MASK_" #flag } -static const struct pandecode_flag_info mask_flag_info[] = { - FLAG_INFO(R), - FLAG_INFO(G), - FLAG_INFO(B), - FLAG_INFO(A), - {} -}; -#undef FLAG_INFO - -#define FLAG_INFO(flag) { MALI_##flag, "MALI_" #flag } -static const struct pandecode_flag_info u3_flag_info[] = { - FLAG_INFO(HAS_MSAA), - FLAG_INFO(PER_SAMPLE), - FLAG_INFO(CAN_DISCARD), - FLAG_INFO(HAS_BLEND_SHADER), - FLAG_INFO(DEPTH_WRITEMASK), - FLAG_INFO(DEPTH_CLIP_NEAR), - FLAG_INFO(DEPTH_CLIP_FAR), - {} -}; - -static const struct pandecode_flag_info u4_flag_info[] = { - FLAG_INFO(NO_MSAA), - FLAG_INFO(NO_DITHER), - FLAG_INFO(DEPTH_RANGE_A), - FLAG_INFO(DEPTH_RANGE_B), - FLAG_INFO(STENCIL_TEST), - FLAG_INFO(ALPHA_TO_COVERAGE), - {} -}; -#undef FLAG_INFO - #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), @@ -283,33 +245,6 @@ static const struct pandecode_flag_info mfbd_extra_flag_lo_info[] = { }; #undef FLAG_INFO -#define FLAG_INFO(flag) { MALI_##flag, "MALI_" #flag } -static const struct pandecode_flag_info shader_midgard1_flag_lo_info [] = { - FLAG_INFO(WRITES_Z), - FLAG_INFO(EARLY_Z), - FLAG_INFO(READS_TILEBUFFER), - FLAG_INFO(WRITES_GLOBAL), - FLAG_INFO(READS_ZS), - {} -}; - -static const struct pandecode_flag_info shader_midgard1_flag_hi_info [] = { - FLAG_INFO(WRITES_S), - FLAG_INFO(SUPPRESS_INF_NAN), - {} -}; -#undef FLAG_INFO - -#define FLAG_INFO(flag) { MALI_BIFROST_##flag, "MALI_BIFROST_" #flag } -static const struct pandecode_flag_info shader_bifrost_info [] = { - FLAG_INFO(FULL_THREAD), - FLAG_INFO(EARLY_Z), - FLAG_INFO(FIRST_ATEST), - {} -}; - -#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), @@ -318,17 +253,6 @@ static const struct pandecode_flag_info mfbd_flag_info [] = { }; #undef FLAG_INFO -#define FLAG_INFO(flag) { MALI_SAMP_##flag, "MALI_SAMP_" #flag } -static const struct pandecode_flag_info sampler_flag_info [] = { - FLAG_INFO(MAG_NEAREST), - FLAG_INFO(MIN_NEAREST), - FLAG_INFO(MIP_LINEAR_1), - FLAG_INFO(MIP_LINEAR_2), - FLAG_INFO(NORM_COORDS), - {} -}; -#undef FLAG_INFO - #define FLAG_INFO(flag) { MALI_SFBD_FORMAT_##flag, "MALI_SFBD_FORMAT_" #flag } static const struct pandecode_flag_info sfbd_unk1_info [] = { FLAG_INFO(MSAA_8), @@ -345,278 +269,6 @@ static const struct pandecode_flag_info sfbd_unk2_info [] = { }; #undef FLAG_INFO -#define DEFINE_CASE(name) case MALI_## name: return "MALI_" #name -static char *pandecode_format(enum mali_format format) -{ - static char unk_format_str[10]; - - switch (format) { - DEFINE_CASE(ETC2_RGB8); - DEFINE_CASE(ETC2_R11_UNORM); - DEFINE_CASE(ETC2_RGBA8); - DEFINE_CASE(ETC2_RG11_UNORM); - DEFINE_CASE(ETC2_R11_SNORM); - DEFINE_CASE(ETC2_RG11_SNORM); - DEFINE_CASE(ETC2_RGB8A1); - DEFINE_CASE(NXR); - DEFINE_CASE(BC1_UNORM); - DEFINE_CASE(BC2_UNORM); - DEFINE_CASE(BC3_UNORM); - DEFINE_CASE(BC4_UNORM); - DEFINE_CASE(BC4_SNORM); - DEFINE_CASE(BC5_UNORM); - DEFINE_CASE(BC5_SNORM); - DEFINE_CASE(BC6H_UF16); - DEFINE_CASE(BC6H_SF16); - DEFINE_CASE(BC7_UNORM); - DEFINE_CASE(ASTC_3D_LDR); - DEFINE_CASE(ASTC_3D_HDR); - DEFINE_CASE(ASTC_2D_LDR); - DEFINE_CASE(ASTC_2D_HDR); - DEFINE_CASE(RGB565); - DEFINE_CASE(RGB5_X1_UNORM); - DEFINE_CASE(RGB5_A1_UNORM); - DEFINE_CASE(RGB10_A2_UNORM); - DEFINE_CASE(RGB10_A2_SNORM); - DEFINE_CASE(RGB10_A2UI); - DEFINE_CASE(RGB10_A2I); - DEFINE_CASE(RGB332_UNORM); - DEFINE_CASE(RGB233_UNORM); - DEFINE_CASE(Z24X8_UNORM); - DEFINE_CASE(R32_FIXED); - DEFINE_CASE(RG32_FIXED); - DEFINE_CASE(RGB32_FIXED); - DEFINE_CASE(RGBA32_FIXED); - DEFINE_CASE(R11F_G11F_B10F); - DEFINE_CASE(R9F_G9F_B9F_E5F); - DEFINE_CASE(VARYING_POS); - DEFINE_CASE(VARYING_DISCARD); - - DEFINE_CASE(R8_SNORM); - DEFINE_CASE(R16_SNORM); - DEFINE_CASE(R32_SNORM); - DEFINE_CASE(RG8_SNORM); - DEFINE_CASE(RG16_SNORM); - DEFINE_CASE(RG32_SNORM); - DEFINE_CASE(RGB8_SNORM); - DEFINE_CASE(RGB16_SNORM); - DEFINE_CASE(RGB32_SNORM); - DEFINE_CASE(RGBA8_SNORM); - DEFINE_CASE(RGBA16_SNORM); - DEFINE_CASE(RGBA32_SNORM); - - DEFINE_CASE(R8UI); - DEFINE_CASE(R16UI); - DEFINE_CASE(R32UI); - DEFINE_CASE(RG8UI); - DEFINE_CASE(RG16UI); - DEFINE_CASE(RG32UI); - DEFINE_CASE(RGB8UI); - DEFINE_CASE(RGB16UI); - DEFINE_CASE(RGB32UI); - DEFINE_CASE(RGBA8UI); - DEFINE_CASE(RGBA16UI); - DEFINE_CASE(RGBA32UI); - - DEFINE_CASE(R8_UNORM); - DEFINE_CASE(R16_UNORM); - DEFINE_CASE(R32_UNORM); - DEFINE_CASE(R32F); - DEFINE_CASE(RG8_UNORM); - DEFINE_CASE(RG16_UNORM); - DEFINE_CASE(RG32_UNORM); - DEFINE_CASE(RG32F); - DEFINE_CASE(RGB8_UNORM); - DEFINE_CASE(RGB16_UNORM); - DEFINE_CASE(RGB32_UNORM); - DEFINE_CASE(RGB32F); - DEFINE_CASE(RGBA4_UNORM); - DEFINE_CASE(RGBA8_UNORM); - DEFINE_CASE(RGBA16_UNORM); - DEFINE_CASE(RGBA32_UNORM); - DEFINE_CASE(RGBA32F); - - DEFINE_CASE(R8I); - DEFINE_CASE(R16I); - DEFINE_CASE(R32I); - DEFINE_CASE(RG8I); - DEFINE_CASE(R16F); - DEFINE_CASE(RG16I); - DEFINE_CASE(RG32I); - DEFINE_CASE(RG16F); - DEFINE_CASE(RGB8I); - DEFINE_CASE(RGB16I); - DEFINE_CASE(RGB32I); - DEFINE_CASE(RGB16F); - DEFINE_CASE(RGBA8I); - DEFINE_CASE(RGBA16I); - DEFINE_CASE(RGBA32I); - DEFINE_CASE(RGBA16F); - - DEFINE_CASE(RGBA4); - DEFINE_CASE(RGBA8_2); - DEFINE_CASE(RGB10_A2_2); - default: - snprintf(unk_format_str, sizeof(unk_format_str), "MALI_0x%02x", format); - return unk_format_str; - } -} - -#undef DEFINE_CASE - -#define DEFINE_CASE(name) case MALI_FUNC_ ## name: return "MALI_FUNC_" #name -static char * -pandecode_func(enum mali_func mode) -{ - switch (mode) { - DEFINE_CASE(NEVER); - DEFINE_CASE(LESS); - DEFINE_CASE(EQUAL); - DEFINE_CASE(LEQUAL); - DEFINE_CASE(GREATER); - DEFINE_CASE(NOTEQUAL); - DEFINE_CASE(GEQUAL); - DEFINE_CASE(ALWAYS); - - default: - pandecode_msg("XXX: invalid func %X\n", mode); - return ""; - } -} -#undef DEFINE_CASE - -#define DEFINE_CASE(name) case MALI_MSAA_ ## name: return "MALI_MSAA_" #name -static char * -pandecode_msaa_mode(enum mali_msaa_mode mode) -{ - switch (mode) { - DEFINE_CASE(SINGLE); - DEFINE_CASE(AVERAGE); - DEFINE_CASE(MULTIPLE); - DEFINE_CASE(LAYERED); - default: - unreachable("Impossible"); - return ""; - } -} -#undef DEFINE_CASE - -#define DEFINE_CASE(name) case MALI_STENCIL_ ## name: return "MALI_STENCIL_" #name -static char * -pandecode_stencil_op(enum mali_stencil_op op) -{ - switch (op) { - DEFINE_CASE(KEEP); - DEFINE_CASE(REPLACE); - DEFINE_CASE(ZERO); - DEFINE_CASE(INVERT); - DEFINE_CASE(INCR_WRAP); - DEFINE_CASE(DECR_WRAP); - DEFINE_CASE(INCR); - DEFINE_CASE(DECR); - - default: - pandecode_msg("XXX: invalid stencil op %X\n", op); - return ""; - } -} - -#undef DEFINE_CASE - -static char *pandecode_attr_mode_short(enum mali_attr_mode mode) -{ - switch(mode) { - /* TODO: Combine to just "instanced" once this can be done - * unambiguously in all known cases */ - case MALI_ATTR_POT_DIVIDE: - return "instanced_pot"; - case MALI_ATTR_MODULO: - return "instanced_mod"; - case MALI_ATTR_NPOT_DIVIDE: - return "instanced_npot"; - case MALI_ATTR_IMAGE: - return "image"; - default: - pandecode_msg("XXX: invalid attribute mode %X\n", mode); - return ""; - } -} - -static const char * -pandecode_special_record(uint64_t v, bool* attribute) -{ - switch(v) { - case MALI_ATTR_VERTEXID: - *attribute = true; - return "gl_VertexID"; - case MALI_ATTR_INSTANCEID: - *attribute = true; - return "gl_InstanceID"; - case MALI_VARYING_FRAG_COORD: - return "gl_FragCoord"; - case MALI_VARYING_FRONT_FACING: - return "gl_FrontFacing"; - case MALI_VARYING_POINT_COORD: - return "gl_PointCoord"; - default: - pandecode_msg("XXX: invalid special record %" PRIx64 "\n", v); - return ""; - } -} - -#define DEFINE_CASE(name) case MALI_WRAP_## name: return "MALI_WRAP_" #name -static char * -pandecode_wrap_mode(enum mali_wrap_mode op) -{ - switch (op) { - DEFINE_CASE(REPEAT); - DEFINE_CASE(CLAMP_TO_EDGE); - DEFINE_CASE(CLAMP); - DEFINE_CASE(CLAMP_TO_BORDER); - DEFINE_CASE(MIRRORED_REPEAT); - DEFINE_CASE(MIRRORED_CLAMP_TO_EDGE); - DEFINE_CASE(MIRRORED_CLAMP); - DEFINE_CASE(MIRRORED_CLAMP_TO_BORDER); - - default: - pandecode_msg("XXX: invalid wrap mode %X\n", op); - return ""; - } -} -#undef DEFINE_CASE - -#define DEFINE_CASE(name) case MALI_BLOCK_## name: return "MALI_BLOCK_" #name -static char * -pandecode_block_format(enum mali_block_format fmt) -{ - switch (fmt) { - DEFINE_CASE(TILED); - DEFINE_CASE(UNKNOWN); - DEFINE_CASE(LINEAR); - DEFINE_CASE(AFBC); - - default: - unreachable("Invalid case"); - } -} -#undef DEFINE_CASE - -#define DEFINE_CASE(name) case MALI_EXCEPTION_ACCESS_## name: return ""#name -static char * -pandecode_exception_access(unsigned access) -{ - switch (access) { - DEFINE_CASE(NONE); - DEFINE_CASE(EXECUTE); - DEFINE_CASE(READ); - DEFINE_CASE(WRITE); - - default: - unreachable("Invalid case"); - } -} -#undef DEFINE_CASE - /* Midgard's tiler descriptor is embedded within the * larger FBD */ @@ -670,9 +322,6 @@ pandecode_midgard_tiler_descriptor( MEMORY_PROP(t, heap_start); assert(t->heap_end >= t->heap_start); - struct pandecode_mapped_memory *heap = - pandecode_find_mapped_gpu_mem_containing(t->heap_start); - unsigned heap_size = t->heap_end - t->heap_start; /* Tiling is enabled with a special flag */ @@ -682,13 +331,6 @@ pandecode_midgard_tiler_descriptor( bool tiling_enabled = hierarchy_mask; if (tiling_enabled) { - /* When tiling is enabled, the heap should be a tight fit */ - unsigned heap_offset = t->heap_start - heap->gpu_va; - if ((heap_offset + heap_size) != heap->length) { - pandecode_msg("XXX: heap size %u (expected %zu)\n", - heap_size, heap->length - heap_offset); - } - /* We should also have no other flags */ if (tiler_flags) pandecode_msg("XXX: unexpected tiler %X\n", tiler_flags); @@ -793,7 +435,7 @@ pandecode_sfbd_format(struct mali_sfbd_format format) pandecode_log_decoded_flags(sfbd_unk2_info, format.unk2); pandecode_log_cont(",\n"); - pandecode_prop("block = %s", pandecode_block_format(format.block)); + pandecode_prop("block = %s", mali_block_format_as_str(format.block)); pandecode_prop("unk3 = 0x%" PRIx32, format.unk3); @@ -834,14 +476,6 @@ pandecode_shared_memory(const struct mali_shared_memory *desc, bool is_compute) MEMORY_PROP(desc, scratchpad); MEMORY_PROP(desc, shared_memory); MEMORY_PROP(desc, unknown1); - - if (desc->scratchpad) { - struct pandecode_mapped_memory *smem = - pandecode_find_mapped_gpu_mem_containing(desc->scratchpad); - - pandecode_msg("scratchpad size %u\n", smem->length); - } - } static struct pandecode_fbd @@ -997,12 +631,12 @@ static unsigned pandecode_access_mask_from_channel_swizzle(unsigned swizzle) { unsigned mask = 0; - assert(MALI_CHANNEL_RED == 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_ALPHA) + if (chan <= MALI_CHANNEL_A) mask |= (1 << chan); } @@ -1031,42 +665,15 @@ pandecode_validate_format_swizzle(enum mali_format fmt, unsigned swizzle) * 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) + 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]); } -/* Maps MALI_RGBA32F to rgba32f, etc */ - -static void -pandecode_format_short(enum mali_format fmt, bool srgb) -{ - /* 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]); - - /* Sanity check sRGB flag is applied to RGB, per the name */ - if (srgb && lower_format[0] != 'r') - pandecode_msg("XXX: sRGB applied to non-colour format\n"); - - /* Just prefix with an s, so you get formats like srgba8_unorm */ - if (srgb) - pandecode_log_cont("s"); - - pandecode_log_cont("%s", lower_format); - free(lower_format); -} - static void pandecode_swizzle(unsigned swizzle, enum mali_format format) { @@ -1085,7 +692,7 @@ pandecode_swizzle(unsigned swizzle, enum mali_format format) for (unsigned c = 0; c < 4; ++c) { enum mali_channel chan = (swizzle >> (3 * c)) & 0x7; - if (chan >= MALI_CHANNEL_RESERVED_0) { + if (chan > MALI_CHANNEL_1) { pandecode_log("XXX: invalid swizzle channel %d\n", chan); continue; } @@ -1104,7 +711,7 @@ pandecode_rt_format(struct mali_rt_format format) pandecode_prop("unk3 = 0x%" PRIx32, format.unk3); pandecode_prop("unk4 = 0x%" PRIx32, format.unk4); - pandecode_prop("block = %s", pandecode_block_format(format.block)); + 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"); @@ -1118,7 +725,7 @@ pandecode_rt_format(struct mali_rt_format format) pandecode_log_decoded_flags(mfbd_fmt_flag_info, format.flags); pandecode_log_cont(",\n"); - pandecode_prop("msaa = %s", pandecode_msaa_mode(format.msaa)); + 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 @@ -1155,7 +762,7 @@ pandecode_render_target(uint64_t gpu_va, unsigned job_no, const struct mali_fram pandecode_rt_format(rt->format); - if (rt->format.block == MALI_BLOCK_AFBC) { + if (rt->format.block == MALI_BLOCK_FORMAT_AFBC) { pandecode_log(".afbc = {\n"); pandecode_indent++; @@ -1336,10 +943,10 @@ pandecode_mfbd_bfr(uint64_t gpu_va, int job_no, bool is_fragment, bool is_comput pandecode_log_decoded_flags(mfbd_extra_flag_lo_info, fbx->flags_lo); pandecode_log_cont(",\n"); - pandecode_prop("zs_block = %s", pandecode_block_format(fbx->zs_block)); + 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_AFBC) { + if (fbx->zs_block == MALI_BLOCK_FORMAT_AFBC) { pandecode_log(".ds_afbc = {\n"); pandecode_indent++; @@ -1418,108 +1025,12 @@ pandecode_mfbd_bfr(uint64_t gpu_va, int job_no, bool is_fragment, bool is_comput return info; } -/* Just add a comment decoding the shift/odd fields forming the padded vertices - * count */ - -static void -pandecode_padded_vertices(unsigned shift, unsigned k) -{ - unsigned odd = 2*k + 1; - unsigned pot = 1 << shift; - pandecode_msg("padded_num_vertices = %d\n", odd * pot); -} - -/* Given a magic divisor, recover what we were trying to divide by. - * - * Let m represent the magic divisor. By definition, m is an element on Z, whre - * 0 <= m < 2^N, for N bits in m. - * - * Let q represent the number we would like to divide by. - * - * By definition of a magic divisor for N-bit unsigned integers (a number you - * multiply by to magically get division), m is a number such that: - * - * (m * x) & (2^N - 1) = floor(x/q). - * for all x on Z where 0 <= x < 2^N - * - * Ignore the case where any of the above values equals zero; it is irrelevant - * for our purposes (instanced arrays). - * - * Choose x = q. Then: - * - * (m * x) & (2^N - 1) = floor(x/q). - * (m * q) & (2^N - 1) = floor(q/q). - * - * floor(q/q) = floor(1) = 1, therefore: - * - * (m * q) & (2^N - 1) = 1 - * - * Recall the identity that the bitwise AND of one less than a power-of-two - * equals the modulo with that power of two, i.e. for all x: - * - * x & (2^N - 1) = x % N - * - * Therefore: - * - * mq % (2^N) = 1 - * - * By definition, a modular multiplicative inverse of a number m is the number - * q such that with respect to a modulos M: - * - * mq % M = 1 - * - * Therefore, q is the modular multiplicative inverse of m with modulus 2^N. - * - */ - -static void -pandecode_magic_divisor(uint32_t magic, unsigned shift, unsigned orig_divisor, unsigned extra) -{ -#if 0 - /* Compute the modular inverse of `magic` with respect to 2^(32 - - * shift) the most lame way possible... just repeatedly add. - * Asymptoptically slow but nobody cares in practice, unless you have - * massive numbers of vertices or high divisors. */ - - unsigned inverse = 0; - - /* Magic implicitly has the highest bit set */ - magic |= (1 << 31); - - /* Depending on rounding direction */ - if (extra) - magic++; - - for (;;) { - uint32_t product = magic * inverse; - - if (shift) { - product >>= shift; - } - - if (product == 1) - break; - - ++inverse; - } - - pandecode_msg("dividing by %d (maybe off by two)\n", inverse); - - /* Recall we're supposed to divide by (gl_level_divisor * - * padded_num_vertices) */ - - unsigned padded_num_vertices = inverse / orig_divisor; - - pandecode_msg("padded_num_vertices = %d\n", padded_num_vertices); -#endif -} - 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"; + char *prefix = varying ? "Varying" : "Attribute"; assert(addr); if (!count) { @@ -1527,116 +1038,21 @@ pandecode_attributes(const struct pandecode_mapped_memory *mem, return; } - union mali_attr *attr = pandecode_fetch_gpu_mem(mem, addr, sizeof(union mali_attr) * count); + MAP_ADDR(ATTRIBUTE_BUFFER, addr, cl); for (int i = 0; i < count; ++i) { - /* First, check for special records */ - if (attr[i].elements < MALI_RECORD_SPECIAL) { - if (attr[i].size) - pandecode_msg("XXX: tripped size=%d\n", attr[i].size); - - if (attr[i].stride) { - /* gl_InstanceID passes a magic divisor in the - * stride field to divide by the padded vertex - * count. No other records should do so, so - * stride should otherwise be zero. Note that - * stride in the usual attribute sense doesn't - * apply to special records. */ - - bool has_divisor = attr[i].elements == MALI_ATTR_INSTANCEID; - - pandecode_log_cont("/* %smagic divisor = %X */ ", - has_divisor ? "" : "XXX: ", attr[i].stride); - } - - if (attr[i].shift || attr[i].extra_flags) { - /* Attributes use these fields for - * instancing/padding/etc type issues, but - * varyings don't */ - - pandecode_log_cont("/* %sshift=%d, extra=%d */ ", - varying ? "XXX: " : "", - attr[i].shift, attr[i].extra_flags); - } - - /* Print the special record name */ - bool attribute = false; - pandecode_log("%s_%d = %s;\n", prefix, i, pandecode_special_record(attr[i].elements, &attribute)); - - /* Sanity check */ - if (attribute == varying) - pandecode_msg("XXX: mismatched special record\n"); + fprintf(pandecode_dump_stream, "%s\n", prefix); - continue; - } - - enum mali_attr_mode mode = attr[i].elements & 7; - - if (mode == MALI_ATTR_UNUSED) - pandecode_msg("XXX: unused attribute record\n"); - - /* For non-linear records, we need to print the type of record */ - if (mode != MALI_ATTR_LINEAR) - pandecode_log_cont("%s ", pandecode_attr_mode_short(mode)); - - /* Print the name to link with attr_meta */ - pandecode_log_cont("%s_%d", prefix, i); - - /* Print the stride and size */ - pandecode_log_cont("<%u>[%u]", attr[i].stride, attr[i].size); - - /* TODO: Sanity check the quotient itself. It must be equal to - * (or be greater than, if the driver added padding) the padded - * vertex count. */ - - /* Finally, print the pointer */ - mali_ptr raw_elements = attr[i].elements & ~7; - char *a = pointer_as_memory_reference(raw_elements); - pandecode_log_cont(" = (%s);\n", a); - free(a); - - /* Check the pointer */ - pandecode_validate_buffer(raw_elements, attr[i].size); - - /* shift/extra_flags exist only for instanced */ - if (attr[i].shift | attr[i].extra_flags) { - /* These are set to random values by the blob for - * varyings, most likely a symptom of uninitialized - * memory where the hardware masked the bug. As such we - * put this at a warning, not an error. */ - - if (mode == MALI_ATTR_LINEAR) - pandecode_msg("warn: instancing fields set for linear\n"); - - pandecode_prop("shift = %d", attr[i].shift); - pandecode_prop("extra_flags = %d", attr[i].extra_flags); - } + struct MALI_ATTRIBUTE_BUFFER temp; + MALI_ATTRIBUTE_BUFFER_unpack(cl + i * MALI_ATTRIBUTE_BUFFER_LENGTH, &temp); + MALI_ATTRIBUTE_BUFFER_print(pandecode_dump_stream, &temp, 2); - /* Decode further where possible */ - - if (mode == MALI_ATTR_MODULO) { - pandecode_padded_vertices( - attr[i].shift, - attr[i].extra_flags); - } - - if (mode == MALI_ATTR_NPOT_DIVIDE) { - i++; - pandecode_log("{\n"); - pandecode_indent++; - pandecode_prop("unk = 0x%x", attr[i].unk); - pandecode_prop("magic_divisor = 0x%08x", attr[i].magic_divisor); - if (attr[i].zero != 0) - pandecode_prop("XXX: zero tripped (0x%x)\n", attr[i].zero); - pandecode_prop("divisor = %d", attr[i].divisor); - pandecode_magic_divisor(attr[i].magic_divisor, attr[i - 1].shift, attr[i].divisor, attr[i - 1].extra_flags); - pandecode_indent--; - pandecode_log("}, \n"); + if (temp.type == MALI_ATTRIBUTE_TYPE_1D_NPOT_DIVISOR) { + struct MALI_ATTRIBUTE_BUFFER_CONTINUATION_NPOT temp2; + MALI_ATTRIBUTE_BUFFER_CONTINUATION_NPOT_unpack(cl + (i + 1) * MALI_ATTRIBUTE_BUFFER_LENGTH, &temp2); + MALI_ATTRIBUTE_BUFFER_CONTINUATION_NPOT_print(pandecode_dump_stream, &temp2, 2); } - } - - pandecode_log("\n"); } static mali_ptr @@ -1652,56 +1068,6 @@ pandecode_shader_address(const char *name, mali_ptr ptr) return shader_ptr; } -static void -pandecode_stencil(const char *name, const struct mali_stencil_test *stencil) -{ - unsigned any_nonzero = - stencil->ref | stencil->mask | stencil->func | - stencil->sfail | stencil->dpfail | stencil->dppass; - - if (any_nonzero == 0) - return; - - const char *func = pandecode_func(stencil->func); - const char *sfail = pandecode_stencil_op(stencil->sfail); - const char *dpfail = pandecode_stencil_op(stencil->dpfail); - const char *dppass = pandecode_stencil_op(stencil->dppass); - - if (stencil->zero) - pandecode_msg("XXX: stencil zero tripped: %X\n", stencil->zero); - - pandecode_log(".stencil_%s = {\n", name); - pandecode_indent++; - pandecode_prop("ref = %d", stencil->ref); - pandecode_prop("mask = 0x%02X", stencil->mask); - pandecode_prop("func = %s", func); - pandecode_prop("sfail = %s", sfail); - pandecode_prop("dpfail = %s", dpfail); - pandecode_prop("dppass = %s", dppass); - pandecode_indent--; - pandecode_log("},\n"); -} - -static void -pandecode_blend_equation(const struct mali_blend_equation *blend) -{ - if (blend->zero1) - pandecode_msg("XXX: blend zero tripped: %X\n", blend->zero1); - - pandecode_log(".equation = {\n"); - pandecode_indent++; - - pandecode_prop("rgb_mode = 0x%X", blend->rgb_mode); - pandecode_prop("alpha_mode = 0x%X", blend->alpha_mode); - - pandecode_log(".color_mask = "); - pandecode_log_decoded_flags(mask_flag_info, blend->color_mask); - pandecode_log_cont(",\n"); - - pandecode_indent--; - pandecode_log("},\n"); -} - /* Decodes a Bifrost blend constant. See the notes in bifrost_blend_rt */ static unsigned @@ -1727,13 +1093,12 @@ pandecode_bifrost_blend(void *descs, int job_no, int rt_no) b->constant, decode_bifrost_constant(b->constant)); /* TODO figure out blend shader enable bit */ - pandecode_blend_equation(&b->equation); + DUMP_CL("Equation", BLEND_EQUATION, &b->equation, 2); pandecode_prop("unk2 = 0x%" PRIx16, b->unk2); pandecode_prop("index = 0x%" PRIx16, b->index); - pandecode_log(".format = "); - pandecode_format_short(b->format, false); + pandecode_log(".format = %s", mali_format_as_str(b->format)); pandecode_swizzle(b->swizzle, b->format); pandecode_log_cont(",\n"); @@ -1794,7 +1159,7 @@ pandecode_midgard_blend(union midgard_blend *blend, bool is_shader) if (is_shader) { pandecode_shader_address("shader", blend->shader); } else { - pandecode_blend_equation(&blend->equation); + DUMP_CL("Equation", BLEND_EQUATION, &blend->equation, 2); pandecode_prop("constant = %f", blend->constant); } @@ -1812,12 +1177,12 @@ pandecode_midgard_blend_mrt(void *descs, int job_no, int rt_no) ((struct midgard_blend_rt *) descs) + rt_no; /* Flags determine presence of blend shader */ - bool is_shader = (b->flags & 0xF) >= 0x2; + 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++; - pandecode_prop("flags = 0x%" PRIx64, b->flags); + DUMP_CL("Flags", BLEND_FLAGS, &b->flags, 2); union midgard_blend blend = b->blend; mali_ptr shader = pandecode_midgard_blend(&blend, is_shader); @@ -1834,81 +1199,14 @@ pandecode_midgard_blend_mrt(void *descs, int job_no, int rt_no) */ static int -pandecode_attribute_meta(int job_no, int count, const struct mali_vertex_tiler_postfix *v, bool varying, char *suffix) +pandecode_attribute_meta(int count, mali_ptr attribute, bool varying, char *suffix) { - char base[128]; - char *prefix = varying ? "varying" : "attribute"; - unsigned max_index = 0; - snprintf(base, sizeof(base), "%s_meta", prefix); - - struct mali_attr_meta *attr_meta; - mali_ptr p = varying ? v->varying_meta : v->attribute_meta; - - struct pandecode_mapped_memory *attr_mem = pandecode_find_mapped_gpu_mem_containing(p); - - for (int i = 0; i < count; ++i, p += sizeof(struct mali_attr_meta)) { - attr_meta = pandecode_fetch_gpu_mem(attr_mem, p, - sizeof(*attr_mem)); - - /* If the record is discard, it should be zero for everything else */ - - if (attr_meta->format == MALI_VARYING_DISCARD) { - uint64_t zero = - attr_meta->index | - attr_meta->unknown1 | - attr_meta->unknown3 | - attr_meta->src_offset; - - if (zero) - pandecode_msg("XXX: expected empty record for varying discard\n"); - - /* We want to look for a literal 0000 swizzle -- this - * is not encoded with all zeroes, however */ - - enum mali_channel z = MALI_CHANNEL_ZERO; - unsigned zero_swizzle = z | (z << 3) | (z << 6) | (z << 9); - bool good_swizzle = attr_meta->swizzle == zero_swizzle; - - if (!good_swizzle) - pandecode_msg("XXX: expected zero swizzle for discard\n"); - - if (!varying) - pandecode_msg("XXX: cannot discard attribute\n"); - - /* If we're all good, omit the record */ - if (!zero && varying && good_swizzle) { - pandecode_log("/* discarded varying */\n"); - continue; - } - } + const char *prefix = varying ? "Varying" : "Attribute"; - if (attr_meta->index > max_index) - max_index = attr_meta->index; + for (int i = 0; i < count; ++i, attribute += MALI_ATTRIBUTE_LENGTH) + DUMP_ADDR(prefix, ATTRIBUTE, attribute, 1); - if (attr_meta->unknown1 != 0x2) { - pandecode_msg("XXX: expected unknown1 = 0x2\n"); - pandecode_prop("unknown1 = 0x%" PRIx64, (u64) attr_meta->unknown1); - } - - if (attr_meta->unknown3) { - pandecode_msg("XXX: unexpected unknown3 set\n"); - pandecode_prop("unknown3 = 0x%" PRIx64, (u64) attr_meta->unknown3); - } - - pandecode_format_short(attr_meta->format, false); - 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_log("\n"); - - return count ? (max_index + 1) : 0; + return count; } /* return bits [lo, hi) of word */ @@ -1930,21 +1228,17 @@ pandecode_vertex_tiler_prefix(struct mali_vertex_tiler_prefix *p, int job_no, bo /* Decode invocation_count. See the comment before the definition of * invocation_count for an explanation. */ + struct MALI_INVOCATION invocation; + struct mali_invocation_packed invocation_packed = p->invocation; + MALI_INVOCATION_unpack((const uint8_t *) &invocation_packed, &invocation); - unsigned size_y_shift = bits(p->invocation_shifts, 0, 5); - unsigned size_z_shift = bits(p->invocation_shifts, 5, 10); - unsigned workgroups_x_shift = bits(p->invocation_shifts, 10, 16); - unsigned workgroups_y_shift = bits(p->invocation_shifts, 16, 22); - unsigned workgroups_z_shift = bits(p->invocation_shifts, 22, 28); - unsigned workgroups_x_shift_2 = bits(p->invocation_shifts, 28, 32); - - unsigned size_x = bits(p->invocation_count, 0, size_y_shift) + 1; - unsigned size_y = bits(p->invocation_count, size_y_shift, size_z_shift) + 1; - unsigned size_z = bits(p->invocation_count, size_z_shift, workgroups_x_shift) + 1; + 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(p->invocation_count, workgroups_x_shift, workgroups_y_shift) + 1; - unsigned groups_y = bits(p->invocation_count, workgroups_y_shift, workgroups_z_shift) + 1; - unsigned groups_z = bits(p->invocation_count, workgroups_z_shift, 32) + 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 @@ -1954,76 +1248,44 @@ pandecode_vertex_tiler_prefix(struct mali_vertex_tiler_prefix *p, int job_no, bo * decode and pack it ourselves! If it is bit exact with what we * decoded, we're good to go. */ - struct mali_vertex_tiler_prefix ref; + struct mali_invocation_packed ref; panfrost_pack_work_groups_compute(&ref, groups_x, groups_y, groups_z, size_x, size_y, size_z, graphics); - bool canonical = - (p->invocation_count == ref.invocation_count) && - (p->invocation_shifts == ref.invocation_shifts); - - if (!canonical) { + if (memcmp(&ref, &invocation_packed, sizeof(ref))) { pandecode_msg("XXX: non-canonical workgroups packing\n"); - pandecode_msg("expected: %X, %X", - ref.invocation_count, - ref.invocation_shifts); - - pandecode_prop("invocation_count = 0x%" PRIx32, p->invocation_count); - pandecode_prop("size_y_shift = %d", size_y_shift); - pandecode_prop("size_z_shift = %d", size_z_shift); - pandecode_prop("workgroups_x_shift = %d", workgroups_x_shift); - pandecode_prop("workgroups_y_shift = %d", workgroups_y_shift); - pandecode_prop("workgroups_z_shift = %d", workgroups_z_shift); - pandecode_prop("workgroups_x_shift_2 = %d", workgroups_x_shift_2); + MALI_INVOCATION_print(pandecode_dump_stream, &invocation, 1 * 2); } /* Regardless, print the decode */ - pandecode_msg("size (%d, %d, %d), count (%d, %d, %d)\n", + fprintf(pandecode_dump_stream, + "Invocation (%d, %d, %d) x (%d, %d, %d)\n", size_x, size_y, size_z, groups_x, groups_y, groups_z); - /* TODO: Decode */ - if (p->unknown_draw) - pandecode_prop("unknown_draw = 0x%" PRIx32, p->unknown_draw); - - pandecode_prop("workgroups_x_shift_3 = 0x%" PRIx32, p->workgroups_x_shift_3); - - if (p->draw_mode != MALI_DRAW_MODE_NONE) - pandecode_prop("draw_mode = %s", mali_draw_mode_as_str(p->draw_mode)); - - /* Index count only exists for tiler jobs anyway */ - - if (p->index_count) - pandecode_prop("index_count = MALI_POSITIVE(%" PRId32 ")", p->index_count + 1); - - - unsigned index_raw_size = (p->unknown_draw & MALI_DRAW_INDEXED_SIZE); - index_raw_size >>= MALI_DRAW_INDEXED_SHIFT; + fprintf(pandecode_dump_stream, "Primitive\n"); + struct MALI_PRIMITIVE primitive; + struct mali_primitive_packed prim_packed = p->primitive; + MALI_PRIMITIVE_unpack((const uint8_t *) &prim_packed, &primitive); + MALI_PRIMITIVE_print(pandecode_dump_stream, &primitive, 1 * 2); /* Validate an index buffer is present if we need one. TODO: verify * relationship between invocation_count and index_count */ - if (p->indices) { - unsigned count = p->index_count; - + if (primitive.indices) { /* Grab the size */ - unsigned size = (index_raw_size == 0x3) ? 4 : index_raw_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 (!index_raw_size) + if (!size) pandecode_msg("XXX: index size missing\n"); else - pandecode_validate_buffer(p->indices, count * size); - } else if (index_raw_size) - pandecode_msg("XXX: unexpected index size %u\n", index_raw_size); - - if (p->offset_bias_correction) - pandecode_prop("offset_bias_correction = %d", p->offset_bias_correction); - - /* TODO: Figure out what this is. It's not zero */ - pandecode_prop("zero1 = 0x%" PRIx32, p->zero1); + pandecode_validate_buffer(primitive.indices, primitive.index_count * size); + } else if (primitive.index_type) + pandecode_msg("XXX: unexpected index size\n"); pandecode_indent--; pandecode_log("},\n"); @@ -2066,8 +1328,7 @@ shader_type_for_job(unsigned 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"; + default: return "UNKNOWN"; } } @@ -2113,33 +1374,25 @@ pandecode_shader_disassemble(mali_ptr shader_ptr, int shader_no, int type, MESA_SHADER_FRAGMENT : MESA_SHADER_VERTEX); } - /* Print shader-db stats. Skip COMPUTE jobs since they are used for - * driver-internal purposes with the blob and interfere */ - - bool should_shaderdb = type != MALI_JOB_TYPE_COMPUTE; - - if (should_shaderdb) { - 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); - } + 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_type type, + enum mali_texture_dimension dim, enum mali_texture_layout layout, bool manual_stride, uint8_t levels, @@ -2159,14 +1412,14 @@ pandecode_texture_payload(mali_ptr payload, int bitmap_count = levels + 1; /* Miptree for each face */ - if (type == MALI_TEX_CUBE) + if (dim == MALI_TEXTURE_DIMENSION_CUBE) bitmap_count *= 6; /* Array of layers */ - bitmap_count *= (depth + 1); + bitmap_count *= depth; /* Array of textures */ - bitmap_count *= (array_size + 1); + bitmap_count *= array_size; /* Stride for each element */ if (manual_stride) @@ -2200,228 +1453,31 @@ pandecode_texture(mali_ptr u, struct pandecode_mapped_memory *tmem, unsigned job_no, unsigned tex) { - struct mali_texture_descriptor *PANDECODE_PTR_VAR(t, tmem, u); - - pandecode_log("struct mali_texture_descriptor texture_descriptor_%"PRIx64"_%d_%d = {\n", u, job_no, tex); - pandecode_indent++; - - pandecode_prop("width = %" PRId32, t->width); - pandecode_prop("height = %" PRId32, t->height); - pandecode_prop("depth = %" PRId32, t->depth); - pandecode_prop("array_size = %" PRId32, t->array_size); + 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); - pandecode_log("\n"); - pandecode_prop("f.swizzle = 0x%" PRIx32, t->format.swizzle); - pandecode_prop("f.format = 0x%" PRIx32, t->format.format); - pandecode_prop("f.srgb = 0x%" PRIx32, t->format.srgb); - pandecode_prop("f.unknown1 = 0x%" PRIx32, t->format.unknown1); - pandecode_prop("f.type = %" PRId32, t->format.type); - pandecode_prop("f.layout = %" PRId32, t->format.layout); - pandecode_prop("f.unknown2 = 0x%" PRIx32, t->format.unknown2); - pandecode_prop("f.manual_stride = %" PRId32, t->format.manual_stride); - pandecode_prop("f.zero = 0x%" PRIx32, t->format.zero); - pandecode_log("\n"); - - pandecode_prop("unknown3 = 0x%" PRIx32, t->unknown3); - pandecode_prop("unknown3A = 0x%" PRIx32, t->unknown3A); - pandecode_prop("levels = %" PRId32, t->levels); - pandecode_prop("swizzle = 0x%" PRIx32, t->swizzle); - pandecode_prop("swizzle_zero = 0x%" PRIx32, t->swizzle_zero); - - pandecode_prop("unknown5 = 0x%" PRIx32, t->unknown5); - pandecode_prop("unknown6 = 0x%" PRIx32, t->unknown6); - pandecode_prop("unknown7 = 0x%" PRIx32, t->unknown7); - pandecode_log("\n"); - - struct mali_texture_format f = t->format; - - /* See the definiton of enum mali_texture_type */ - - bool is_cube = f.type == MALI_TEX_CUBE; - unsigned dimension = is_cube ? 2 : f.type; - - pandecode_make_indent(); - - /* Print the layout. Default is linear; a modifier can denote AFBC or - * u-interleaved/tiled modes */ - - if (f.layout == MALI_TEXTURE_AFBC) - pandecode_log_cont("afbc"); - else if (f.layout == MALI_TEXTURE_TILED) - pandecode_log_cont("tiled"); - else if (f.layout == MALI_TEXTURE_LINEAR) - pandecode_log_cont("linear"); - else - pandecode_msg("XXX: invalid texture layout 0x%X\n", f.layout); - - pandecode_swizzle(t->swizzle, f.format); - pandecode_log_cont(" "); - - /* Distinguish cube/2D with modifier */ - - if (is_cube) - pandecode_log_cont("cube "); + struct MALI_MIDGARD_TEXTURE temp; + MALI_MIDGARD_TEXTURE_unpack(cl, &temp); + MALI_MIDGARD_TEXTURE_print(pandecode_dump_stream, &temp, 2); - pandecode_format_short(f.format, f.srgb); - pandecode_swizzle(f.swizzle, f.format); - - /* All four width/height/depth/array_size dimensions are present - * regardless of the type of texture, but it is an error to have - * non-zero dimensions for unused dimensions. Verify this. array_size - * can always be set, as can width. Depth used for MSAA. */ - - if (t->height && dimension < 2) - pandecode_msg("XXX: nonzero height for <2D texture\n"); - - /* Print only the dimensions that are actually there */ - - pandecode_log_cont(": %d", t->width + 1); - - if (t->height || t->depth) - pandecode_log_cont("x%u", t->height + 1); - - if (t->depth) - pandecode_log_cont("x%u", t->depth + 1); - - if (t->array_size) - pandecode_log_cont("[%u]", t->array_size + 1); - - if (t->levels) - pandecode_log_cont(" mip %u", t->levels); - - pandecode_log_cont("\n"); - - if (f.unknown1 | f.zero) { - pandecode_msg("XXX: texture format zero tripped\n"); - pandecode_prop("unknown1 = %" PRId32, f.unknown1); - pandecode_prop("zero = %" PRId32, f.zero); - } - - if (!f.unknown2) { - pandecode_msg("XXX: expected unknown texture bit set\n"); - pandecode_prop("unknown2 = %" PRId32, f.unknown2); - } - - if (t->swizzle_zero) { - pandecode_msg("XXX: swizzle zero tripped\n"); - pandecode_prop("swizzle_zero = %d", t->swizzle_zero); - } - - if (t->unknown3 | t->unknown3A | t->unknown5 | t->unknown6 | t->unknown7) { - pandecode_msg("XXX: texture zero tripped\n"); - pandecode_prop("unknown3 = %" PRId16, t->unknown3); - pandecode_prop("unknown3A = %" PRId8, t->unknown3A); - pandecode_prop("unknown5 = 0x%" PRIx32, t->unknown5); - pandecode_prop("unknown6 = 0x%" PRIx32, t->unknown6); - pandecode_prop("unknown7 = 0x%" PRIx32, t->unknown7); - } - - pandecode_texture_payload(u + sizeof(*t), f.type, f.layout, f.manual_stride, t->levels, t->depth, t->array_size, tmem); - - pandecode_indent--; - pandecode_log("};\n"); + 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); } static void pandecode_bifrost_texture( - const struct bifrost_texture_descriptor *t, + const void *cl, unsigned job_no, unsigned tex) { - pandecode_log("struct bifrost_texture_descriptor texture_descriptor_%d_%d = {\n", job_no, tex); - pandecode_indent++; - - pandecode_prop("format_unk = 0x%" PRIx32, t->format_unk); - pandecode_prop("type = %" PRId32, t->type); - - if (t->zero) { - pandecode_msg("XXX: zero tripped\n"); - pandecode_prop("zero = 0x%" PRIx32, t->zero); - } - - pandecode_prop("format_swizzle = 0x%" PRIx32, t->format_swizzle); - pandecode_prop("format = 0x%" PRIx32, t->format); - pandecode_prop("srgb = 0x%" PRIx32, t->srgb); - pandecode_prop("format_unk3 = 0x%" PRIx32, t->format_unk3); - pandecode_prop("width = %" PRId32, t->width); - pandecode_prop("height = %" PRId32, t->height); - pandecode_prop("swizzle = 0x%" PRIx32, t->swizzle); - pandecode_prop("levels = %" PRId32, t->levels); - pandecode_prop("unk1 = 0x%" PRIx32, t->unk1); - pandecode_prop("levels_unk = %" PRId32, t->levels_unk); - pandecode_prop("level_2 = %" PRId32, t->level_2); - pandecode_prop("payload = 0x%" PRIx64, t->payload); - pandecode_prop("array_size = %" PRId32, t->array_size); - pandecode_prop("unk4 = 0x%" PRIx32, t->unk4); - pandecode_prop("depth = %" PRId32, t->depth); - pandecode_prop("unk5 = 0x%" PRIx32, t->unk5); - pandecode_log("\n"); - - /* See the definiton of enum mali_texture_type */ - - bool is_cube = t->type == MALI_TEX_CUBE; - unsigned dimension = is_cube ? 2 : t->type; - - /* Print the layout. Default is linear; a modifier can denote AFBC or - * u-interleaved/tiled modes */ - - if (t->layout == MALI_TEXTURE_AFBC) - pandecode_log_cont("afbc"); - else if (t->layout == MALI_TEXTURE_TILED) - pandecode_log_cont("tiled"); - else if (t->layout == MALI_TEXTURE_LINEAR) - pandecode_log_cont("linear"); - else - pandecode_msg("XXX: invalid texture layout 0x%X\n", t->layout); - - pandecode_swizzle(t->swizzle, t->format); - pandecode_log_cont(" "); - - /* Distinguish cube/2D with modifier */ - - if (is_cube) - pandecode_log_cont("cube "); - - pandecode_format_short(t->format, t->srgb); - - /* All four width/height/depth/array_size dimensions are present - * regardless of the type of texture, but it is an error to have - * non-zero dimensions for unused dimensions. Verify this. array_size - * can always be set, as can width. */ - - if (t->height && dimension < 2) - pandecode_msg("XXX: nonzero height for <2D texture\n"); - - if (t->depth && dimension < 3) - pandecode_msg("XXX: nonzero depth for <2D texture\n"); - - /* Print only the dimensions that are actually there */ - - pandecode_log_cont(": %d", t->width + 1); - - if (dimension >= 2) - pandecode_log_cont("x%u", t->height + 1); - - if (dimension >= 3) - pandecode_log_cont("x%u", t->depth + 1); - - if (t->array_size) - pandecode_log_cont("[%u]", t->array_size + 1); - - if (t->levels) - pandecode_log_cont(" mip %u", t->levels); + struct MALI_BIFROST_TEXTURE temp; + MALI_BIFROST_TEXTURE_unpack(cl, &temp); + MALI_BIFROST_TEXTURE_print(pandecode_dump_stream, &temp, 2); - pandecode_log_cont("\n"); - - struct pandecode_mapped_memory *tmem = pandecode_find_mapped_gpu_mem_containing(t->payload); - if (t->payload) { - pandecode_texture_payload(t->payload, t->type, t->layout, - true, t->levels, t->depth, - t->array_size, tmem); - } - - pandecode_indent--; - pandecode_log("};\n"); + struct pandecode_mapped_memory *tmem = pandecode_find_mapped_gpu_mem_containing(temp.surfaces); + pandecode_texture_payload(temp.surfaces, temp.dimension, temp.texel_ordering, + true, temp.levels, 1, 1, tmem); } /* 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 */ @@ -2487,23 +1543,21 @@ pandecode_textures(mali_ptr textures, unsigned texture_count, int job_no, bool i if (!mmem) return; - if (is_bifrost) { - const struct bifrost_texture_descriptor *PANDECODE_PTR_VAR(t, mmem, textures); - - pandecode_log("uint64_t textures_%"PRIx64"_%d[] = {\n", textures, job_no); - pandecode_indent++; + pandecode_log("Textures (%"PRIx64"):\n", textures); - for (unsigned tex = 0; tex < texture_count; ++tex) - pandecode_bifrost_texture(&t[tex], job_no, tex); + if (is_bifrost) { + const void *cl = pandecode_fetch_gpu_mem(mmem, + textures, MALI_BIFROST_TEXTURE_LENGTH * + texture_count); - pandecode_indent--; - pandecode_log("};\n"); + 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); - pandecode_log("uint64_t textures_%"PRIx64"_%d[] = {\n", textures, job_no); - pandecode_indent++; - 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); @@ -2511,9 +1565,6 @@ pandecode_textures(mali_ptr textures, unsigned texture_count, int job_no, bool i free(a); } - pandecode_indent--; - pandecode_log("};\n"); - /* 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)); @@ -2527,93 +1578,11 @@ pandecode_textures(mali_ptr textures, unsigned texture_count, int job_no, bool i static void pandecode_samplers(mali_ptr samplers, unsigned sampler_count, int job_no, bool is_bifrost) { - struct pandecode_mapped_memory *smem = pandecode_find_mapped_gpu_mem_containing(samplers); - - if (!smem) - return; - - if (is_bifrost) { - struct bifrost_sampler_descriptor *s; - - for (int i = 0; i < sampler_count; ++i) { - s = pandecode_fetch_gpu_mem(smem, samplers + sizeof(*s) * i, sizeof(*s)); - - pandecode_log("struct bifrost_sampler_descriptor sampler_descriptor_%"PRIx64"_%d_%d = {\n", samplers + sizeof(*s) * i, job_no, i); - pandecode_indent++; - - if (s->unk1 != 1) { - pandecode_msg("XXX: unk1 tripped\n"); - pandecode_prop("unk1 = 0x%x", s->unk1); - } - - pandecode_prop("wrap_s = %s", pandecode_wrap_mode(s->wrap_s)); - pandecode_prop("wrap_t = %s", pandecode_wrap_mode(s->wrap_t)); - pandecode_prop("wrap_r = %s", pandecode_wrap_mode(s->wrap_r)); - - if (s->unk8 != 0x8) { - pandecode_msg("XXX: unk8 tripped\n"); - pandecode_prop("unk8 = 0x%x", s->unk8); - } - - pandecode_prop("unk2 = 0x%x", s->unk2); - pandecode_prop("unk3 = 0x%x", s->unk3); - pandecode_prop("min_filter = %s", s->min_filter ? "nearest" : "linear"); - pandecode_prop("norm_coords = 0x%x", s->norm_coords & 0x1); - pandecode_prop("zero1 = 0x%x", s->zero1 & 0x1); - pandecode_prop("mip_filter = %s", s->mip_filter ? "linear" : "nearest"); - pandecode_prop("mag_filter = %s", s->mag_filter ? "linear" : "nearest"); - - pandecode_prop("min_lod = FIXED_16(%f)", DECODE_FIXED_16(s->min_lod)); - pandecode_prop("max_lod = FIXED_16(%f)", DECODE_FIXED_16(s->max_lod)); - - if (s->zero1 || s->zero2 || s->zero3 || s->zero4) { - pandecode_msg("XXX: sampler zero tripped\n"); - pandecode_prop("zero = 0x%" PRIx8 ", 0x%" PRIx64 ", 0x%" PRIx64 ", 0x%" PRIx64 "\n", s->zero1, s->zero2, s->zero3, s->zero4); - } - - pandecode_indent--; - pandecode_log("};\n"); - } - } else { - struct mali_sampler_descriptor *s; - - for (int i = 0; i < sampler_count; ++i) { - s = pandecode_fetch_gpu_mem(smem, samplers + sizeof(*s) * i, sizeof(*s)); - - pandecode_log("struct mali_sampler_descriptor sampler_descriptor_%"PRIx64"_%d_%d = {\n", samplers + sizeof(*s) * i, job_no, i); - pandecode_indent++; - - pandecode_log(".filter_mode = "); - pandecode_log_decoded_flags(sampler_flag_info, s->filter_mode); - pandecode_log_cont(",\n"); - - pandecode_prop("min_lod = FIXED_16(%f)", DECODE_FIXED_16(s->min_lod)); - pandecode_prop("max_lod = FIXED_16(%f)", DECODE_FIXED_16(s->max_lod)); - - if (s->lod_bias) - pandecode_prop("lod_bias = FIXED_16(%f)", DECODE_FIXED_16(s->lod_bias)); - - pandecode_prop("wrap_s = %s", pandecode_wrap_mode(s->wrap_s)); - pandecode_prop("wrap_t = %s", pandecode_wrap_mode(s->wrap_t)); - pandecode_prop("wrap_r = %s", pandecode_wrap_mode(s->wrap_r)); - - pandecode_prop("compare_func = %s", pandecode_func(s->compare_func)); - - if (s->zero || s->zero2) { - pandecode_msg("XXX: sampler zero tripped\n"); - pandecode_prop("zero = 0x%X, 0x%X\n", s->zero, s->zero2); - } - - pandecode_prop("seamless_cube_map = %d", s->seamless_cube_map); - - pandecode_prop("border_color = { %f, %f, %f, %f }", - s->border_color[0], - s->border_color[1], - s->border_color[2], - s->border_color[3]); - - pandecode_indent--; - pandecode_log("};\n"); + for (int i = 0; i < sampler_count; ++i) { + if (is_bifrost) { + DUMP_ADDR("Sampler", BIFROST_SAMPLER, samplers + (MALI_BIFROST_SAMPLER_LENGTH * i), 1); + } else { + DUMP_ADDR("Sampler", MIDGARD_SAMPLER, samplers + (MALI_MIDGARD_SAMPLER_LENGTH * i), 1); } } } @@ -2652,7 +1621,7 @@ pandecode_vertex_tiler_postfix_pre( if (p->shader) { struct pandecode_mapped_memory *smem = pandecode_find_mapped_gpu_mem_containing(p->shader); - struct mali_shader_meta *PANDECODE_PTR_VAR(s, smem, p->shader); + uint32_t *cl = pandecode_fetch_gpu_mem(smem, p->shader, MALI_STATE_LENGTH); /* Disassemble ahead-of-time to get stats. Initialize with * stats for the missing-shader case so we get validation @@ -2669,152 +1638,78 @@ pandecode_vertex_tiler_postfix_pre( .uniform_buffer_count = 0 }; - if (s->shader & ~0xF) - info = pandecode_shader_disassemble(s->shader & ~0xF, job_no, job_type, is_bifrost, gpu_id); + struct MALI_STATE state; + struct MALI_MIDGARD_PROPERTIES midg_props; + struct MALI_BIFROST_PROPERTIES bi_props; - pandecode_log("struct mali_shader_meta shader_meta_%"PRIx64"_%d%s = {\n", p->shader, job_no, suffix); - pandecode_indent++; + MALI_STATE_unpack((const uint8_t *) cl, &state); - /* Save for dumps */ - attribute_count = s->attribute_count; - varying_count = s->varying_count; - texture_count = s->texture_count; - sampler_count = s->sampler_count; + if (state.shader.shader & ~0xF) + info = pandecode_shader_disassemble(state.shader.shader & ~0xF, job_no, job_type, is_bifrost, gpu_id); - if (is_bifrost) { - uniform_count = s->bifrost2.uniform_count; - uniform_buffer_count = s->bifrost1.uniform_buffer_count; - } else { - uniform_count = s->midgard1.uniform_count; - uniform_buffer_count = s->midgard1.uniform_buffer_count; - } - - pandecode_shader_address("shader", s->shader); - - pandecode_shader_prop("texture_count", s->texture_count, info.texture_count, false); - pandecode_shader_prop("sampler_count", s->sampler_count, info.sampler_count, false); - pandecode_shader_prop("attribute_count", s->attribute_count, info.attribute_count, false); - pandecode_shader_prop("varying_count", s->varying_count, info.varying_count, false); - pandecode_shader_prop("uniform_buffer_count", - uniform_buffer_count, - info.uniform_buffer_count, true); + fprintf(pandecode_dump_stream, "State %"PRIx64"\n", p->shader); + MALI_STATE_print(pandecode_dump_stream, &state, 1 * 2); - if (!is_bifrost) { - pandecode_shader_prop("uniform_count", - uniform_count, - info.uniform_count, false); - - pandecode_shader_prop("work_count", - s->midgard1.work_count, info.work_count, false); - } + /* 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) { - pandecode_log("bifrost1.unk1 = "); - pandecode_log_decoded_flags(shader_bifrost_info, s->bifrost1.unk1); - pandecode_log_cont(",\n"); - } else { - bool helpers = s->midgard1.flags_lo & MALI_HELPER_INVOCATIONS; - - if (helpers != info.helper_invocations) { - pandecode_msg("XXX: expected helpers %u but got %u\n", - info.helper_invocations, helpers); - } - - pandecode_log(".midgard1.flags_lo = "); - pandecode_log_decoded_flags(shader_midgard1_flag_lo_info, - s->midgard1.flags_lo & ~MALI_HELPER_INVOCATIONS); - pandecode_log_cont(",\n"); - - pandecode_log(".midgard1.flags_hi = "); - pandecode_log_decoded_flags(shader_midgard1_flag_hi_info, s->midgard1.flags_hi); - pandecode_log_cont(",\n"); - } - - if (s->depth_units || s->depth_factor) { - pandecode_prop("depth_factor = %f", s->depth_factor); - pandecode_prop("depth_units = %f", s->depth_units); - } - - if (s->coverage_mask) - pandecode_prop("coverage_mask = 0x%X", s->coverage_mask); - - if (s->unknown2_2) - pandecode_prop(".unknown2_2 = %X", s->unknown2_2); - - if (s->unknown2_3 || s->unknown2_4) { - pandecode_log(".unknown2_3 = "); - - int unknown2_3 = s->unknown2_3; - int unknown2_4 = s->unknown2_4; + MALI_BIFROST_PROPERTIES_unpack((const uint8_t *) &state.properties, &bi_props); + MALI_BIFROST_PROPERTIES_print(pandecode_dump_stream, &bi_props, 2 * 2); - /* We're not quite sure what these flags mean without the depth test, if anything */ - - if (unknown2_3 & (MALI_DEPTH_WRITEMASK | MALI_DEPTH_FUNC_MASK)) { - const char *func = pandecode_func(MALI_GET_DEPTH_FUNC(unknown2_3)); - unknown2_3 &= ~MALI_DEPTH_FUNC_MASK; - - pandecode_log_cont("MALI_DEPTH_FUNC(%s) | ", func); - } - - pandecode_log_decoded_flags(u3_flag_info, unknown2_3); - pandecode_log_cont(",\n"); - - pandecode_log(".unknown2_4 = "); - pandecode_log_decoded_flags(u4_flag_info, unknown2_4); - pandecode_log_cont(",\n"); - } + uniform_count = state.preload.uniform_count; + uniform_buffer_count = bi_props.uniform_buffer_count; + } else { + MALI_MIDGARD_PROPERTIES_unpack((const uint8_t *) &state.properties, &midg_props); + MALI_MIDGARD_PROPERTIES_print(pandecode_dump_stream, &midg_props, 2 * 2); - if (s->stencil_mask_front || s->stencil_mask_back) { - pandecode_prop("stencil_mask_front = 0x%02X", s->stencil_mask_front); - pandecode_prop("stencil_mask_back = 0x%02X", s->stencil_mask_back); + uniform_count = midg_props.uniform_count; + uniform_buffer_count = midg_props.uniform_buffer_count; } - pandecode_stencil("front", &s->stencil_front); - pandecode_stencil("back", &s->stencil_back); + 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) { - pandecode_log(".bifrost2 = {\n"); - pandecode_indent++; - - pandecode_prop("unk3 = 0x%" PRIx32, s->bifrost2.unk3); - pandecode_prop("preload_regs = 0x%" PRIx32, s->bifrost2.preload_regs); - pandecode_prop("uniform_count = %" PRId32, s->bifrost2.uniform_count); - pandecode_prop("unk4 = 0x%" PRIx32, s->bifrost2.unk4); - - pandecode_indent--; - pandecode_log("},\n"); - } else if (s->midgard2.unknown2_7) { - pandecode_log(".midgard2 = {\n"); - pandecode_indent++; - - pandecode_prop("unknown2_7 = 0x%" PRIx32, s->midgard2.unknown2_7); - pandecode_indent--; - pandecode_log("},\n"); - } - - if (s->padding) { - pandecode_msg("XXX: shader padding tripped\n"); - pandecode_prop("padding = 0x%" PRIx32, s->padding); + uint32_t opaque = state.preload.uniform_count << 15 + | state.preload.untyped; + + switch (job_type) { + case MALI_JOB_TYPE_VERTEX: + DUMP_CL("Preload", PRELOAD_VERTEX, &opaque, 2); + break; + case MALI_JOB_TYPE_TILER: + DUMP_CL("Preload", PRELOAD_FRAGMENT, &opaque, 2); + break; + case MALI_JOB_TYPE_COMPUTE: + DUMP_CL("Preload", PRELOAD_COMPUTE, &opaque, 2); + break; + default: + DUMP_CL("Preload", PRELOAD, &opaque, 2); + break; + } } if (!is_bifrost) { /* TODO: Blend shaders routing/disasm */ - union midgard_blend blend = s->blend; - mali_ptr shader = pandecode_midgard_blend(&blend, s->unknown2_3 & MALI_HAS_BLEND_SHADER); + 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); - } else { - pandecode_msg("mdg_blend = %" PRIx64 "\n", s->blend.shader); } - pandecode_indent--; - pandecode_log("};\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_memory & MALI_MFBD)) { - void* blend_base = (void *) (s + 1); + void* blend_base = ((void *) cl) + MALI_STATE_LENGTH; for (unsigned i = 0; i < fbd_info.rt_count; i++) { mali_ptr shader = 0; @@ -2832,36 +1727,13 @@ pandecode_vertex_tiler_postfix_pre( } else pandecode_msg("XXX: missing shader descriptor\n"); - if (p->viewport) { - struct pandecode_mapped_memory *fmem = pandecode_find_mapped_gpu_mem_containing(p->viewport); - struct mali_viewport *PANDECODE_PTR_VAR(f, fmem, p->viewport); - - pandecode_log("struct mali_viewport viewport_%"PRIx64"_%d%s = {\n", p->viewport, job_no, suffix); - pandecode_indent++; - - pandecode_prop("clip_minx = %f", f->clip_minx); - pandecode_prop("clip_miny = %f", f->clip_miny); - pandecode_prop("clip_minz = %f", f->clip_minz); - pandecode_prop("clip_maxx = %f", f->clip_maxx); - pandecode_prop("clip_maxy = %f", f->clip_maxy); - pandecode_prop("clip_maxz = %f", f->clip_maxz); - - /* Only the higher coordinates are MALI_POSITIVE scaled */ - - pandecode_prop("viewport0 = { %d, %d }", - f->viewport0[0], f->viewport0[1]); - - pandecode_prop("viewport1 = { MALI_POSITIVE(%d), MALI_POSITIVE(%d) }", - f->viewport1[0] + 1, f->viewport1[1] + 1); - - pandecode_indent--; - pandecode_log("};\n"); - } + if (p->viewport) + DUMP_ADDR("Viewport", VIEWPORT, p->viewport, 1); unsigned max_attr_index = 0; if (p->attribute_meta) - max_attr_index = pandecode_attribute_meta(job_no, attribute_count, p, false, suffix); + max_attr_index = pandecode_attribute_meta(attribute_count, p->attribute_meta, false, suffix); if (p->attributes) { attr_mem = pandecode_find_mapped_gpu_mem_containing(p->attributes); @@ -2873,7 +1745,7 @@ pandecode_vertex_tiler_postfix_pre( * since the GPU will write to it itself */ if (p->varying_meta) { - varying_count = pandecode_attribute_meta(job_no, varying_count, p, true, suffix); + varying_count = pandecode_attribute_meta(varying_count, p->varying_meta, true, suffix); } if (p->varyings) { @@ -2911,48 +1783,6 @@ pandecode_vertex_tiler_postfix_pre( pandecode_samplers(p->sampler_descriptor, sampler_count, job_no, is_bifrost); } -static void -pandecode_gl_enables(uint32_t gl_enables, int job_type) -{ - pandecode_log(".gl_enables = "); - - pandecode_log_decoded_flags(gl_enable_flag_info, gl_enables); - - pandecode_log_cont(",\n"); -} - -static void -pandecode_vertex_tiler_postfix(const struct mali_vertex_tiler_postfix *p, int job_no, bool is_bifrost) -{ - if (p->shader & 0xF) - pandecode_msg("warn: shader tagged %X\n", (unsigned) (p->shader & 0xF)); - - pandecode_log(".postfix = {\n"); - pandecode_indent++; - - pandecode_gl_enables(p->gl_enables, MALI_JOB_TYPE_TILER); - pandecode_prop("instance_shift = 0x%x", p->instance_shift); - pandecode_prop("instance_odd = 0x%x", p->instance_odd); - - if (p->zero4) { - pandecode_msg("XXX: vertex only zero tripped"); - pandecode_prop("zero4 = 0x%" PRIx32, p->zero4); - } - - pandecode_prop("offset_start = 0x%x", p->offset_start); - - if (p->zero5) { - pandecode_msg("XXX: vertex only zero tripped"); - pandecode_prop("zero5 = 0x%" PRIx64, p->zero5); - } - - MEMORY_PROP(p, position_varying); - MEMORY_PROP(p, occlusion_counter); - - pandecode_indent--; - pandecode_log("},\n"); -} - static void pandecode_tiler_heap_meta(mali_ptr gpu_va, int job_no) { @@ -3068,30 +1898,6 @@ pandecode_primitive_size(union midgard_primitive_size u, bool constant) pandecode_log("},\n"); } -static void -pandecode_tiler_only_bfr(const struct bifrost_tiler_only *t, int job_no) -{ - pandecode_log_cont("{\n"); - pandecode_indent++; - - /* 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); - } - - pandecode_indent--; - pandecode_log("},\n"); -} - static int pandecode_vertex_job_bfr(const struct mali_job_descriptor_header *h, const struct pandecode_mapped_memory *mem, @@ -3105,7 +1911,9 @@ pandecode_vertex_job_bfr(const struct mali_job_descriptor_header *h, pandecode_indent++; pandecode_vertex_tiler_prefix(&v->prefix, job_no, false); - pandecode_vertex_tiler_postfix(&v->postfix, job_no, true); + struct mali_draw_packed draw; + memcpy(&draw, &v->postfix, sizeof(draw)); + DUMP_CL("Draw", DRAW, &draw, 2); pandecode_indent--; pandecode_log("};\n"); @@ -3121,17 +1929,30 @@ pandecode_tiler_job_bfr(const struct mali_job_descriptor_header *h, struct bifrost_payload_tiler *PANDECODE_PTR_VAR(t, mem, payload); pandecode_vertex_tiler_postfix_pre(&t->postfix, job_no, h->job_type, "", true, gpu_id); - pandecode_tiler_meta(t->tiler.tiler_meta, job_no); + pandecode_tiler_meta(t->tiler_meta, job_no); pandecode_log("struct bifrost_payload_tiler payload_%"PRIx64"_%d = {\n", payload, job_no); pandecode_indent++; pandecode_vertex_tiler_prefix(&t->prefix, job_no, false); - pandecode_log(".tiler = "); - pandecode_tiler_only_bfr(&t->tiler, job_no); + /* 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); + } - pandecode_vertex_tiler_postfix(&t->postfix, job_no, true); + struct mali_draw_packed draw; + memcpy(&draw, &t->postfix, sizeof(draw)); + DUMP_CL("Draw", DRAW, &draw, 2); pandecode_indent--; pandecode_log("};\n"); @@ -3153,10 +1974,16 @@ pandecode_vertex_or_tiler_job_mdg(const struct mali_job_descriptor_header *h, pandecode_indent++; pandecode_vertex_tiler_prefix(&v->prefix, job_no, is_graphics); - pandecode_vertex_tiler_postfix(&v->postfix, job_no, false); - bool has_primitive_pointer = v->prefix.unknown_draw & MALI_DRAW_VARYING_SIZE; - pandecode_primitive_size(v->primitive_size, !has_primitive_pointer); + struct mali_draw_packed draw; + memcpy(&draw, &v->postfix, sizeof(draw)); + DUMP_CL("Draw", DRAW, &draw, 2); + + struct MALI_PRIMITIVE primitive; + struct mali_primitive_packed prim_packed = v->prefix.primitive; + MALI_PRIMITIVE_unpack((const uint8_t *) &prim_packed, &primitive); + + pandecode_primitive_size(v->primitive_size, primitive.point_size_array == 0); pandecode_indent--; pandecode_log("};\n"); @@ -3278,15 +2105,8 @@ pandecode_jc(mali_ptr jc_gpu_va, bool bifrost, unsigned gpu_id, bool minimal) h = PANDECODE_PTR(mem, jc_gpu_va, struct mali_job_descriptor_header); - /* On Midgard, for 32-bit jobs except for fragment jobs, the - * high 32-bits of the 64-bit pointer are reused to store - * something else. - */ - int offset = h->job_descriptor_size == MALI_JOB_32 && - h->job_type != MALI_JOB_TYPE_FRAGMENT ? 4 : 0; - mali_ptr payload_ptr = jc_gpu_va + sizeof(*h) - offset; - - payload = pandecode_fetch_gpu_mem(mem, payload_ptr, 256); + mali_ptr payload_ptr = jc_gpu_va + sizeof(*h); + payload = pandecode_fetch_gpu_mem(mem, payload_ptr, 64); int job_no = job_descriptor_number++; @@ -3306,7 +2126,7 @@ pandecode_jc(mali_ptr jc_gpu_va, bool bifrost, unsigned gpu_id, bool minimal) pandecode_prop("exception_status = %x (source ID: 0x%x access: %s exception: 0x%x)", h->exception_status, (h->exception_status >> 16) & 0xFFFF, - pandecode_exception_access((h->exception_status >> 8) & 0x3), + mali_exception_access_as_str((h->exception_status >> 8) & 0x3), h->exception_status & 0xFF); if (h->first_incomplete_task)