blob: ca6f0441eaa71f9f6df9a8d95df6712e3d319869 [file] [log] [blame]
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001/*
2 * Copyright (C) 2017-2019 Alyssa Rosenzweig
3 * Copyright (C) 2017-2019 Connor Abbott
Alyssa Rosenzweigd4575c32019-06-25 13:30:17 -07004 * Copyright (C) 2019 Collabora, Ltd.
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00005 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
15 * Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 */
25
Alyssa Rosenzweig88dc4c22020-08-05 18:13:11 -040026#include <midgard_pack.h>
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +000027#include <stdio.h>
28#include <stdlib.h>
29#include <memory.h>
30#include <stdbool.h>
31#include <stdarg.h>
Alyssa Rosenzweige09392f2019-08-20 14:34:09 -070032#include <ctype.h>
Alyssa Rosenzweigfc7bcee2019-06-11 12:25:35 -070033#include "decode.h"
Lionel Landwerlin66373952019-08-09 16:39:58 +030034#include "util/macros.h"
Alyssa Rosenzweigd699ffb2019-05-14 22:21:39 +000035#include "util/u_math.h"
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +000036
Alyssa Rosenzweigec2a59c2019-07-10 10:33:24 -070037#include "midgard/disassemble.h"
38#include "bifrost/disassemble.h"
39
Alyssa Rosenzweig25ed9302019-08-16 16:22:38 -070040#include "pan_encoder.h"
41
Tomeu Vizoso9447a842019-10-30 12:05:30 +010042static void pandecode_swizzle(unsigned swizzle, enum mali_format format);
43
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +000044#define MEMORY_PROP(obj, p) {\
Alyssa Rosenzweig2608da12019-06-19 09:35:57 -070045 if (obj->p) { \
46 char *a = pointer_as_memory_reference(obj->p); \
47 pandecode_prop("%s = %s", #p, a); \
48 free(a); \
49 } \
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +000050}
51
Alyssa Rosenzweig0c1874a2019-07-12 08:47:35 -070052#define MEMORY_PROP_DIR(obj, p) {\
53 if (obj.p) { \
54 char *a = pointer_as_memory_reference(obj.p); \
55 pandecode_prop("%s = %s", #p, a); \
56 free(a); \
57 } \
58}
59
Boris Brezillonaa2670c2020-09-05 18:14:17 +020060#define DUMP_UNPACKED(T, var, ...) { \
Boris Brezillon670e8182020-09-09 17:56:53 +020061 pandecode_log(__VA_ARGS__); \
Boris Brezillonaa2670c2020-09-05 18:14:17 +020062 pan_print(pandecode_dump_stream, T, var, (pandecode_indent + 1) * 2); \
63}
64
65#define DUMP_CL(T, cl, ...) {\
Boris Brezillon62c0ef02020-09-05 18:04:43 +020066 pan_unpack(cl, T, temp); \
Boris Brezillonaa2670c2020-09-05 18:14:17 +020067 DUMP_UNPACKED(T, temp, __VA_ARGS__); \
Alyssa Rosenzweigd2ddd4d2020-08-05 19:43:58 -040068}
69
Boris Brezillon95eb7d92020-09-06 11:01:09 +020070#define DUMP_SECTION(A, S, cl, ...) { \
71 pan_section_unpack(cl, A, S, temp); \
72 pandecode_log(__VA_ARGS__); \
73 pan_section_print(pandecode_dump_stream, A, S, temp, (pandecode_indent + 1) * 2); \
74}
75
Alyssa Rosenzweig4e3fe542020-08-14 16:03:12 -040076#define MAP_ADDR(T, addr, cl) \
77 const uint8_t *cl = 0; \
78 { \
79 struct pandecode_mapped_memory *mapped_mem = pandecode_find_mapped_gpu_mem_containing(addr); \
80 cl = pandecode_fetch_gpu_mem(mapped_mem, addr, MALI_ ## T ## _LENGTH); \
81 }
82
Boris Brezillon670e8182020-09-09 17:56:53 +020083#define DUMP_ADDR(T, addr, ...) {\
Alyssa Rosenzweig4e3fe542020-08-14 16:03:12 -040084 MAP_ADDR(T, addr, cl) \
Boris Brezillon670e8182020-09-09 17:56:53 +020085 DUMP_CL(T, cl, __VA_ARGS__); \
Alyssa Rosenzweigd2ddd4d2020-08-05 19:43:58 -040086}
87
Icecream95be22c072020-01-23 10:14:35 +130088FILE *pandecode_dump_stream;
89
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +000090/* Semantic logging type.
91 *
92 * Raw: for raw messages to be printed as is.
93 * Message: for helpful information to be commented out in replays.
94 * Property: for properties of a struct
95 *
96 * Use one of pandecode_log, pandecode_msg, or pandecode_prop as syntax sugar.
97 */
98
99enum pandecode_log_type {
100 PANDECODE_RAW,
101 PANDECODE_MESSAGE,
102 PANDECODE_PROPERTY
103};
104
105#define pandecode_log(...) pandecode_log_typed(PANDECODE_RAW, __VA_ARGS__)
106#define pandecode_msg(...) pandecode_log_typed(PANDECODE_MESSAGE, __VA_ARGS__)
107#define pandecode_prop(...) pandecode_log_typed(PANDECODE_PROPERTY, __VA_ARGS__)
108
109unsigned pandecode_indent = 0;
110
111static void
112pandecode_make_indent(void)
113{
114 for (unsigned i = 0; i < pandecode_indent; ++i)
Boris Brezillon6249ae72020-09-09 17:52:23 +0200115 fprintf(pandecode_dump_stream, " ");
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +0000116}
117
118static void
119pandecode_log_typed(enum pandecode_log_type type, const char *format, ...)
120{
121 va_list ap;
122
123 pandecode_make_indent();
124
125 if (type == PANDECODE_MESSAGE)
Icecream95be22c072020-01-23 10:14:35 +1300126 fprintf(pandecode_dump_stream, "// ");
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +0000127 else if (type == PANDECODE_PROPERTY)
Icecream95be22c072020-01-23 10:14:35 +1300128 fprintf(pandecode_dump_stream, ".");
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +0000129
130 va_start(ap, format);
Icecream95be22c072020-01-23 10:14:35 +1300131 vfprintf(pandecode_dump_stream, format, ap);
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +0000132 va_end(ap);
133
134 if (type == PANDECODE_PROPERTY)
Icecream95be22c072020-01-23 10:14:35 +1300135 fprintf(pandecode_dump_stream, ",\n");
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +0000136}
137
138static void
139pandecode_log_cont(const char *format, ...)
140{
141 va_list ap;
142
143 va_start(ap, format);
Icecream95be22c072020-01-23 10:14:35 +1300144 vfprintf(pandecode_dump_stream, format, ap);
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +0000145 va_end(ap);
146}
147
Alyssa Rosenzweig4391c652019-08-19 15:14:48 -0700148/* To check for memory safety issues, validates that the given pointer in GPU
149 * memory is valid, containing at least sz bytes. The goal is to eliminate
150 * GPU-side memory bugs (NULL pointer dereferences, buffer overflows, or buffer
151 * overruns) by statically validating pointers.
152 */
153
154static void
155pandecode_validate_buffer(mali_ptr addr, size_t sz)
156{
157 if (!addr) {
158 pandecode_msg("XXX: null pointer deref");
159 return;
160 }
161
162 /* Find a BO */
163
164 struct pandecode_mapped_memory *bo =
165 pandecode_find_mapped_gpu_mem_containing(addr);
166
167 if (!bo) {
168 pandecode_msg("XXX: invalid memory dereference\n");
169 return;
170 }
171
172 /* Bounds check */
173
174 unsigned offset = addr - bo->gpu_va;
175 unsigned total = offset + sz;
176
177 if (total > bo->length) {
Alyssa Rosenzweigf38ce6e2019-08-21 16:06:23 -0700178 pandecode_msg("XXX: buffer overrun. "
Alyssa Rosenzweigbcfcb7e2019-08-30 17:02:43 -0700179 "Chunk of size %zu at offset %d in buffer of size %zu. "
180 "Overrun by %zu bytes. \n",
Alyssa Rosenzweig4391c652019-08-19 15:14:48 -0700181 sz, offset, bo->length, total - bo->length);
182 return;
183 }
184}
185
Alyssa Rosenzweig31fc52a2019-07-10 07:22:19 -0700186/* Midgard's tiler descriptor is embedded within the
187 * larger FBD */
188
189static void
Alyssa Rosenzweiga8bd3ad2019-08-19 11:48:32 -0700190pandecode_midgard_tiler_descriptor(
Boris Brezillone8556982020-09-05 18:16:37 +0200191 const struct mali_midgard_tiler_packed *tp,
192 const struct mali_midgard_tiler_weights_packed *wp,
Alyssa Rosenzweiga8bd3ad2019-08-19 11:48:32 -0700193 unsigned width,
Alyssa Rosenzweig897110a2019-08-19 14:47:50 -0700194 unsigned height,
Alyssa Rosenzweig9fb09042019-11-27 08:31:16 -0500195 bool is_fragment,
196 bool has_hierarchy)
Alyssa Rosenzweig31fc52a2019-07-10 07:22:19 -0700197{
Boris Brezillone8556982020-09-05 18:16:37 +0200198 pan_unpack(tp, MIDGARD_TILER, t);
199 DUMP_UNPACKED(MIDGARD_TILER, t, "Tiler:\n");
Alyssa Rosenzweig31fc52a2019-07-10 07:22:19 -0700200
Boris Brezillone8556982020-09-05 18:16:37 +0200201 MEMORY_PROP_DIR(t, polygon_list);
Alyssa Rosenzweig31fc52a2019-07-10 07:22:19 -0700202
Alyssa Rosenzweig52101e42019-08-19 10:38:25 -0700203 /* The body is offset from the base of the polygon list */
Alyssa Rosenzweigb010a6d2020-04-06 20:31:32 -0400204 //assert(t->polygon_list_body > t->polygon_list);
Boris Brezillone8556982020-09-05 18:16:37 +0200205 unsigned body_offset = t.polygon_list_body - t.polygon_list;
Alyssa Rosenzweig52101e42019-08-19 10:38:25 -0700206
207 /* It needs to fit inside the reported size */
Alyssa Rosenzweigb010a6d2020-04-06 20:31:32 -0400208 //assert(t->polygon_list_size >= body_offset);
Alyssa Rosenzweig52101e42019-08-19 10:38:25 -0700209
Alyssa Rosenzweiga8bd3ad2019-08-19 11:48:32 -0700210 /* Now that we've sanity checked, we'll try to calculate the sizes
211 * ourselves for comparison */
212
Boris Brezillone8556982020-09-05 18:16:37 +0200213 unsigned ref_header = panfrost_tiler_header_size(width, height, t.hierarchy_mask, has_hierarchy);
214 unsigned ref_size = panfrost_tiler_full_size(width, height, t.hierarchy_mask, has_hierarchy);
Alyssa Rosenzweiga8bd3ad2019-08-19 11:48:32 -0700215
Boris Brezillone8556982020-09-05 18:16:37 +0200216 if (!((ref_header == body_offset) && (ref_size == t.polygon_list_size))) {
Alyssa Rosenzweiga8bd3ad2019-08-19 11:48:32 -0700217 pandecode_msg("XXX: bad polygon list size (expected %d / 0x%x)\n",
218 ref_header, ref_size);
Boris Brezillone8556982020-09-05 18:16:37 +0200219 pandecode_prop("polygon_list_size = 0x%x", t.polygon_list_size);
Alyssa Rosenzweiga8bd3ad2019-08-19 11:48:32 -0700220 pandecode_msg("body offset %d\n", body_offset);
221 }
Alyssa Rosenzweig52101e42019-08-19 10:38:25 -0700222
Alyssa Rosenzweig897110a2019-08-19 14:47:50 -0700223 /* The tiler heap has a start and end specified -- it should be
224 * identical to what we have in the BO. The exception is if tiling is
225 * disabled. */
Alyssa Rosenzweig13d07972019-08-19 10:56:23 -0700226
Boris Brezillone8556982020-09-05 18:16:37 +0200227 MEMORY_PROP_DIR(t, heap_start);
228 assert(t.heap_end >= t.heap_start);
Alyssa Rosenzweig13d07972019-08-19 10:56:23 -0700229
Boris Brezillone8556982020-09-05 18:16:37 +0200230 unsigned heap_size = t.heap_end - t.heap_start;
Alyssa Rosenzweig13d07972019-08-19 10:56:23 -0700231
Alyssa Rosenzweig897110a2019-08-19 14:47:50 -0700232 /* Tiling is enabled with a special flag */
Boris Brezillone8556982020-09-05 18:16:37 +0200233 unsigned hierarchy_mask = t.hierarchy_mask & MALI_MIDGARD_TILER_HIERARCHY_MASK;
234 unsigned tiler_flags = t.hierarchy_mask ^ hierarchy_mask;
Alyssa Rosenzweig897110a2019-08-19 14:47:50 -0700235
236 bool tiling_enabled = hierarchy_mask;
237
238 if (tiling_enabled) {
Alyssa Rosenzweig897110a2019-08-19 14:47:50 -0700239 /* We should also have no other flags */
240 if (tiler_flags)
241 pandecode_msg("XXX: unexpected tiler %X\n", tiler_flags);
242 } else {
243 /* When tiling is disabled, we should have that flag and no others */
244
Boris Brezillone8556982020-09-05 18:16:37 +0200245 if (tiler_flags != MALI_MIDGARD_TILER_DISABLED) {
246 pandecode_msg("XXX: unexpected tiler flag %X, expected MALI_MIDGARD_TILER_DISABLED\n",
Alyssa Rosenzweig897110a2019-08-19 14:47:50 -0700247 tiler_flags);
248 }
249
250 /* We should also have an empty heap */
251 if (heap_size) {
252 pandecode_msg("XXX: tiler heap size %d given, expected empty\n",
253 heap_size);
254 }
255
256 /* Disabled tiling is used only for clear-only jobs, which are
257 * purely FRAGMENT, so we should never see this for
258 * non-FRAGMENT descriptors. */
259
260 if (!is_fragment)
261 pandecode_msg("XXX: tiler disabled for non-FRAGMENT job\n");
262 }
263
264 /* We've never seen weights used in practice, but we know from the
265 * kernel these fields is there */
Alyssa Rosenzweig31fc52a2019-07-10 07:22:19 -0700266
Boris Brezillone8556982020-09-05 18:16:37 +0200267 pan_unpack(wp, MIDGARD_TILER_WEIGHTS, w);
Alyssa Rosenzweig31fc52a2019-07-10 07:22:19 -0700268 bool nonzero_weights = false;
269
Boris Brezillone8556982020-09-05 18:16:37 +0200270 nonzero_weights |= w.weight0 != 0x0;
271 nonzero_weights |= w.weight1 != 0x0;
272 nonzero_weights |= w.weight2 != 0x0;
273 nonzero_weights |= w.weight3 != 0x0;
274 nonzero_weights |= w.weight4 != 0x0;
275 nonzero_weights |= w.weight5 != 0x0;
276 nonzero_weights |= w.weight6 != 0x0;
277 nonzero_weights |= w.weight7 != 0x0;
Alyssa Rosenzweig31fc52a2019-07-10 07:22:19 -0700278
Boris Brezillone8556982020-09-05 18:16:37 +0200279 if (nonzero_weights)
280 DUMP_UNPACKED(MIDGARD_TILER_WEIGHTS, w, "Tiler Weights:\n");
Alyssa Rosenzweig31fc52a2019-07-10 07:22:19 -0700281}
282
Alyssa Rosenzweigf06e8f72019-08-21 12:06:50 -0700283/* Information about the framebuffer passed back for
284 * additional analysis */
285
286struct pandecode_fbd {
287 unsigned width;
288 unsigned height;
289 unsigned rt_count;
290 bool has_extra;
291};
292
293static struct pandecode_fbd
Tomeu Vizoso697f02c2019-11-12 12:15:02 +0100294pandecode_sfbd(uint64_t gpu_va, int job_no, bool is_fragment, unsigned gpu_id)
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +0000295{
296 struct pandecode_mapped_memory *mem = pandecode_find_mapped_gpu_mem_containing(gpu_va);
Boris Brezillon95eb7d92020-09-06 11:01:09 +0200297 const void *PANDECODE_PTR_VAR(s, mem, (mali_ptr) gpu_va);
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +0000298
Alyssa Rosenzweigd6d6d632019-08-30 17:00:09 -0700299 struct pandecode_fbd info = {
300 .has_extra = false,
301 .rt_count = 1
302 };
Alyssa Rosenzweigf06e8f72019-08-21 12:06:50 -0700303
Boris Brezillon95eb7d92020-09-06 11:01:09 +0200304 pandecode_log("Single-Target Framebuffer:\n");
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +0000305 pandecode_indent++;
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +0000306
Boris Brezillon95eb7d92020-09-06 11:01:09 +0200307 DUMP_SECTION(SINGLE_TARGET_FRAMEBUFFER, LOCAL_STORAGE, s, "Local Storage:\n");
308 pan_section_unpack(s, SINGLE_TARGET_FRAMEBUFFER, PARAMETERS, p);
309 DUMP_UNPACKED(SINGLE_TARGET_FRAMEBUFFER_PARAMETERS, p, "Parameters:\n");
Alyssa Rosenzweigf06e8f72019-08-21 12:06:50 -0700310
Boris Brezillon95eb7d92020-09-06 11:01:09 +0200311 const void *t = pan_section_ptr(s, SINGLE_TARGET_FRAMEBUFFER, TILER);
312 const void *w = pan_section_ptr(s, SINGLE_TARGET_FRAMEBUFFER, TILER_WEIGHTS);
Alyssa Rosenzweig9fb09042019-11-27 08:31:16 -0500313
314 bool has_hierarchy = !(gpu_id == 0x0720 || gpu_id == 0x0820 || gpu_id == 0x0830);
Boris Brezillon95eb7d92020-09-06 11:01:09 +0200315 pandecode_midgard_tiler_descriptor(t, w, p.bound_max_x + 1, p.bound_max_y + 1, is_fragment, has_hierarchy);
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +0000316
317 pandecode_indent--;
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +0000318
Boris Brezillon95eb7d92020-09-06 11:01:09 +0200319 /* Dummy unpack of the padding section to make sure all words are 0.
320 * No need to call print here since the section is supposed to be empty.
321 */
322 pan_section_unpack(s, SINGLE_TARGET_FRAMEBUFFER, PADDING_1, padding1);
323 pan_section_unpack(s, SINGLE_TARGET_FRAMEBUFFER, PADDING_2, padding2);
324 pandecode_log("\n");
Alyssa Rosenzweigf06e8f72019-08-21 12:06:50 -0700325
326 return info;
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +0000327}
328
329static void
Alyssa Rosenzweig0aa5d892019-06-19 08:41:51 -0700330pandecode_compute_fbd(uint64_t gpu_va, int job_no)
331{
332 struct pandecode_mapped_memory *mem = pandecode_find_mapped_gpu_mem_containing(gpu_va);
Boris Brezillon3a06fc32020-09-03 09:18:09 +0200333 const struct mali_local_storage_packed *PANDECODE_PTR_VAR(s, mem, (mali_ptr) gpu_va);
334 DUMP_CL(LOCAL_STORAGE, s, "Local Storage:\n");
Alyssa Rosenzweig0aa5d892019-06-19 08:41:51 -0700335}
336
Alyssa Rosenzweige09392f2019-08-20 14:34:09 -0700337/* Extracts the number of components associated with a Mali format */
338
339static unsigned
340pandecode_format_component_count(enum mali_format fmt)
Alyssa Rosenzweigf9430472019-02-24 06:22:23 +0000341{
Alyssa Rosenzweige09392f2019-08-20 14:34:09 -0700342 /* Mask out the format class */
343 unsigned top = fmt & 0b11100000;
344
345 switch (top) {
346 case MALI_FORMAT_SNORM:
347 case MALI_FORMAT_UINT:
348 case MALI_FORMAT_UNORM:
349 case MALI_FORMAT_SINT:
350 return ((fmt >> 3) & 3) + 1;
351 default:
352 /* TODO: Validate */
353 return 4;
354 }
355}
356
357/* Extracts a mask of accessed components from a 12-bit Mali swizzle */
358
359static unsigned
360pandecode_access_mask_from_channel_swizzle(unsigned swizzle)
361{
362 unsigned mask = 0;
Alyssa Rosenzweigcdc32762020-08-12 16:46:07 -0400363 assert(MALI_CHANNEL_R == 0);
Alyssa Rosenzweige09392f2019-08-20 14:34:09 -0700364
365 for (unsigned c = 0; c < 4; ++c) {
366 enum mali_channel chan = (swizzle >> (3*c)) & 0x7;
367
Alyssa Rosenzweigcdc32762020-08-12 16:46:07 -0400368 if (chan <= MALI_CHANNEL_A)
Alyssa Rosenzweige09392f2019-08-20 14:34:09 -0700369 mask |= (1 << chan);
370 }
371
372 return mask;
373}
374
375/* Validates that a (format, swizzle) pair is valid, in the sense that the
376 * swizzle doesn't access any components that are undefined in the format.
377 * Returns whether the swizzle is trivial (doesn't do any swizzling) and can be
378 * omitted */
379
380static bool
381pandecode_validate_format_swizzle(enum mali_format fmt, unsigned swizzle)
382{
383 unsigned nr_comp = pandecode_format_component_count(fmt);
384 unsigned access_mask = pandecode_access_mask_from_channel_swizzle(swizzle);
385 unsigned valid_mask = (1 << nr_comp) - 1;
386 unsigned invalid_mask = ~valid_mask;
387
388 if (access_mask & invalid_mask) {
389 pandecode_msg("XXX: invalid components accessed\n");
390 return false;
391 }
392
393 /* Check for the default non-swizzling swizzle so we can suppress
394 * useless printing for the defaults */
395
396 unsigned default_swizzles[4] = {
Alyssa Rosenzweigcdc32762020-08-12 16:46:07 -0400397 MALI_CHANNEL_R | (MALI_CHANNEL_0 << 3) | (MALI_CHANNEL_0 << 6) | (MALI_CHANNEL_1 << 9),
398 MALI_CHANNEL_R | (MALI_CHANNEL_G << 3) | (MALI_CHANNEL_0 << 6) | (MALI_CHANNEL_1 << 9),
399 MALI_CHANNEL_R | (MALI_CHANNEL_G << 3) | (MALI_CHANNEL_B << 6) | (MALI_CHANNEL_1 << 9),
400 MALI_CHANNEL_R | (MALI_CHANNEL_G << 3) | (MALI_CHANNEL_B << 6) | (MALI_CHANNEL_A << 9)
Alyssa Rosenzweige09392f2019-08-20 14:34:09 -0700401 };
402
403 return (swizzle == default_swizzles[nr_comp - 1]);
404}
405
Alyssa Rosenzweige09392f2019-08-20 14:34:09 -0700406static void
407pandecode_swizzle(unsigned swizzle, enum mali_format format)
408{
409 /* First, do some validation */
410 bool trivial_swizzle = pandecode_validate_format_swizzle(
411 format, swizzle);
412
413 if (trivial_swizzle)
414 return;
415
416 /* Next, print the swizzle */
417 pandecode_log_cont(".");
418
419 static const char components[] = "rgba01";
420
421 for (unsigned c = 0; c < 4; ++c) {
422 enum mali_channel chan = (swizzle >> (3 * c)) & 0x7;
423
Alyssa Rosenzweigcdc32762020-08-12 16:46:07 -0400424 if (chan > MALI_CHANNEL_1) {
Alyssa Rosenzweige09392f2019-08-20 14:34:09 -0700425 pandecode_log("XXX: invalid swizzle channel %d\n", chan);
426 continue;
427 }
428 pandecode_log_cont("%c", components[chan]);
429 }
Alyssa Rosenzweigf9430472019-02-24 06:22:23 +0000430}
431
432static void
Boris Brezillon5d5f7552020-09-08 10:17:40 +0200433pandecode_render_target(uint64_t gpu_va, unsigned job_no, bool is_bifrost, unsigned gpu_id,
434 const struct MALI_MULTI_TARGET_FRAMEBUFFER_PARAMETERS *fb)
Alyssa Rosenzweigf9430472019-02-24 06:22:23 +0000435{
Boris Brezillon5d5f7552020-09-08 10:17:40 +0200436 pandecode_log("Color Render Targets:\n");
Alyssa Rosenzweigf9430472019-02-24 06:22:23 +0000437 pandecode_indent++;
438
Boris Brezillon5d5f7552020-09-08 10:17:40 +0200439 for (int i = 0; i < (fb->render_target_count); i++) {
440 mali_ptr rt_va = gpu_va + i * MALI_RENDER_TARGET_LENGTH;
441 struct pandecode_mapped_memory *mem =
442 pandecode_find_mapped_gpu_mem_containing(rt_va);
443 const struct mali_render_target_packed *PANDECODE_PTR_VAR(rtp, mem, (mali_ptr) rt_va);
444 DUMP_CL(RENDER_TARGET, rtp, "Color Render Target %d:\n", i);
Alyssa Rosenzweige49204c2019-08-20 11:11:46 -0700445 }
Alyssa Rosenzweigb78e04c2019-08-14 16:01:38 -0700446
Alyssa Rosenzweigf9430472019-02-24 06:22:23 +0000447 pandecode_indent--;
Boris Brezillon5d5f7552020-09-08 10:17:40 +0200448 pandecode_log("\n");
Alyssa Rosenzweigf9430472019-02-24 06:22:23 +0000449}
450
451static void
Boris Brezillon5d5f7552020-09-08 10:17:40 +0200452pandecode_mfbd_bifrost_deps(const void *fb, int job_no)
Alyssa Rosenzweig8c88bd02019-06-11 14:56:30 -0700453{
Boris Brezillon5d5f7552020-09-08 10:17:40 +0200454 pan_section_unpack(fb, MULTI_TARGET_FRAMEBUFFER, BIFROST_PARAMETERS, params);
455
456 /* The blob stores all possible sample locations in a single buffer
457 * allocated on startup, and just switches the pointer when switching
458 * MSAA state. For now, we just put the data into the cmdstream, but we
459 * should do something like what the blob does with a real driver.
460 *
461 * There seem to be 32 slots for sample locations, followed by another
462 * 16. The second 16 is just the center location followed by 15 zeros
463 * in all the cases I've identified (maybe shader vs. depth/color
464 * samples?).
465 */
466
467 struct pandecode_mapped_memory *smem =
468 pandecode_find_mapped_gpu_mem_containing(params.sample_locations);
469
470 const u16 *PANDECODE_PTR_VAR(samples, smem, params.sample_locations);
471
472 pandecode_log("uint16_t sample_locations_%d[] = {\n", job_no);
Alyssa Rosenzweig8c88bd02019-06-11 14:56:30 -0700473 pandecode_indent++;
Boris Brezillon5d5f7552020-09-08 10:17:40 +0200474 for (int i = 0; i < 32 + 16; i++) {
475 pandecode_log("%d, %d,\n", samples[2 * i], samples[2 * i + 1]);
Alyssa Rosenzweig8c88bd02019-06-11 14:56:30 -0700476 }
477
478 pandecode_indent--;
479 pandecode_log("};\n");
480}
481
Alyssa Rosenzweigf06e8f72019-08-21 12:06:50 -0700482static struct pandecode_fbd
Boris Brezillon5d5f7552020-09-08 10:17:40 +0200483pandecode_mfbd_bfr(uint64_t gpu_va, int job_no, bool is_fragment, bool is_compute, bool is_bifrost, unsigned gpu_id)
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +0000484{
485 struct pandecode_mapped_memory *mem = pandecode_find_mapped_gpu_mem_containing(gpu_va);
Boris Brezillon5d5f7552020-09-08 10:17:40 +0200486 const void *PANDECODE_PTR_VAR(fb, mem, (mali_ptr) gpu_va);
487 pan_section_unpack(fb, MULTI_TARGET_FRAMEBUFFER, PARAMETERS, params);
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +0000488
Alyssa Rosenzweigf06e8f72019-08-21 12:06:50 -0700489 struct pandecode_fbd info;
Alyssa Rosenzweig3f5cd442020-02-28 07:17:53 -0500490
Boris Brezillon5d5f7552020-09-08 10:17:40 +0200491 if (is_bifrost)
492 pandecode_mfbd_bifrost_deps(fb, job_no);
Alyssa Rosenzweigf06e8f72019-08-21 12:06:50 -0700493
Boris Brezillon5d5f7552020-09-08 10:17:40 +0200494 pandecode_log("Multi-Target Framebuffer:\n");
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +0000495 pandecode_indent++;
496
Alyssa Rosenzweig3f5cd442020-02-28 07:17:53 -0500497 if (is_bifrost) {
Boris Brezillon5d5f7552020-09-08 10:17:40 +0200498 DUMP_SECTION(MULTI_TARGET_FRAMEBUFFER, BIFROST_PARAMETERS, fb, "Bifrost Params:\n");
Alyssa Rosenzweig3f5cd442020-02-28 07:17:53 -0500499 } else {
Boris Brezillon5d5f7552020-09-08 10:17:40 +0200500 DUMP_SECTION(MULTI_TARGET_FRAMEBUFFER, LOCAL_STORAGE, fb, "Local Storage:\n");
Alyssa Rosenzweig3f5cd442020-02-28 07:17:53 -0500501 }
Alyssa Rosenzweig85e745f2019-06-12 09:33:06 -0700502
Boris Brezillon5d5f7552020-09-08 10:17:40 +0200503 info.width = params.width;
504 info.height = params.height;
505 info.rt_count = params.render_target_count;
506 DUMP_UNPACKED(MULTI_TARGET_FRAMEBUFFER_PARAMETERS, params, "Parameters:\n");
Alyssa Rosenzweigf06e8f72019-08-21 12:06:50 -0700507
Boris Brezillon5d5f7552020-09-08 10:17:40 +0200508 if (!is_compute) {
509 if (is_bifrost) {
510 DUMP_SECTION(MULTI_TARGET_FRAMEBUFFER, BIFROST_TILER_POINTER, fb, "Tiler Pointer");
511 } else {
512 const void *t = pan_section_ptr(fb, MULTI_TARGET_FRAMEBUFFER, TILER);
513 const void *w = pan_section_ptr(fb, MULTI_TARGET_FRAMEBUFFER, TILER_WEIGHTS);
514 pandecode_midgard_tiler_descriptor(t, w, params.width, params.height, is_fragment, true);
Alyssa Rosenzweigc2c8b1a2020-05-26 18:10:39 -0400515 }
Boris Brezillon5d5f7552020-09-08 10:17:40 +0200516 } else {
Alyssa Rosenzweig39939692020-01-22 08:51:19 -0500517 pandecode_msg("XXX: skipping compute MFBD, fixme\n");
Boris Brezillon5d5f7552020-09-08 10:17:40 +0200518 }
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +0000519
Boris Brezillon5d5f7552020-09-08 10:17:40 +0200520 if (is_bifrost) {
521 pan_section_unpack(fb, MULTI_TARGET_FRAMEBUFFER, BIFROST_PADDING, padding);
Alyssa Rosenzweig85e745f2019-06-12 09:33:06 -0700522 }
523
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +0000524 pandecode_indent--;
Boris Brezillon5d5f7552020-09-08 10:17:40 +0200525 pandecode_log("\n");
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +0000526
Boris Brezillon5d5f7552020-09-08 10:17:40 +0200527 gpu_va += MALI_MULTI_TARGET_FRAMEBUFFER_LENGTH;
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +0000528
Boris Brezillon5d5f7552020-09-08 10:17:40 +0200529 info.has_extra = params.has_zs_crc_extension;
Alyssa Rosenzweigf06e8f72019-08-21 12:06:50 -0700530
531 if (info.has_extra) {
Boris Brezillon5d5f7552020-09-08 10:17:40 +0200532 struct pandecode_mapped_memory *mem =
533 pandecode_find_mapped_gpu_mem_containing(gpu_va);
534 const struct mali_zs_crc_extension_packed *PANDECODE_PTR_VAR(zs_crc, mem, (mali_ptr)gpu_va);
535 DUMP_CL(ZS_CRC_EXTENSION, zs_crc, "ZS CRC Extension:\n");
536 pandecode_log("\n");
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +0000537
Boris Brezillon5d5f7552020-09-08 10:17:40 +0200538 gpu_va += MALI_ZS_CRC_EXTENSION_LENGTH;
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +0000539 }
540
Alyssa Rosenzweig897110a2019-08-19 14:47:50 -0700541 if (is_fragment)
Boris Brezillon5d5f7552020-09-08 10:17:40 +0200542 pandecode_render_target(gpu_va, job_no, is_bifrost, gpu_id, &params);
Alyssa Rosenzweiga9fc1c82019-06-23 11:29:46 -0700543
Alyssa Rosenzweigf06e8f72019-08-21 12:06:50 -0700544 return info;
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +0000545}
546
547static void
Alyssa Rosenzweig7103baf2019-07-12 08:57:10 -0700548pandecode_attributes(const struct pandecode_mapped_memory *mem,
Alyssa Rosenzweig7318b522019-07-10 10:36:16 -0700549 mali_ptr addr, int job_no, char *suffix,
Alyssa Rosenzweigf4678f32019-08-22 13:27:38 -0700550 int count, bool varying, enum mali_job_type job_type)
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +0000551{
Alyssa Rosenzweig4e3fe542020-08-14 16:03:12 -0400552 char *prefix = varying ? "Varying" : "Attribute";
Alyssa Rosenzweiged464e02019-08-22 13:07:01 -0700553 assert(addr);
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +0000554
Alyssa Rosenzweiged464e02019-08-22 13:07:01 -0700555 if (!count) {
556 pandecode_msg("warn: No %s records\n", prefix);
Alyssa Rosenzweig5ad83012019-08-08 09:23:29 -0700557 return;
558 }
559
Alyssa Rosenzweig4e3fe542020-08-14 16:03:12 -0400560 MAP_ADDR(ATTRIBUTE_BUFFER, addr, cl);
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +0000561
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +0000562 for (int i = 0; i < count; ++i) {
Boris Brezillon706974c2020-09-15 09:25:18 +0200563 pan_unpack(cl + i * MALI_ATTRIBUTE_BUFFER_LENGTH, ATTRIBUTE_BUFFER, temp);
Boris Brezillonaa2670c2020-09-05 18:14:17 +0200564 DUMP_UNPACKED(ATTRIBUTE_BUFFER, temp, "%s:\n", prefix);
Alyssa Rosenzweigf4678f32019-08-22 13:27:38 -0700565
Boris Brezillon706974c2020-09-15 09:25:18 +0200566 if (temp.type != MALI_ATTRIBUTE_TYPE_1D_NPOT_DIVISOR)
567 continue;
568
569 pan_unpack(cl + (i + 1) * MALI_ATTRIBUTE_BUFFER_LENGTH,
570 ATTRIBUTE_BUFFER_CONTINUATION_NPOT, temp2);
571 pan_print(pandecode_dump_stream, ATTRIBUTE_BUFFER_CONTINUATION_NPOT,
572 temp2, (pandecode_indent + 1) * 2);
Alyssa Rosenzweig3b3d9652019-12-19 12:28:42 -0500573 }
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +0000574}
575
576static mali_ptr
Alyssa Rosenzweig7103baf2019-07-12 08:57:10 -0700577pandecode_shader_address(const char *name, mali_ptr ptr)
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +0000578{
579 /* TODO: Decode flags */
580 mali_ptr shader_ptr = ptr & ~15;
581
582 char *a = pointer_as_memory_reference(shader_ptr);
583 pandecode_prop("%s = (%s) | %d", name, a, (int) (ptr & 15));
584 free(a);
585
586 return shader_ptr;
587}
588
Alyssa Rosenzweigae705382019-05-18 20:48:43 +0000589/* Decodes a Bifrost blend constant. See the notes in bifrost_blend_rt */
590
591static unsigned
592decode_bifrost_constant(u16 constant)
593{
594 float lo = (float) (constant & 0xFF);
595 float hi = (float) (constant >> 8);
596
597 return (hi / 255.0) + (lo / 65535.0);
598}
599
Alyssa Rosenzweig050b9342019-05-04 21:57:01 +0000600static mali_ptr
601pandecode_bifrost_blend(void *descs, int job_no, int rt_no)
602{
603 struct bifrost_blend_rt *b =
604 ((struct bifrost_blend_rt *) descs) + rt_no;
605
606 pandecode_log("struct bifrost_blend_rt blend_rt_%d_%d = {\n", job_no, rt_no);
607 pandecode_indent++;
608
Alyssa Rosenzweigae705382019-05-18 20:48:43 +0000609 pandecode_prop("flags = 0x%" PRIx16, b->flags);
610 pandecode_prop("constant = 0x%" PRIx8 " /* %f */",
Alyssa Rosenzweig7318b522019-07-10 10:36:16 -0700611 b->constant, decode_bifrost_constant(b->constant));
Alyssa Rosenzweigae705382019-05-18 20:48:43 +0000612
Alyssa Rosenzweig050b9342019-05-04 21:57:01 +0000613 /* TODO figure out blend shader enable bit */
Boris Brezillon670e8182020-09-09 17:56:53 +0200614 DUMP_CL(BLEND_EQUATION, &b->equation, "Equation:\n");
Tomeu Vizoso3c98c452020-04-24 08:40:51 +0200615
Alyssa Rosenzweig050b9342019-05-04 21:57:01 +0000616 pandecode_prop("unk2 = 0x%" PRIx16, b->unk2);
617 pandecode_prop("index = 0x%" PRIx16, b->index);
Tomeu Vizoso3c98c452020-04-24 08:40:51 +0200618
Alyssa Rosenzweig0c621dc2020-08-11 21:30:46 -0400619 pandecode_log(".format = %s", mali_format_as_str(b->format));
Tomeu Vizoso3c98c452020-04-24 08:40:51 +0200620 pandecode_swizzle(b->swizzle, b->format);
621 pandecode_log_cont(",\n");
622
623 pandecode_prop("swizzle = 0x%" PRIx32, b->swizzle);
624 pandecode_prop("format = 0x%" PRIx32, b->format);
625
626 if (b->zero1) {
627 pandecode_msg("XXX: pandecode_bifrost_blend zero1 tripped\n");
628 pandecode_prop("zero1 = 0x%" PRIx32, b->zero1);
629 }
630
631 pandecode_log(".shader_type = ");
632 switch(b->shader_type) {
633 case BIFROST_BLEND_F16:
634 pandecode_log_cont("BIFROST_BLEND_F16");
635 break;
636 case BIFROST_BLEND_F32:
637 pandecode_log_cont("BIFROST_BLEND_F32");
638 break;
639 case BIFROST_BLEND_I32:
640 pandecode_log_cont("BIFROST_BLEND_I32");
641 break;
642 case BIFROST_BLEND_U32:
643 pandecode_log_cont("BIFROST_BLEND_U32");
644 break;
645 case BIFROST_BLEND_I16:
646 pandecode_log_cont("BIFROST_BLEND_I16");
647 break;
648 case BIFROST_BLEND_U16:
649 pandecode_log_cont("BIFROST_BLEND_U16");
650 break;
651 }
652 pandecode_log_cont(",\n");
653
654 if (b->zero2) {
655 pandecode_msg("XXX: pandecode_bifrost_blend zero2 tripped\n");
656 pandecode_prop("zero2 = 0x%" PRIx32, b->zero2);
657 }
658
Alyssa Rosenzweig050b9342019-05-04 21:57:01 +0000659 pandecode_prop("shader = 0x%" PRIx32, b->shader);
660
661 pandecode_indent--;
662 pandecode_log("},\n");
Alyssa Rosenzweig7318b522019-07-10 10:36:16 -0700663
Alyssa Rosenzweig050b9342019-05-04 21:57:01 +0000664 return 0;
665}
666
667static mali_ptr
668pandecode_midgard_blend(union midgard_blend *blend, bool is_shader)
669{
Alyssa Rosenzweig9ce45ac2019-08-21 08:59:57 -0700670 /* constant/equation is in a union */
671 if (!blend->shader)
Alyssa Rosenzweigb6d46d02019-06-19 09:31:16 -0700672 return 0;
673
Alyssa Rosenzweig050b9342019-05-04 21:57:01 +0000674 pandecode_log(".blend = {\n");
675 pandecode_indent++;
676
677 if (is_shader) {
Alyssa Rosenzweig7103baf2019-07-12 08:57:10 -0700678 pandecode_shader_address("shader", blend->shader);
Alyssa Rosenzweig050b9342019-05-04 21:57:01 +0000679 } else {
Boris Brezillon670e8182020-09-09 17:56:53 +0200680 DUMP_CL(BLEND_EQUATION, &blend->equation, "Equation:\n");
Alyssa Rosenzweigae705382019-05-18 20:48:43 +0000681 pandecode_prop("constant = %f", blend->constant);
Alyssa Rosenzweig050b9342019-05-04 21:57:01 +0000682 }
683
684 pandecode_indent--;
685 pandecode_log("},\n");
686
687 /* Return blend shader to disassemble if present */
688 return is_shader ? (blend->shader & ~0xF) : 0;
689}
690
691static mali_ptr
692pandecode_midgard_blend_mrt(void *descs, int job_no, int rt_no)
693{
694 struct midgard_blend_rt *b =
695 ((struct midgard_blend_rt *) descs) + rt_no;
696
697 /* Flags determine presence of blend shader */
Alyssa Rosenzweig94c9f872020-08-18 17:06:01 -0400698 bool is_shader = b->flags.opaque[0] & 0x2;
Alyssa Rosenzweig050b9342019-05-04 21:57:01 +0000699
700 pandecode_log("struct midgard_blend_rt blend_rt_%d_%d = {\n", job_no, rt_no);
701 pandecode_indent++;
702
Boris Brezillon670e8182020-09-09 17:56:53 +0200703 DUMP_CL(BLEND_FLAGS, &b->flags, "Flags:\n");
Alyssa Rosenzweig050b9342019-05-04 21:57:01 +0000704
Alyssa Rosenzweig9ffe0612019-07-12 08:45:51 -0700705 union midgard_blend blend = b->blend;
706 mali_ptr shader = pandecode_midgard_blend(&blend, is_shader);
Alyssa Rosenzweig050b9342019-05-04 21:57:01 +0000707
708 pandecode_indent--;
709 pandecode_log("};\n");
710
711 return shader;
712}
713
Alyssa Rosenzweig2208eb92019-08-20 13:59:26 -0700714/* Attributes and varyings have descriptor records, which contain information
715 * about their format and ordering with the attribute/varying buffers. We'll
716 * want to validate that the combinations specified are self-consistent.
717 */
718
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +0000719static int
Alyssa Rosenzweig68552282020-08-26 16:50:16 -0400720pandecode_attribute_meta(int count, mali_ptr attribute, bool varying, char *suffix)
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +0000721{
Alyssa Rosenzweig68552282020-08-26 16:50:16 -0400722 for (int i = 0; i < count; ++i, attribute += MALI_ATTRIBUTE_LENGTH)
Boris Brezillon670e8182020-09-09 17:56:53 +0200723 DUMP_ADDR(ATTRIBUTE, attribute, "%s:\n", varying ? "Varying" : "Attribute");
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +0000724
Alyssa Rosenzweig2c8a7222020-08-13 13:27:16 -0400725 return count;
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +0000726}
727
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +0000728/* return bits [lo, hi) of word */
729static u32
730bits(u32 word, u32 lo, u32 hi)
731{
732 if (hi - lo >= 32)
733 return word; // avoid undefined behavior with the shift
734
735 return (word >> lo) & ((1 << (hi - lo)) - 1);
736}
737
738static void
Alyssa Rosenzweig385a4f72019-12-24 22:33:47 -0500739pandecode_vertex_tiler_prefix(struct mali_vertex_tiler_prefix *p, int job_no, bool graphics)
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +0000740{
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +0000741 /* Decode invocation_count. See the comment before the definition of
742 * invocation_count for an explanation.
743 */
Alyssa Rosenzweig02e768e2020-08-26 13:04:17 -0400744 struct mali_invocation_packed invocation_packed = p->invocation;
Boris Brezillon706974c2020-09-15 09:25:18 +0200745 pan_unpack(&invocation_packed, INVOCATION, invocation);
Alyssa Rosenzweig25ed9302019-08-16 16:22:38 -0700746
Alyssa Rosenzweig02e768e2020-08-26 13:04:17 -0400747 unsigned size_x = bits(invocation.invocations, 0, invocation.size_y_shift) + 1;
748 unsigned size_y = bits(invocation.invocations, invocation.size_y_shift, invocation.size_z_shift) + 1;
749 unsigned size_z = bits(invocation.invocations, invocation.size_z_shift, invocation.workgroups_x_shift) + 1;
Alyssa Rosenzweig25ed9302019-08-16 16:22:38 -0700750
Alyssa Rosenzweig02e768e2020-08-26 13:04:17 -0400751 unsigned groups_x = bits(invocation.invocations, invocation.workgroups_x_shift, invocation.workgroups_y_shift) + 1;
752 unsigned groups_y = bits(invocation.invocations, invocation.workgroups_y_shift, invocation.workgroups_z_shift) + 1;
753 unsigned groups_z = bits(invocation.invocations, invocation.workgroups_z_shift, 32) + 1;
Alyssa Rosenzweig25ed9302019-08-16 16:22:38 -0700754
755 /* Even though we have this decoded, we want to ensure that the
756 * representation is "unique" so we don't lose anything by printing only
757 * the final result. More specifically, we need to check that we were
758 * passed something in canonical form, since the definition per the
759 * hardware is inherently not unique. How? Well, take the resulting
760 * decode and pack it ourselves! If it is bit exact with what we
761 * decoded, we're good to go. */
762
Alyssa Rosenzweig02e768e2020-08-26 13:04:17 -0400763 struct mali_invocation_packed ref;
Alyssa Rosenzweig385a4f72019-12-24 22:33:47 -0500764 panfrost_pack_work_groups_compute(&ref, groups_x, groups_y, groups_z, size_x, size_y, size_z, graphics);
Alyssa Rosenzweig25ed9302019-08-16 16:22:38 -0700765
Alyssa Rosenzweig02e768e2020-08-26 13:04:17 -0400766 if (memcmp(&ref, &invocation_packed, sizeof(ref))) {
Alyssa Rosenzweig25ed9302019-08-16 16:22:38 -0700767 pandecode_msg("XXX: non-canonical workgroups packing\n");
Boris Brezillonaa2670c2020-09-05 18:14:17 +0200768 DUMP_UNPACKED(INVOCATION, invocation, "Invocation:\n")
Alyssa Rosenzweig25ed9302019-08-16 16:22:38 -0700769 }
770
771 /* Regardless, print the decode */
Boris Brezillonaa2670c2020-09-05 18:14:17 +0200772 pandecode_log("Invocation (%d, %d, %d) x (%d, %d, %d)\n",
773 size_x, size_y, size_z,
774 groups_x, groups_y, groups_z);
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +0000775
Alyssa Rosenzweigb60d5672020-08-25 16:59:14 -0400776 struct mali_primitive_packed prim_packed = p->primitive;
Boris Brezillon706974c2020-09-15 09:25:18 +0200777 pan_unpack(&prim_packed, PRIMITIVE, primitive);
Boris Brezillonaa2670c2020-09-05 18:14:17 +0200778 DUMP_UNPACKED(PRIMITIVE, primitive, "Primitive:\n");
Alyssa Rosenzweigf38ce6e2019-08-21 16:06:23 -0700779
780 /* Validate an index buffer is present if we need one. TODO: verify
781 * relationship between invocation_count and index_count */
782
Alyssa Rosenzweigb60d5672020-08-25 16:59:14 -0400783 if (primitive.indices) {
Alyssa Rosenzweigf38ce6e2019-08-21 16:06:23 -0700784 /* Grab the size */
Alyssa Rosenzweigb60d5672020-08-25 16:59:14 -0400785 unsigned size = (primitive.index_type == MALI_INDEX_TYPE_UINT32) ?
786 sizeof(uint32_t) : primitive.index_type;
Alyssa Rosenzweigf38ce6e2019-08-21 16:06:23 -0700787
788 /* Ensure we got a size, and if so, validate the index buffer
789 * is large enough to hold a full set of indices of the given
790 * size */
791
Alyssa Rosenzweigb60d5672020-08-25 16:59:14 -0400792 if (!size)
Alyssa Rosenzweigf38ce6e2019-08-21 16:06:23 -0700793 pandecode_msg("XXX: index size missing\n");
794 else
Alyssa Rosenzweigb60d5672020-08-25 16:59:14 -0400795 pandecode_validate_buffer(primitive.indices, primitive.index_count * size);
796 } else if (primitive.index_type)
797 pandecode_msg("XXX: unexpected index size\n");
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +0000798}
799
800static void
Alyssa Rosenzweig7103baf2019-07-12 08:57:10 -0700801pandecode_uniform_buffers(mali_ptr pubufs, int ubufs_count, int job_no)
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +0000802{
803 struct pandecode_mapped_memory *umem = pandecode_find_mapped_gpu_mem_containing(pubufs);
Alyssa Rosenzweig7d3c48f2020-02-16 17:01:02 -0500804 uint64_t *PANDECODE_PTR_VAR(ubufs, umem, pubufs);
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +0000805
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +0000806 for (int i = 0; i < ubufs_count; i++) {
Alyssa Rosenzweig7d3c48f2020-02-16 17:01:02 -0500807 unsigned size = (ubufs[i] & ((1 << 10) - 1)) * 16;
808 mali_ptr addr = (ubufs[i] >> 10) << 2;
Alyssa Rosenzweig4aeb6942019-08-19 15:16:01 -0700809
810 pandecode_validate_buffer(addr, size);
811
Alyssa Rosenzweig7d3c48f2020-02-16 17:01:02 -0500812 char *ptr = pointer_as_memory_reference(addr);
Alyssa Rosenzweig6ec33b42019-08-21 11:46:06 -0700813 pandecode_log("ubuf_%d[%u] = %s;\n", i, size, ptr);
Alyssa Rosenzweig4aeb6942019-08-19 15:16:01 -0700814 free(ptr);
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +0000815 }
816
Alyssa Rosenzweig6ec33b42019-08-21 11:46:06 -0700817 pandecode_log("\n");
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +0000818}
819
820static void
Alyssa Rosenzweigae84f162019-08-22 11:30:13 -0700821pandecode_uniforms(mali_ptr uniforms, unsigned uniform_count)
822{
823 pandecode_validate_buffer(uniforms, uniform_count * 16);
824
825 char *ptr = pointer_as_memory_reference(uniforms);
826 pandecode_log("vec4 uniforms[%u] = %s;\n", uniform_count, ptr);
827 free(ptr);
828}
829
Alyssa Rosenzweig09671c82019-12-23 11:40:40 -0500830static const char *
831shader_type_for_job(unsigned type)
832{
833 switch (type) {
Alyssa Rosenzweig4b7056b2020-08-05 18:40:44 -0400834 case MALI_JOB_TYPE_VERTEX: return "VERTEX";
835 case MALI_JOB_TYPE_TILER: return "FRAGMENT";
836 case MALI_JOB_TYPE_COMPUTE: return "COMPUTE";
Alyssa Rosenzweig80049062020-08-26 16:52:53 -0400837 default: return "UNKNOWN";
Alyssa Rosenzweig09671c82019-12-23 11:40:40 -0500838 }
839}
840
Alyssa Rosenzweigc4a4f3d2019-08-14 09:19:54 -0700841static unsigned shader_id = 0;
842
Alyssa Rosenzweig58fc2602019-08-21 14:00:46 -0700843static struct midgard_disasm_stats
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +0000844pandecode_shader_disassemble(mali_ptr shader_ptr, int shader_no, int type,
Tomeu Vizoso072207b2019-11-07 08:27:53 +0100845 bool is_bifrost, unsigned gpu_id)
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +0000846{
847 struct pandecode_mapped_memory *mem = pandecode_find_mapped_gpu_mem_containing(shader_ptr);
848 uint8_t *PANDECODE_PTR_VAR(code, mem, shader_ptr);
849
850 /* Compute maximum possible size */
851 size_t sz = mem->length - (shader_ptr - mem->gpu_va);
852
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +0000853 /* Print some boilerplate to clearly denote the assembly (which doesn't
854 * obey indentation rules), and actually do the disassembly! */
855
Icecream95be22c072020-01-23 10:14:35 +1300856 pandecode_log_cont("\n\n");
Alyssa Rosenzweig50382df2019-05-18 18:58:56 +0000857
Alyssa Rosenzweig58fc2602019-08-21 14:00:46 -0700858 struct midgard_disasm_stats stats;
Alyssa Rosenzweigc4a4f3d2019-08-14 09:19:54 -0700859
Alyssa Rosenzweig50382df2019-05-18 18:58:56 +0000860 if (is_bifrost) {
Alyssa Rosenzweigc88f8162020-03-27 22:34:15 -0400861 disassemble_bifrost(pandecode_dump_stream, code, sz, true);
Alyssa Rosenzweig58fc2602019-08-21 14:00:46 -0700862
863 /* TODO: Extend stats to Bifrost */
Alyssa Rosenzweigcbbf7542019-08-21 14:57:23 -0700864 stats.texture_count = -128;
865 stats.sampler_count = -128;
866 stats.attribute_count = -128;
867 stats.varying_count = -128;
868 stats.uniform_count = -128;
869 stats.uniform_buffer_count = -128;
870 stats.work_count = -128;
Alyssa Rosenzweig58fc2602019-08-21 14:00:46 -0700871
872 stats.instruction_count = 0;
873 stats.bundle_count = 0;
874 stats.quadword_count = 0;
Alyssa Rosenzweigd6d6d632019-08-30 17:00:09 -0700875 stats.helper_invocations = false;
Alyssa Rosenzweig50382df2019-05-18 18:58:56 +0000876 } else {
Icecream95be22c072020-01-23 10:14:35 +1300877 stats = disassemble_midgard(pandecode_dump_stream,
878 code, sz, gpu_id,
Alyssa Rosenzweig4b7056b2020-08-05 18:40:44 -0400879 type == MALI_JOB_TYPE_TILER ?
Alyssa Rosenzweigac14fac2019-11-07 09:31:02 -0500880 MESA_SHADER_FRAGMENT : MESA_SHADER_VERTEX);
Alyssa Rosenzweig50382df2019-05-18 18:58:56 +0000881 }
882
Alyssa Rosenzweigc088a3b2020-08-26 16:52:23 -0400883 unsigned nr_threads =
884 (stats.work_count <= 4) ? 4 :
885 (stats.work_count <= 8) ? 2 :
886 1;
Alyssa Rosenzweig58fc2602019-08-21 14:00:46 -0700887
Alyssa Rosenzweigc088a3b2020-08-26 16:52:23 -0400888 pandecode_log_cont("shader%d - MESA_SHADER_%s shader: "
889 "%u inst, %u bundles, %u quadwords, "
890 "%u registers, %u threads, 0 loops, 0:0 spills:fills\n\n\n",
891 shader_id++,
892 shader_type_for_job(type),
893 stats.instruction_count, stats.bundle_count, stats.quadword_count,
894 stats.work_count, nr_threads);
Alyssa Rosenzweig58fc2602019-08-21 14:00:46 -0700895
896 return stats;
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +0000897}
898
899static void
Alyssa Rosenzweiga3d29362020-04-21 16:08:07 -0400900pandecode_texture_payload(mali_ptr payload,
Alyssa Rosenzweigf008a632020-08-11 17:27:36 -0400901 enum mali_texture_dimension dim,
Alyssa Rosenzweiga3d29362020-04-21 16:08:07 -0400902 enum mali_texture_layout layout,
903 bool manual_stride,
904 uint8_t levels,
905 uint16_t depth,
906 uint16_t array_size,
907 struct pandecode_mapped_memory *tmem)
908{
909 pandecode_log(".payload = {\n");
910 pandecode_indent++;
911
912 /* A bunch of bitmap pointers follow.
913 * We work out the correct number,
914 * based on the mipmap/cubemap
915 * properties, but dump extra
916 * possibilities to futureproof */
917
918 int bitmap_count = levels + 1;
919
920 /* Miptree for each face */
Alyssa Rosenzweigf008a632020-08-11 17:27:36 -0400921 if (dim == MALI_TEXTURE_DIMENSION_CUBE)
Alyssa Rosenzweiga3d29362020-04-21 16:08:07 -0400922 bitmap_count *= 6;
Alyssa Rosenzweigeba9bcd2020-06-30 16:21:30 -0400923
924 /* Array of layers */
Alyssa Rosenzweigf008a632020-08-11 17:27:36 -0400925 bitmap_count *= depth;
Alyssa Rosenzweiga3d29362020-04-21 16:08:07 -0400926
927 /* Array of textures */
Alyssa Rosenzweigf008a632020-08-11 17:27:36 -0400928 bitmap_count *= array_size;
Alyssa Rosenzweiga3d29362020-04-21 16:08:07 -0400929
930 /* Stride for each element */
931 if (manual_stride)
932 bitmap_count *= 2;
933
934 mali_ptr *pointers_and_strides = pandecode_fetch_gpu_mem(tmem,
935 payload, sizeof(mali_ptr) * bitmap_count);
936 for (int i = 0; i < bitmap_count; ++i) {
937 /* How we dump depends if this is a stride or a pointer */
938
939 if (manual_stride && (i & 1)) {
940 /* signed 32-bit snuck in as a 64-bit pointer */
941 uint64_t stride_set = pointers_and_strides[i];
942 uint32_t clamped_stride = stride_set;
943 int32_t stride = clamped_stride;
944 assert(stride_set == clamped_stride);
945 pandecode_log("(mali_ptr) %d /* stride */, \n", stride);
946 } else {
947 char *a = pointer_as_memory_reference(pointers_and_strides[i]);
948 pandecode_log("%s, \n", a);
949 free(a);
950 }
951 }
952
953 pandecode_indent--;
954 pandecode_log("},\n");
955}
956
957static void
Alyssa Rosenzweig8fc4ca82019-08-20 14:48:55 -0700958pandecode_texture(mali_ptr u,
959 struct pandecode_mapped_memory *tmem,
960 unsigned job_no, unsigned tex)
961{
Alyssa Rosenzweigf008a632020-08-11 17:27:36 -0400962 struct pandecode_mapped_memory *mapped_mem = pandecode_find_mapped_gpu_mem_containing(u);
963 const uint8_t *cl = pandecode_fetch_gpu_mem(mapped_mem, u, MALI_MIDGARD_TEXTURE_LENGTH);
Alyssa Rosenzweig8fc4ca82019-08-20 14:48:55 -0700964
Boris Brezillon706974c2020-09-15 09:25:18 +0200965 pan_unpack(cl, MIDGARD_TEXTURE, temp);
Boris Brezillonaa2670c2020-09-05 18:14:17 +0200966 DUMP_UNPACKED(MIDGARD_TEXTURE, temp, "Texture:\n")
Alyssa Rosenzweig8fc4ca82019-08-20 14:48:55 -0700967
Boris Brezillonaa2670c2020-09-05 18:14:17 +0200968 pandecode_indent++;
Alyssa Rosenzweigf008a632020-08-11 17:27:36 -0400969 pandecode_texture_payload(u + MALI_MIDGARD_TEXTURE_LENGTH,
970 temp.dimension, temp.texel_ordering, temp.manual_stride,
971 temp.levels, temp.depth, temp.array_size, mapped_mem);
Boris Brezillonaa2670c2020-09-05 18:14:17 +0200972 pandecode_indent--;
Alyssa Rosenzweig8fc4ca82019-08-20 14:48:55 -0700973}
974
Alyssa Rosenzweig497977b2020-03-09 13:51:39 -0400975static void
Alyssa Rosenzweiga3d29362020-04-21 16:08:07 -0400976pandecode_bifrost_texture(
Alyssa Rosenzweigad0b32c2020-08-06 18:12:28 -0400977 const void *cl,
Alyssa Rosenzweiga3d29362020-04-21 16:08:07 -0400978 unsigned job_no,
979 unsigned tex)
Alyssa Rosenzweig497977b2020-03-09 13:51:39 -0400980{
Boris Brezillon706974c2020-09-15 09:25:18 +0200981 pan_unpack(cl, BIFROST_TEXTURE, temp);
Boris Brezillonaa2670c2020-09-05 18:14:17 +0200982 DUMP_UNPACKED(BIFROST_TEXTURE, temp, "Texture:\n")
Alyssa Rosenzweig497977b2020-03-09 13:51:39 -0400983
Alyssa Rosenzweigad0b32c2020-08-06 18:12:28 -0400984 struct pandecode_mapped_memory *tmem = pandecode_find_mapped_gpu_mem_containing(temp.surfaces);
Boris Brezillonaa2670c2020-09-05 18:14:17 +0200985 pandecode_indent++;
Alyssa Rosenzweigad0b32c2020-08-06 18:12:28 -0400986 pandecode_texture_payload(temp.surfaces, temp.dimension, temp.texel_ordering,
987 true, temp.levels, 1, 1, tmem);
Boris Brezillonaa2670c2020-09-05 18:14:17 +0200988 pandecode_indent--;
Alyssa Rosenzweig497977b2020-03-09 13:51:39 -0400989}
990
Alyssa Rosenzweigcbbf7542019-08-21 14:57:23 -0700991/* 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 */
992
993static void
994pandecode_shader_prop(const char *name, unsigned claim, signed truth, bool fuzzy)
995{
996 /* Nothing to do */
997 if (claim == truth)
998 return;
999
Alyssa Rosenzweig5815f332020-02-25 17:29:55 -05001000 if (fuzzy && (truth < 0))
1001 pandecode_msg("XXX: fuzzy %s, claimed %d, expected %d\n", name, claim, truth);
Alyssa Rosenzweigcbbf7542019-08-21 14:57:23 -07001002
1003 if ((truth >= 0) && !fuzzy) {
Alyssa Rosenzweigf48136e2019-08-22 09:02:48 -07001004 pandecode_msg("%s: expected %s = %d, claimed %u\n",
1005 (truth < claim) ? "warn" : "XXX",
Alyssa Rosenzweigcbbf7542019-08-21 14:57:23 -07001006 name, truth, claim);
1007 } else if ((claim > -truth) && !fuzzy) {
1008 pandecode_msg("XXX: expected %s <= %u, claimed %u\n",
1009 name, -truth, claim);
1010 } else if (fuzzy && (claim < truth))
1011 pandecode_msg("XXX: expected %s >= %u, claimed %u\n",
1012 name, truth, claim);
1013
1014 pandecode_log(".%s = %" PRId16, name, claim);
1015
1016 if (fuzzy)
1017 pandecode_log_cont(" /* %u used */", truth);
1018
1019 pandecode_log_cont(",\n");
1020}
1021
Alyssa Rosenzweig8fc4ca82019-08-20 14:48:55 -07001022static void
Tomeu Vizoso8e1ae5f2019-11-05 15:31:42 +01001023pandecode_blend_shader_disassemble(mali_ptr shader, int job_no, int job_type,
Tomeu Vizoso072207b2019-11-07 08:27:53 +01001024 bool is_bifrost, unsigned gpu_id)
Tomeu Vizoso8e1ae5f2019-11-05 15:31:42 +01001025{
1026 struct midgard_disasm_stats stats =
Tomeu Vizoso072207b2019-11-07 08:27:53 +01001027 pandecode_shader_disassemble(shader, job_no, job_type, is_bifrost, gpu_id);
Tomeu Vizoso8e1ae5f2019-11-05 15:31:42 +01001028
1029 bool has_texture = (stats.texture_count > 0);
1030 bool has_sampler = (stats.sampler_count > 0);
1031 bool has_attribute = (stats.attribute_count > 0);
1032 bool has_varying = (stats.varying_count > 0);
1033 bool has_uniform = (stats.uniform_count > 0);
1034 bool has_ubo = (stats.uniform_buffer_count > 0);
1035
1036 if (has_texture || has_sampler)
1037 pandecode_msg("XXX: blend shader accessing textures\n");
1038
1039 if (has_attribute || has_varying)
1040 pandecode_msg("XXX: blend shader accessing interstage\n");
1041
1042 if (has_uniform || has_ubo)
1043 pandecode_msg("XXX: blend shader accessing uniforms\n");
1044}
1045
1046static void
Alyssa Rosenzweig497977b2020-03-09 13:51:39 -04001047pandecode_textures(mali_ptr textures, unsigned texture_count, int job_no, bool is_bifrost)
1048{
1049 struct pandecode_mapped_memory *mmem = pandecode_find_mapped_gpu_mem_containing(textures);
1050
1051 if (!mmem)
1052 return;
1053
Alyssa Rosenzweigad0b32c2020-08-06 18:12:28 -04001054 pandecode_log("Textures (%"PRIx64"):\n", textures);
1055
Alyssa Rosenzweig497977b2020-03-09 13:51:39 -04001056 if (is_bifrost) {
Alyssa Rosenzweigad0b32c2020-08-06 18:12:28 -04001057 const void *cl = pandecode_fetch_gpu_mem(mmem,
1058 textures, MALI_BIFROST_TEXTURE_LENGTH *
1059 texture_count);
Alyssa Rosenzweig497977b2020-03-09 13:51:39 -04001060
Alyssa Rosenzweigad0b32c2020-08-06 18:12:28 -04001061 for (unsigned tex = 0; tex < texture_count; ++tex) {
1062 pandecode_bifrost_texture(cl +
1063 MALI_BIFROST_TEXTURE_LENGTH * tex,
1064 job_no, tex);
1065 }
Alyssa Rosenzweig497977b2020-03-09 13:51:39 -04001066 } else {
1067 mali_ptr *PANDECODE_PTR_VAR(u, mmem, textures);
1068
Alyssa Rosenzweig497977b2020-03-09 13:51:39 -04001069 for (int tex = 0; tex < texture_count; ++tex) {
1070 mali_ptr *PANDECODE_PTR_VAR(u, mmem, textures + tex * sizeof(mali_ptr));
1071 char *a = pointer_as_memory_reference(*u);
1072 pandecode_log("%s,\n", a);
1073 free(a);
1074 }
1075
Alyssa Rosenzweig497977b2020-03-09 13:51:39 -04001076 /* Now, finally, descend down into the texture descriptor */
1077 for (unsigned tex = 0; tex < texture_count; ++tex) {
1078 mali_ptr *PANDECODE_PTR_VAR(u, mmem, textures + tex * sizeof(mali_ptr));
1079 struct pandecode_mapped_memory *tmem = pandecode_find_mapped_gpu_mem_containing(*u);
1080 if (tmem)
1081 pandecode_texture(*u, tmem, job_no, tex);
1082 }
1083 }
1084}
1085
1086static void
1087pandecode_samplers(mali_ptr samplers, unsigned sampler_count, int job_no, bool is_bifrost)
1088{
Alyssa Rosenzweigb10c3c82020-08-11 18:25:03 -04001089 for (int i = 0; i < sampler_count; ++i) {
1090 if (is_bifrost) {
Boris Brezillon670e8182020-09-09 17:56:53 +02001091 DUMP_ADDR(BIFROST_SAMPLER, samplers + (MALI_BIFROST_SAMPLER_LENGTH * i), "Sampler:\n");
Alyssa Rosenzweigb10c3c82020-08-11 18:25:03 -04001092 } else {
Boris Brezillon670e8182020-09-09 17:56:53 +02001093 DUMP_ADDR(MIDGARD_SAMPLER, samplers + (MALI_MIDGARD_SAMPLER_LENGTH * i), "Sampler:\n");
Alyssa Rosenzweigb10c3c82020-08-11 18:25:03 -04001094 }
Alyssa Rosenzweig497977b2020-03-09 13:51:39 -04001095 }
1096}
1097
1098static void
Alyssa Rosenzweig8fc4ca82019-08-20 14:48:55 -07001099pandecode_vertex_tiler_postfix_pre(
Alyssa Rosenzweig76028912020-08-26 17:05:41 -04001100 const struct MALI_DRAW *p,
Alyssa Rosenzweig7318b522019-07-10 10:36:16 -07001101 int job_no, enum mali_job_type job_type,
Tomeu Vizoso072207b2019-11-07 08:27:53 +01001102 char *suffix, bool is_bifrost, unsigned gpu_id)
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001103{
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001104 struct pandecode_mapped_memory *attr_mem;
1105
Alyssa Rosenzweigf06e8f72019-08-21 12:06:50 -07001106 struct pandecode_fbd fbd_info = {
1107 /* Default for Bifrost */
1108 .rt_count = 1
1109 };
1110
Alyssa Rosenzweig76028912020-08-26 17:05:41 -04001111 if (is_bifrost)
1112 pandecode_compute_fbd(p->shared & ~1, job_no);
Boris Brezillon5d5f7552020-09-08 10:17:40 +02001113 else if (p->shared & MALI_FBD_TAG_IS_MFBD)
1114 fbd_info = pandecode_mfbd_bfr((u64) ((uintptr_t) p->shared) & ~MALI_FBD_TAG_MASK,
1115 job_no, false, job_type == MALI_JOB_TYPE_COMPUTE, is_bifrost, gpu_id);
Alyssa Rosenzweig4b7056b2020-08-05 18:40:44 -04001116 else if (job_type == MALI_JOB_TYPE_COMPUTE)
Alyssa Rosenzweig76028912020-08-26 17:05:41 -04001117 pandecode_compute_fbd((u64) (uintptr_t) p->shared, job_no);
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001118 else
Alyssa Rosenzweig76028912020-08-26 17:05:41 -04001119 fbd_info = pandecode_sfbd((u64) (uintptr_t) p->shared, job_no, false, gpu_id);
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001120
1121 int varying_count = 0, attribute_count = 0, uniform_count = 0, uniform_buffer_count = 0;
1122 int texture_count = 0, sampler_count = 0;
1123
Alyssa Rosenzweig76028912020-08-26 17:05:41 -04001124 if (p->state) {
1125 struct pandecode_mapped_memory *smem = pandecode_find_mapped_gpu_mem_containing(p->state);
1126 uint32_t *cl = pandecode_fetch_gpu_mem(smem, p->state, MALI_STATE_LENGTH);
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001127
Alyssa Rosenzweigcbbf7542019-08-21 14:57:23 -07001128 /* Disassemble ahead-of-time to get stats. Initialize with
1129 * stats for the missing-shader case so we get validation
1130 * there, too */
1131
1132 struct midgard_disasm_stats info = {
1133 .texture_count = 0,
1134 .sampler_count = 0,
1135 .attribute_count = 0,
1136 .varying_count = 0,
1137 .work_count = 1,
1138
1139 .uniform_count = -128,
1140 .uniform_buffer_count = 0
1141 };
Alyssa Rosenzweig9b067d92019-08-21 14:28:36 -07001142
Boris Brezillon706974c2020-09-15 09:25:18 +02001143 pan_unpack(cl, STATE, state);
Alyssa Rosenzweig661b4692020-08-21 10:34:06 -04001144
Alyssa Rosenzweig3d7ce132020-08-21 19:59:22 -04001145 if (state.shader.shader & ~0xF)
1146 info = pandecode_shader_disassemble(state.shader.shader & ~0xF, job_no, job_type, is_bifrost, gpu_id);
Alyssa Rosenzweig661b4692020-08-21 10:34:06 -04001147
Boris Brezillonaa2670c2020-09-05 18:14:17 +02001148 DUMP_UNPACKED(STATE, state, "State:\n");
1149 pandecode_indent++;
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001150
1151 /* Save for dumps */
Alyssa Rosenzweig3d7ce132020-08-21 19:59:22 -04001152 attribute_count = state.shader.attribute_count;
1153 varying_count = state.shader.varying_count;
1154 texture_count = state.shader.texture_count;
1155 sampler_count = state.shader.sampler_count;
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001156
Alyssa Rosenzweig3d7ce132020-08-21 19:59:22 -04001157 fprintf(pandecode_dump_stream, " Properties\n");
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001158 if (is_bifrost) {
Boris Brezillon706974c2020-09-15 09:25:18 +02001159 pan_unpack(&state.properties, BIFROST_PROPERTIES, bi_props);
Boris Brezillonaa2670c2020-09-05 18:14:17 +02001160 DUMP_UNPACKED(BIFROST_PROPERTIES, bi_props, "Properties:\n");
Alyssa Rosenzweigacf77cb2020-08-20 16:41:41 -04001161
Alyssa Rosenzweig3d7ce132020-08-21 19:59:22 -04001162 uniform_count = state.preload.uniform_count;
Alyssa Rosenzweigacf77cb2020-08-20 16:41:41 -04001163 uniform_buffer_count = bi_props.uniform_buffer_count;
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001164 } else {
Boris Brezillon706974c2020-09-15 09:25:18 +02001165 pan_unpack(&state.properties, MIDGARD_PROPERTIES, midg_props);
Boris Brezillonaa2670c2020-09-05 18:14:17 +02001166 DUMP_UNPACKED(MIDGARD_PROPERTIES, midg_props, "Properties:\n")
Alyssa Rosenzweig1b7d4f12020-08-20 16:25:14 -04001167
1168 uniform_count = midg_props.uniform_count;
1169 uniform_buffer_count = midg_props.uniform_buffer_count;
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001170 }
1171
Alyssa Rosenzweig661b4692020-08-21 10:34:06 -04001172 pandecode_shader_prop("texture_count", texture_count, info.texture_count, false);
1173 pandecode_shader_prop("sampler_count", sampler_count, info.sampler_count, false);
1174 pandecode_shader_prop("attribute_count", attribute_count, info.attribute_count, false);
1175 pandecode_shader_prop("varying_count", varying_count, info.varying_count, false);
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001176
Alyssa Rosenzweig7a95ed22020-08-20 20:42:32 -04001177 if (is_bifrost) {
Alyssa Rosenzweig3d7ce132020-08-21 19:59:22 -04001178 uint32_t opaque = state.preload.uniform_count << 15
1179 | state.preload.untyped;
1180
Alyssa Rosenzweig7a95ed22020-08-20 20:42:32 -04001181 switch (job_type) {
1182 case MALI_JOB_TYPE_VERTEX:
Boris Brezillon670e8182020-09-09 17:56:53 +02001183 DUMP_CL(PRELOAD_VERTEX, &opaque, "Preload:\n");
Alyssa Rosenzweig7a95ed22020-08-20 20:42:32 -04001184 break;
1185 case MALI_JOB_TYPE_TILER:
Boris Brezillon670e8182020-09-09 17:56:53 +02001186 DUMP_CL(PRELOAD_FRAGMENT, &opaque, "Preload:\n");
Alyssa Rosenzweig7a95ed22020-08-20 20:42:32 -04001187 break;
1188 case MALI_JOB_TYPE_COMPUTE:
Boris Brezillon670e8182020-09-09 17:56:53 +02001189 DUMP_CL(PRELOAD_COMPUTE, &opaque, "Preload:\n");
Alyssa Rosenzweig7a95ed22020-08-20 20:42:32 -04001190 break;
1191 default:
Boris Brezillon670e8182020-09-09 17:56:53 +02001192 DUMP_CL(PRELOAD, &opaque, "Preload:\n");
Alyssa Rosenzweig7a95ed22020-08-20 20:42:32 -04001193 break;
1194 }
1195 }
1196
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001197 if (!is_bifrost) {
Alyssa Rosenzweig050b9342019-05-04 21:57:01 +00001198 /* TODO: Blend shaders routing/disasm */
Alyssa Rosenzweig3d7ce132020-08-21 19:59:22 -04001199 union midgard_blend blend;
1200 memcpy(&blend, &state.sfbd_blend, sizeof(blend));
1201 mali_ptr shader = pandecode_midgard_blend(&blend, state.multisample_misc.sfbd_blend_shader);
Tomeu Vizoso8e1ae5f2019-11-05 15:31:42 +01001202 if (shader & ~0xF)
Tomeu Vizoso072207b2019-11-07 08:27:53 +01001203 pandecode_blend_shader_disassemble(shader, job_no, job_type, false, gpu_id);
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001204 }
Boris Brezillonaa2670c2020-09-05 18:14:17 +02001205 pandecode_indent--;
1206 pandecode_msg("\n");
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001207
Alyssa Rosenzweig050b9342019-05-04 21:57:01 +00001208 /* MRT blend fields are used whenever MFBD is used, with
1209 * per-RT descriptors */
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001210
Boris Brezillon5d5f7552020-09-08 10:17:40 +02001211 if (job_type == MALI_JOB_TYPE_TILER &&
1212 (is_bifrost || p->shared & MALI_FBD_TAG_IS_MFBD)) {
Alyssa Rosenzweig3d7ce132020-08-21 19:59:22 -04001213 void* blend_base = ((void *) cl) + MALI_STATE_LENGTH;
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001214
Alyssa Rosenzweigf06e8f72019-08-21 12:06:50 -07001215 for (unsigned i = 0; i < fbd_info.rt_count; i++) {
Alyssa Rosenzweig050b9342019-05-04 21:57:01 +00001216 mali_ptr shader = 0;
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001217
Alyssa Rosenzweig050b9342019-05-04 21:57:01 +00001218 if (is_bifrost)
1219 shader = pandecode_bifrost_blend(blend_base, job_no, i);
1220 else
1221 shader = pandecode_midgard_blend_mrt(blend_base, job_no, i);
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001222
Tomeu Vizoso8e1ae5f2019-11-05 15:31:42 +01001223 if (shader & ~0xF)
Tomeu Vizoso072207b2019-11-07 08:27:53 +01001224 pandecode_blend_shader_disassemble(shader, job_no, job_type, false, gpu_id);
Alyssa Rosenzweig139708b2019-08-21 14:04:05 -07001225
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001226 }
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001227 }
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001228 } else
Alyssa Rosenzweig5f9a1c72019-08-21 14:16:32 -07001229 pandecode_msg("XXX: missing shader descriptor\n");
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001230
Alyssa Rosenzweig7f487e02020-08-05 19:33:20 -04001231 if (p->viewport)
Boris Brezillon670e8182020-09-09 17:56:53 +02001232 DUMP_ADDR(VIEWPORT, p->viewport, "Viewport:\n");
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001233
Alyssa Rosenzweiged464e02019-08-22 13:07:01 -07001234 unsigned max_attr_index = 0;
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001235
Alyssa Rosenzweig76028912020-08-26 17:05:41 -04001236 if (p->attributes)
1237 max_attr_index = pandecode_attribute_meta(attribute_count, p->attributes, false, suffix);
Alyssa Rosenzweiged464e02019-08-22 13:07:01 -07001238
Alyssa Rosenzweig76028912020-08-26 17:05:41 -04001239 if (p->attribute_buffers) {
1240 attr_mem = pandecode_find_mapped_gpu_mem_containing(p->attribute_buffers);
1241 pandecode_attributes(attr_mem, p->attribute_buffers, job_no, suffix, max_attr_index, false, job_type);
Alyssa Rosenzweig9e66ff32019-07-31 11:52:52 -07001242 }
1243
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001244 if (p->varyings) {
Alyssa Rosenzweig76028912020-08-26 17:05:41 -04001245 varying_count = pandecode_attribute_meta(varying_count, p->varyings, true, suffix);
1246 }
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001247
Alyssa Rosenzweig76028912020-08-26 17:05:41 -04001248 if (p->varying_buffers) {
1249 attr_mem = pandecode_find_mapped_gpu_mem_containing(p->varying_buffers);
1250 pandecode_attributes(attr_mem, p->varying_buffers, job_no, suffix, varying_count, true, job_type);
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001251 }
1252
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001253 if (p->uniform_buffers) {
Alyssa Rosenzweig4aeb6942019-08-19 15:16:01 -07001254 if (uniform_buffer_count)
1255 pandecode_uniform_buffers(p->uniform_buffers, uniform_buffer_count, job_no);
1256 else
Alyssa Rosenzweigcbbf7542019-08-21 14:57:23 -07001257 pandecode_msg("warn: UBOs specified but not referenced\n");
Alyssa Rosenzweig4aeb6942019-08-19 15:16:01 -07001258 } else if (uniform_buffer_count)
1259 pandecode_msg("XXX: UBOs referenced but not specified\n");
1260
1261 /* We don't want to actually dump uniforms, but we do need to validate
1262 * that the counts we were given are sane */
1263
Alyssa Rosenzweig76028912020-08-26 17:05:41 -04001264 if (p->push_uniforms) {
Alyssa Rosenzweig4aeb6942019-08-19 15:16:01 -07001265 if (uniform_count)
Alyssa Rosenzweig76028912020-08-26 17:05:41 -04001266 pandecode_uniforms(p->push_uniforms, uniform_count);
Alyssa Rosenzweig4aeb6942019-08-19 15:16:01 -07001267 else
Alyssa Rosenzweigcbbf7542019-08-21 14:57:23 -07001268 pandecode_msg("warn: Uniforms specified but not referenced\n");
Alyssa Rosenzweig4aeb6942019-08-19 15:16:01 -07001269 } else if (uniform_count)
Alyssa Rosenzweigd7473e22019-08-21 14:15:05 -07001270 pandecode_msg("XXX: Uniforms referenced but not specified\n");
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001271
Alyssa Rosenzweig497977b2020-03-09 13:51:39 -04001272 if (p->textures)
1273 pandecode_textures(p->textures, texture_count, job_no, is_bifrost);
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001274
Alyssa Rosenzweig76028912020-08-26 17:05:41 -04001275 if (p->samplers)
1276 pandecode_samplers(p->samplers, sampler_count, job_no, is_bifrost);
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001277}
1278
1279static void
Boris Brezillonefce73d2020-09-08 10:11:26 +02001280pandecode_bifrost_tiler_heap(mali_ptr gpu_va, int job_no)
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001281{
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001282 struct pandecode_mapped_memory *mem = pandecode_find_mapped_gpu_mem_containing(gpu_va);
Boris Brezillonefce73d2020-09-08 10:11:26 +02001283 pan_unpack(PANDECODE_PTR(mem, gpu_va, void), BIFROST_TILER_HEAP, h);
1284 DUMP_UNPACKED(BIFROST_TILER_HEAP, h, "Bifrost Tiler Heap:\n");
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001285}
1286
1287static void
Boris Brezillonefce73d2020-09-08 10:11:26 +02001288pandecode_bifrost_tiler(mali_ptr gpu_va, int job_no)
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001289{
1290 struct pandecode_mapped_memory *mem = pandecode_find_mapped_gpu_mem_containing(gpu_va);
Boris Brezillonefce73d2020-09-08 10:11:26 +02001291 pan_unpack(PANDECODE_PTR(mem, gpu_va, void), BIFROST_TILER, t);
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001292
Boris Brezillonefce73d2020-09-08 10:11:26 +02001293 pandecode_bifrost_tiler_heap(t.heap, job_no);
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001294
Boris Brezillonefce73d2020-09-08 10:11:26 +02001295 DUMP_UNPACKED(BIFROST_TILER, t, "Bifrost Tiler:\n");
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001296 pandecode_indent++;
Boris Brezillonefce73d2020-09-08 10:11:26 +02001297 if (t.hierarchy_mask != 0xa &&
1298 t.hierarchy_mask != 0x14 &&
1299 t.hierarchy_mask != 0x28 &&
1300 t.hierarchy_mask != 0x50 &&
1301 t.hierarchy_mask != 0xa0)
Tomeu Vizoso0a0b6702020-04-09 09:39:17 +02001302 pandecode_prop("XXX: Unexpected hierarchy_mask (not 0xa, 0x14, 0x28, 0x50 or 0xa0)!");
1303
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001304 pandecode_indent--;
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001305}
1306
1307static void
Alyssa Rosenzweig7103baf2019-07-12 08:57:10 -07001308pandecode_primitive_size(union midgard_primitive_size u, bool constant)
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001309{
Alyssa Rosenzweig2608da12019-06-19 09:35:57 -07001310 if (u.pointer == 0x0)
1311 return;
1312
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001313 pandecode_log(".primitive_size = {\n");
1314 pandecode_indent++;
1315
Alyssa Rosenzweigb517e362019-03-15 03:21:27 +00001316 if (constant) {
1317 pandecode_prop("constant = %f", u.constant);
1318 } else {
1319 MEMORY_PROP((&u), pointer);
1320 }
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001321
1322 pandecode_indent--;
1323 pandecode_log("},\n");
1324}
1325
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001326static int
Boris Brezilloneb923542020-09-08 07:07:41 +02001327pandecode_vertex_job_bfr(const struct MALI_JOB_HEADER *h,
1328 const struct pandecode_mapped_memory *mem,
1329 mali_ptr payload, int job_no, unsigned gpu_id)
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001330{
1331 struct bifrost_payload_vertex *PANDECODE_PTR_VAR(v, mem, payload);
1332
Alyssa Rosenzweig76028912020-08-26 17:05:41 -04001333 struct mali_draw_packed draw_packed;
1334 memcpy(&draw_packed, &v->postfix, sizeof(draw_packed));
Boris Brezillon706974c2020-09-15 09:25:18 +02001335 pan_unpack(&draw_packed, DRAW, draw);
Boris Brezilloneb923542020-09-08 07:07:41 +02001336 pandecode_vertex_tiler_postfix_pre(&draw, job_no, h->type, "", true, gpu_id);
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001337
Alyssa Rosenzweig25ed9302019-08-16 16:22:38 -07001338 pandecode_vertex_tiler_prefix(&v->prefix, job_no, false);
Boris Brezillon670e8182020-09-09 17:56:53 +02001339 DUMP_CL(DRAW, &draw_packed, "Draw:\n");
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001340
1341 return sizeof(*v);
1342}
1343
1344static int
Boris Brezilloneb923542020-09-08 07:07:41 +02001345pandecode_tiler_job_bfr(const struct MALI_JOB_HEADER *h,
1346 const struct pandecode_mapped_memory *mem,
1347 mali_ptr payload, int job_no, unsigned gpu_id)
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001348{
1349 struct bifrost_payload_tiler *PANDECODE_PTR_VAR(t, mem, payload);
1350
Alyssa Rosenzweig76028912020-08-26 17:05:41 -04001351 struct mali_draw_packed draw_packed;
1352 memcpy(&draw_packed, &t->postfix, sizeof(draw_packed));
Boris Brezillon706974c2020-09-15 09:25:18 +02001353 pan_unpack(&draw_packed, DRAW, draw);
Boris Brezilloneb923542020-09-08 07:07:41 +02001354 pandecode_vertex_tiler_postfix_pre(&draw, job_no, h->type, "", true, gpu_id);
Boris Brezillonefce73d2020-09-08 10:11:26 +02001355 pandecode_bifrost_tiler(t->tiler_meta, job_no);
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001356
Alyssa Rosenzweig25ed9302019-08-16 16:22:38 -07001357 pandecode_vertex_tiler_prefix(&t->prefix, job_no, false);
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001358
Alyssa Rosenzweig4467e792020-08-26 13:21:06 -04001359 /* TODO: gl_PointSize on Bifrost */
1360 pandecode_primitive_size(t->primitive_size, true);
1361
1362 if (t->zero1 || t->zero2 || t->zero3 || t->zero4 || t->zero5
1363 || t->zero6) {
1364 pandecode_msg("XXX: tiler only zero tripped\n");
1365 pandecode_prop("zero1 = 0x%" PRIx64, t->zero1);
1366 pandecode_prop("zero2 = 0x%" PRIx64, t->zero2);
1367 pandecode_prop("zero3 = 0x%" PRIx64, t->zero3);
1368 pandecode_prop("zero4 = 0x%" PRIx64, t->zero4);
1369 pandecode_prop("zero5 = 0x%" PRIx64, t->zero5);
1370 pandecode_prop("zero6 = 0x%" PRIx64, t->zero6);
1371 }
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001372
Boris Brezillon670e8182020-09-09 17:56:53 +02001373 DUMP_CL(DRAW, &draw_packed, "Draw:\n");
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001374
1375 return sizeof(*t);
1376}
1377
1378static int
Boris Brezilloneb923542020-09-08 07:07:41 +02001379pandecode_vertex_or_tiler_job_mdg(const struct MALI_JOB_HEADER *h,
1380 const struct pandecode_mapped_memory *mem,
1381 mali_ptr payload, int job_no, unsigned gpu_id)
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001382{
1383 struct midgard_payload_vertex_tiler *PANDECODE_PTR_VAR(v, mem, payload);
Boris Brezilloneb923542020-09-08 07:07:41 +02001384 bool is_graphics = (h->type == MALI_JOB_TYPE_VERTEX) || (h->type == MALI_JOB_TYPE_TILER);
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001385
Alyssa Rosenzweig76028912020-08-26 17:05:41 -04001386 struct mali_draw_packed draw_packed;
1387 memcpy(&draw_packed, &v->postfix, sizeof(draw_packed));
Boris Brezillon706974c2020-09-15 09:25:18 +02001388 pan_unpack(&draw_packed, DRAW, draw);
Boris Brezilloneb923542020-09-08 07:07:41 +02001389 pandecode_vertex_tiler_postfix_pre(&draw, job_no, h->type, "", false, gpu_id);
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001390
Alyssa Rosenzweigb010a6d2020-04-06 20:31:32 -04001391 pandecode_vertex_tiler_prefix(&v->prefix, job_no, is_graphics);
Boris Brezillon670e8182020-09-09 17:56:53 +02001392 DUMP_CL(DRAW, &draw_packed, "Draw:\n");
Alyssa Rosenzweigb010a6d2020-04-06 20:31:32 -04001393
Alyssa Rosenzweigb60d5672020-08-25 16:59:14 -04001394 struct mali_primitive_packed prim_packed = v->prefix.primitive;
Boris Brezillon706974c2020-09-15 09:25:18 +02001395 pan_unpack(&prim_packed, PRIMITIVE, primitive);
Alyssa Rosenzweigb60d5672020-08-25 16:59:14 -04001396
1397 pandecode_primitive_size(v->primitive_size, primitive.point_size_array == 0);
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001398
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001399 return sizeof(*v);
1400}
1401
1402static int
Alyssa Rosenzweig7103baf2019-07-12 08:57:10 -07001403pandecode_fragment_job(const struct pandecode_mapped_memory *mem,
Alyssa Rosenzweig7318b522019-07-10 10:36:16 -07001404 mali_ptr payload, int job_no,
Tomeu Vizoso697f02c2019-11-12 12:15:02 +01001405 bool is_bifrost, unsigned gpu_id)
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001406{
1407 const struct mali_payload_fragment *PANDECODE_PTR_VAR(s, mem, payload);
1408
Boris Brezillon5d5f7552020-09-08 10:17:40 +02001409 bool is_mfbd = s->framebuffer & MALI_FBD_TAG_IS_MFBD;
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001410
Alyssa Rosenzweigf06e8f72019-08-21 12:06:50 -07001411 if (!is_mfbd && is_bifrost)
1412 pandecode_msg("XXX: Bifrost fragment must use MFBD\n");
1413
1414 struct pandecode_fbd info;
1415
1416 if (is_mfbd)
Boris Brezillon5d5f7552020-09-08 10:17:40 +02001417 info = pandecode_mfbd_bfr(s->framebuffer & ~MALI_FBD_TAG_MASK, job_no,
1418 true, false, is_bifrost, gpu_id);
Alyssa Rosenzweigf06e8f72019-08-21 12:06:50 -07001419 else
Boris Brezillon5d5f7552020-09-08 10:17:40 +02001420 info = pandecode_sfbd(s->framebuffer & ~MALI_FBD_TAG_MASK, job_no,
1421 true, gpu_id);
Alyssa Rosenzweigf06e8f72019-08-21 12:06:50 -07001422
1423 /* Compute the tag for the tagged pointer. This contains the type of
1424 * FBD (MFBD/SFBD), and in the case of an MFBD, information about which
1425 * additional structures follow the MFBD header (an extra payload or
1426 * not, as well as a count of render targets) */
1427
Boris Brezillon5d5f7552020-09-08 10:17:40 +02001428 unsigned expected_tag = is_mfbd ? MALI_FBD_TAG_IS_MFBD : 0;
Alyssa Rosenzweigf06e8f72019-08-21 12:06:50 -07001429
1430 if (is_mfbd) {
1431 if (info.has_extra)
Boris Brezillon5d5f7552020-09-08 10:17:40 +02001432 expected_tag |= MALI_FBD_TAG_HAS_ZS_RT;
Alyssa Rosenzweigf06e8f72019-08-21 12:06:50 -07001433
1434 expected_tag |= (MALI_POSITIVE(info.rt_count) << 2);
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001435 }
1436
Alyssa Rosenzweigf06e8f72019-08-21 12:06:50 -07001437 if ((s->min_tile_coord | s->max_tile_coord) & ~(MALI_X_COORD_MASK | MALI_Y_COORD_MASK)) {
1438 pandecode_msg("XXX: unexpected tile coordinate bits\n");
1439 pandecode_prop("min_tile_coord = 0x%X\n", s->min_tile_coord);
Alyssa Rosenzweig52d6b4d2020-05-11 18:54:05 -04001440 pandecode_prop("max_tile_coord = 0x%X\n", s->max_tile_coord);
Alyssa Rosenzweigf06e8f72019-08-21 12:06:50 -07001441 }
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001442
Alyssa Rosenzweigded9a682019-08-21 12:29:47 -07001443 /* Extract tile coordinates */
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001444
Alyssa Rosenzweigded9a682019-08-21 12:29:47 -07001445 unsigned min_x = MALI_TILE_COORD_X(s->min_tile_coord) << MALI_TILE_SHIFT;
1446 unsigned min_y = MALI_TILE_COORD_Y(s->min_tile_coord) << MALI_TILE_SHIFT;
1447
1448 unsigned max_x = (MALI_TILE_COORD_X(s->max_tile_coord) + 1) << MALI_TILE_SHIFT;
1449 unsigned max_y = (MALI_TILE_COORD_Y(s->max_tile_coord) + 1) << MALI_TILE_SHIFT;
1450
1451 /* For the max, we also want the floored (rather than ceiled) version for checking */
1452
1453 unsigned max_x_f = (MALI_TILE_COORD_X(s->max_tile_coord)) << MALI_TILE_SHIFT;
1454 unsigned max_y_f = (MALI_TILE_COORD_Y(s->max_tile_coord)) << MALI_TILE_SHIFT;
1455
1456 /* Validate the coordinates are well-ordered */
1457
1458 if (min_x == max_x)
1459 pandecode_msg("XXX: empty X coordinates (%u = %u)\n", min_x, max_x);
1460 else if (min_x > max_x)
1461 pandecode_msg("XXX: misordered X coordinates (%u > %u)\n", min_x, max_x);
1462
1463 if (min_y == max_y)
1464 pandecode_msg("XXX: empty X coordinates (%u = %u)\n", min_x, max_x);
1465 else if (min_y > max_y)
1466 pandecode_msg("XXX: misordered X coordinates (%u > %u)\n", min_x, max_x);
1467
1468 /* Validate the coordinates fit inside the framebuffer. We use floor,
1469 * rather than ceil, for the max coordinates, since the tile
1470 * coordinates for something like an 800x600 framebuffer will actually
1471 * resolve to 800x608, which would otherwise trigger a Y-overflow */
1472
1473 if ((min_x > info.width) || (max_x_f > info.width))
1474 pandecode_msg("XXX: tile coordinates overflow in X direction\n");
1475
1476 if ((min_y > info.height) || (max_y_f > info.height))
1477 pandecode_msg("XXX: tile coordinates overflow in Y direction\n");
1478
1479 /* After validation, we print */
1480
1481 pandecode_log("fragment (%u, %u) ... (%u, %u)\n\n", min_x, min_y, max_x, max_y);
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001482
Alyssa Rosenzweigf06e8f72019-08-21 12:06:50 -07001483 /* The FBD is a tagged pointer */
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001484
Boris Brezillon5d5f7552020-09-08 10:17:40 +02001485 unsigned tag = (s->framebuffer & MALI_FBD_TAG_MASK);
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001486
Alyssa Rosenzweigf06e8f72019-08-21 12:06:50 -07001487 if (tag != expected_tag)
1488 pandecode_msg("XXX: expected FBD tag %X but got %X\n", expected_tag, tag);
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001489
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001490 return sizeof(*s);
1491}
1492
Alyssa Rosenzweig4122f742020-02-18 07:43:51 -05001493/* Entrypoint to start tracing. jc_gpu_va is the GPU address for the first job
1494 * in the chain; later jobs are found by walking the chain. Bifrost is, well,
1495 * if it's bifrost or not. GPU ID is the more finegrained ID (at some point, we
1496 * might wish to combine this with the bifrost parameter) because some details
1497 * are model-specific even within a particular architecture. Minimal traces
1498 * *only* examine the job descriptors, skipping printing entirely if there is
1499 * no faults, and only descends into the payload if there are faults. This is
1500 * useful for looking for faults without the overhead of invasive traces. */
1501
Alyssa Rosenzweig59986462020-02-18 07:46:03 -05001502void
Alyssa Rosenzweig4122f742020-02-18 07:43:51 -05001503pandecode_jc(mali_ptr jc_gpu_va, bool bifrost, unsigned gpu_id, bool minimal)
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001504{
Icecream9501d60d32020-07-16 16:12:13 +12001505 pandecode_dump_file_open();
1506
Alyssa Rosenzweig59986462020-02-18 07:46:03 -05001507 unsigned job_descriptor_number = 0;
Boris Brezilloneb923542020-09-08 07:07:41 +02001508 mali_ptr next_job = 0;
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001509
1510 do {
1511 struct pandecode_mapped_memory *mem =
1512 pandecode_find_mapped_gpu_mem_containing(jc_gpu_va);
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001513 void *payload;
1514
Boris Brezilloneb923542020-09-08 07:07:41 +02001515 pan_unpack(PANDECODE_PTR(mem, jc_gpu_va, struct mali_job_header_packed),
1516 JOB_HEADER, h);
1517 next_job = h.next;
1518 mali_ptr payload_ptr = jc_gpu_va + MALI_JOB_HEADER_LENGTH;
Alyssa Rosenzweigd353b152020-08-21 09:36:14 -04001519 payload = pandecode_fetch_gpu_mem(mem, payload_ptr, 64);
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001520
1521 int job_no = job_descriptor_number++;
1522
Alyssa Rosenzweig4122f742020-02-18 07:43:51 -05001523 /* If the job is good to go, skip it in minimal mode */
Boris Brezilloneb923542020-09-08 07:07:41 +02001524 if (minimal && (h.exception_status == 0x0 || h.exception_status == 0x1))
Alyssa Rosenzweig4122f742020-02-18 07:43:51 -05001525 continue;
1526
Boris Brezilloneb923542020-09-08 07:07:41 +02001527 DUMP_UNPACKED(JOB_HEADER, h, "Job Header:\n");
1528 pandecode_log("\n");
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001529
Boris Brezilloneb923542020-09-08 07:07:41 +02001530 switch (h.type) {
Alyssa Rosenzweig4b7056b2020-08-05 18:40:44 -04001531 case MALI_JOB_TYPE_WRITE_VALUE: {
Alyssa Rosenzweigadf716d2019-12-05 09:06:53 -05001532 struct mali_payload_write_value *s = payload;
1533 pandecode_log("struct mali_payload_write_value payload_%"PRIx64"_%d = {\n", payload_ptr, job_no);
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001534 pandecode_indent++;
Alyssa Rosenzweig9eae9502019-12-04 08:59:29 -05001535 MEMORY_PROP(s, address);
1536
Alyssa Rosenzweigadf716d2019-12-05 09:06:53 -05001537 if (s->value_descriptor != MALI_WRITE_VALUE_ZERO) {
Alyssa Rosenzweig9eae9502019-12-04 08:59:29 -05001538 pandecode_msg("XXX: unknown value descriptor\n");
1539 pandecode_prop("value_descriptor = 0x%" PRIX32, s->value_descriptor);
1540 }
1541
1542 if (s->reserved) {
1543 pandecode_msg("XXX: set value tripped\n");
1544 pandecode_prop("reserved = 0x%" PRIX32, s->reserved);
1545 }
1546
1547 pandecode_prop("immediate = 0x%" PRIX64, s->immediate);
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001548 pandecode_indent--;
1549 pandecode_log("};\n");
1550
1551 break;
1552 }
1553
Alyssa Rosenzweig4b7056b2020-08-05 18:40:44 -04001554 case MALI_JOB_TYPE_TILER:
1555 case MALI_JOB_TYPE_VERTEX:
1556 case MALI_JOB_TYPE_COMPUTE:
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001557 if (bifrost) {
Boris Brezilloneb923542020-09-08 07:07:41 +02001558 if (h.type == MALI_JOB_TYPE_TILER)
1559 pandecode_tiler_job_bfr(&h, mem, payload_ptr, job_no, gpu_id);
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001560 else
Boris Brezilloneb923542020-09-08 07:07:41 +02001561 pandecode_vertex_job_bfr(&h, mem, payload_ptr, job_no, gpu_id);
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001562 } else
Boris Brezilloneb923542020-09-08 07:07:41 +02001563 pandecode_vertex_or_tiler_job_mdg(&h, mem, payload_ptr, job_no, gpu_id);
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001564
1565 break;
1566
Alyssa Rosenzweig4b7056b2020-08-05 18:40:44 -04001567 case MALI_JOB_TYPE_FRAGMENT:
Tomeu Vizoso697f02c2019-11-12 12:15:02 +01001568 pandecode_fragment_job(mem, payload_ptr, job_no, bifrost, gpu_id);
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001569 break;
1570
1571 default:
1572 break;
1573 }
Boris Brezilloneb923542020-09-08 07:07:41 +02001574 } while ((jc_gpu_va = next_job));
Icecream95ef672182020-06-22 22:49:53 +12001575
1576 pandecode_map_read_write();
Alyssa Rosenzweigf6117822019-02-19 05:50:14 +00001577}