+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++;
+
+ 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();
+
+ /* TODO: Are there others? */
+ bool is_zs = f.format == MALI_Z32_UNORM;
+
+ /* Recall Z/S switched the meaning of linear/tiled .. */
+ if (is_zs && f.layout == MALI_TEXTURE_LINEAR)
+ pandecode_msg("XXX: depth/stencil cannot be tiled\n");
+
+ /* 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 ");
+
+ 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. */
+
+ 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);
+
+ 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_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 = t->levels + 1;
+
+ /* Miptree for each face */
+ if (f.type == MALI_TEX_CUBE)
+ bitmap_count *= 6;
+ else if (f.type == MALI_TEX_3D && f.layout == MALI_TEXTURE_LINEAR)
+ bitmap_count *= (t->depth + 1);
+
+ /* Array of textures */
+ bitmap_count *= (t->array_size + 1);
+
+ /* Stride for each element */
+ if (f.manual_stride)
+ bitmap_count *= 2;
+
+ mali_ptr *pointers_and_strides = pandecode_fetch_gpu_mem(tmem,
+ u + sizeof(*t), 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 (f.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");
+
+ pandecode_indent--;
+ pandecode_log("};\n");
+}
+
+/* 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)
+ assert(truth >= 0);
+
+ 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_vertex_tiler_postfix_pre(
+ const struct mali_vertex_tiler_postfix *p,