1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright (C) 2017-2019 Alyssa Rosenzweig 3bf215546Sopenharmony_ci * Copyright (C) 2017-2019 Connor Abbott 4bf215546Sopenharmony_ci * Copyright (C) 2019 Collabora, Ltd. 5bf215546Sopenharmony_ci * 6bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 7bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 8bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 9bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 11bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 12bf215546Sopenharmony_ci * 13bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 14bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 15bf215546Sopenharmony_ci * Software. 16bf215546Sopenharmony_ci * 17bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22bf215546Sopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23bf215546Sopenharmony_ci * SOFTWARE. 24bf215546Sopenharmony_ci */ 25bf215546Sopenharmony_ci 26bf215546Sopenharmony_ci#include <genxml/gen_macros.h> 27bf215546Sopenharmony_ci#include <stdio.h> 28bf215546Sopenharmony_ci#include <stdlib.h> 29bf215546Sopenharmony_ci#include <memory.h> 30bf215546Sopenharmony_ci#include <stdbool.h> 31bf215546Sopenharmony_ci#include <stdarg.h> 32bf215546Sopenharmony_ci#include <errno.h> 33bf215546Sopenharmony_ci#include <ctype.h> 34bf215546Sopenharmony_ci#include "decode.h" 35bf215546Sopenharmony_ci 36bf215546Sopenharmony_ci#include "midgard/disassemble.h" 37bf215546Sopenharmony_ci#include "bifrost/disassemble.h" 38bf215546Sopenharmony_ci#include "bifrost/valhall/disassemble.h" 39bf215546Sopenharmony_ci 40bf215546Sopenharmony_ci#define DUMP_UNPACKED(T, var, ...) { \ 41bf215546Sopenharmony_ci pandecode_log(__VA_ARGS__); \ 42bf215546Sopenharmony_ci pan_print(pandecode_dump_stream, T, var, (pandecode_indent + 1) * 2); \ 43bf215546Sopenharmony_ci} 44bf215546Sopenharmony_ci 45bf215546Sopenharmony_ci#define DUMP_CL(T, cl, ...) {\ 46bf215546Sopenharmony_ci pan_unpack(cl, T, temp); \ 47bf215546Sopenharmony_ci DUMP_UNPACKED(T, temp, __VA_ARGS__); \ 48bf215546Sopenharmony_ci} 49bf215546Sopenharmony_ci 50bf215546Sopenharmony_ci#define DUMP_SECTION(A, S, cl, ...) { \ 51bf215546Sopenharmony_ci pan_section_unpack(cl, A, S, temp); \ 52bf215546Sopenharmony_ci pandecode_log(__VA_ARGS__); \ 53bf215546Sopenharmony_ci pan_section_print(pandecode_dump_stream, A, S, temp, (pandecode_indent + 1) * 2); \ 54bf215546Sopenharmony_ci} 55bf215546Sopenharmony_ci 56bf215546Sopenharmony_ci#define MAP_ADDR(T, addr, cl) \ 57bf215546Sopenharmony_ci const uint8_t *cl = 0; \ 58bf215546Sopenharmony_ci { \ 59bf215546Sopenharmony_ci struct pandecode_mapped_memory *mapped_mem = pandecode_find_mapped_gpu_mem_containing(addr); \ 60bf215546Sopenharmony_ci cl = pandecode_fetch_gpu_mem(mapped_mem, addr, pan_size(T)); \ 61bf215546Sopenharmony_ci } 62bf215546Sopenharmony_ci 63bf215546Sopenharmony_ci#define DUMP_ADDR(T, addr, ...) {\ 64bf215546Sopenharmony_ci MAP_ADDR(T, addr, cl) \ 65bf215546Sopenharmony_ci DUMP_CL(T, cl, __VA_ARGS__); \ 66bf215546Sopenharmony_ci} 67bf215546Sopenharmony_ci 68bf215546Sopenharmony_ci/* Semantic logging type. 69bf215546Sopenharmony_ci * 70bf215546Sopenharmony_ci * Raw: for raw messages to be printed as is. 71bf215546Sopenharmony_ci * Message: for helpful information to be commented out in replays. 72bf215546Sopenharmony_ci * 73bf215546Sopenharmony_ci * Use one of pandecode_log or pandecode_msg as syntax sugar. 74bf215546Sopenharmony_ci */ 75bf215546Sopenharmony_ci 76bf215546Sopenharmony_cienum pandecode_log_type { 77bf215546Sopenharmony_ci PANDECODE_RAW, 78bf215546Sopenharmony_ci PANDECODE_MESSAGE, 79bf215546Sopenharmony_ci}; 80bf215546Sopenharmony_ci 81bf215546Sopenharmony_ci#define pandecode_log(...) pandecode_log_typed(PANDECODE_RAW, __VA_ARGS__) 82bf215546Sopenharmony_ci#define pandecode_msg(...) pandecode_log_typed(PANDECODE_MESSAGE, __VA_ARGS__) 83bf215546Sopenharmony_ci 84bf215546Sopenharmony_cistatic unsigned pandecode_indent = 0; 85bf215546Sopenharmony_ci 86bf215546Sopenharmony_cistatic void 87bf215546Sopenharmony_cipandecode_make_indent(void) 88bf215546Sopenharmony_ci{ 89bf215546Sopenharmony_ci for (unsigned i = 0; i < pandecode_indent; ++i) 90bf215546Sopenharmony_ci fprintf(pandecode_dump_stream, " "); 91bf215546Sopenharmony_ci} 92bf215546Sopenharmony_ci 93bf215546Sopenharmony_cistatic void PRINTFLIKE(2, 3) 94bf215546Sopenharmony_cipandecode_log_typed(enum pandecode_log_type type, const char *format, ...) 95bf215546Sopenharmony_ci{ 96bf215546Sopenharmony_ci va_list ap; 97bf215546Sopenharmony_ci 98bf215546Sopenharmony_ci pandecode_make_indent(); 99bf215546Sopenharmony_ci 100bf215546Sopenharmony_ci if (type == PANDECODE_MESSAGE) 101bf215546Sopenharmony_ci fprintf(pandecode_dump_stream, "// "); 102bf215546Sopenharmony_ci 103bf215546Sopenharmony_ci va_start(ap, format); 104bf215546Sopenharmony_ci vfprintf(pandecode_dump_stream, format, ap); 105bf215546Sopenharmony_ci va_end(ap); 106bf215546Sopenharmony_ci} 107bf215546Sopenharmony_ci 108bf215546Sopenharmony_cistatic void 109bf215546Sopenharmony_cipandecode_log_cont(const char *format, ...) 110bf215546Sopenharmony_ci{ 111bf215546Sopenharmony_ci va_list ap; 112bf215546Sopenharmony_ci 113bf215546Sopenharmony_ci va_start(ap, format); 114bf215546Sopenharmony_ci vfprintf(pandecode_dump_stream, format, ap); 115bf215546Sopenharmony_ci va_end(ap); 116bf215546Sopenharmony_ci} 117bf215546Sopenharmony_ci 118bf215546Sopenharmony_ci/* To check for memory safety issues, validates that the given pointer in GPU 119bf215546Sopenharmony_ci * memory is valid, containing at least sz bytes. The goal is to eliminate 120bf215546Sopenharmony_ci * GPU-side memory bugs (NULL pointer dereferences, buffer overflows, or buffer 121bf215546Sopenharmony_ci * overruns) by statically validating pointers. 122bf215546Sopenharmony_ci */ 123bf215546Sopenharmony_ci 124bf215546Sopenharmony_cistatic void 125bf215546Sopenharmony_cipandecode_validate_buffer(mali_ptr addr, size_t sz) 126bf215546Sopenharmony_ci{ 127bf215546Sopenharmony_ci if (!addr) { 128bf215546Sopenharmony_ci pandecode_msg("XXX: null pointer deref\n"); 129bf215546Sopenharmony_ci return; 130bf215546Sopenharmony_ci } 131bf215546Sopenharmony_ci 132bf215546Sopenharmony_ci /* Find a BO */ 133bf215546Sopenharmony_ci 134bf215546Sopenharmony_ci struct pandecode_mapped_memory *bo = 135bf215546Sopenharmony_ci pandecode_find_mapped_gpu_mem_containing(addr); 136bf215546Sopenharmony_ci 137bf215546Sopenharmony_ci if (!bo) { 138bf215546Sopenharmony_ci pandecode_msg("XXX: invalid memory dereference\n"); 139bf215546Sopenharmony_ci return; 140bf215546Sopenharmony_ci } 141bf215546Sopenharmony_ci 142bf215546Sopenharmony_ci /* Bounds check */ 143bf215546Sopenharmony_ci 144bf215546Sopenharmony_ci unsigned offset = addr - bo->gpu_va; 145bf215546Sopenharmony_ci unsigned total = offset + sz; 146bf215546Sopenharmony_ci 147bf215546Sopenharmony_ci if (total > bo->length) { 148bf215546Sopenharmony_ci pandecode_msg("XXX: buffer overrun. " 149bf215546Sopenharmony_ci "Chunk of size %zu at offset %d in buffer of size %zu. " 150bf215546Sopenharmony_ci "Overrun by %zu bytes. \n", 151bf215546Sopenharmony_ci sz, offset, bo->length, total - bo->length); 152bf215546Sopenharmony_ci return; 153bf215546Sopenharmony_ci } 154bf215546Sopenharmony_ci} 155bf215546Sopenharmony_ci 156bf215546Sopenharmony_ci#if PAN_ARCH <= 5 157bf215546Sopenharmony_ci/* Midgard's tiler descriptor is embedded within the 158bf215546Sopenharmony_ci * larger FBD */ 159bf215546Sopenharmony_ci 160bf215546Sopenharmony_cistatic void 161bf215546Sopenharmony_cipandecode_midgard_tiler_descriptor( 162bf215546Sopenharmony_ci const struct mali_tiler_context_packed *tp, 163bf215546Sopenharmony_ci const struct mali_tiler_weights_packed *wp) 164bf215546Sopenharmony_ci{ 165bf215546Sopenharmony_ci pan_unpack(tp, TILER_CONTEXT, t); 166bf215546Sopenharmony_ci DUMP_UNPACKED(TILER_CONTEXT, t, "Tiler:\n"); 167bf215546Sopenharmony_ci 168bf215546Sopenharmony_ci /* We've never seen weights used in practice, but they exist */ 169bf215546Sopenharmony_ci pan_unpack(wp, TILER_WEIGHTS, w); 170bf215546Sopenharmony_ci bool nonzero_weights = false; 171bf215546Sopenharmony_ci 172bf215546Sopenharmony_ci nonzero_weights |= w.weight0 != 0x0; 173bf215546Sopenharmony_ci nonzero_weights |= w.weight1 != 0x0; 174bf215546Sopenharmony_ci nonzero_weights |= w.weight2 != 0x0; 175bf215546Sopenharmony_ci nonzero_weights |= w.weight3 != 0x0; 176bf215546Sopenharmony_ci nonzero_weights |= w.weight4 != 0x0; 177bf215546Sopenharmony_ci nonzero_weights |= w.weight5 != 0x0; 178bf215546Sopenharmony_ci nonzero_weights |= w.weight6 != 0x0; 179bf215546Sopenharmony_ci nonzero_weights |= w.weight7 != 0x0; 180bf215546Sopenharmony_ci 181bf215546Sopenharmony_ci if (nonzero_weights) 182bf215546Sopenharmony_ci DUMP_UNPACKED(TILER_WEIGHTS, w, "Tiler Weights:\n"); 183bf215546Sopenharmony_ci} 184bf215546Sopenharmony_ci#endif 185bf215546Sopenharmony_ci 186bf215546Sopenharmony_ci/* Information about the framebuffer passed back for 187bf215546Sopenharmony_ci * additional analysis */ 188bf215546Sopenharmony_ci 189bf215546Sopenharmony_cistruct pandecode_fbd { 190bf215546Sopenharmony_ci unsigned width; 191bf215546Sopenharmony_ci unsigned height; 192bf215546Sopenharmony_ci unsigned rt_count; 193bf215546Sopenharmony_ci bool has_extra; 194bf215546Sopenharmony_ci}; 195bf215546Sopenharmony_ci 196bf215546Sopenharmony_ci#if PAN_ARCH == 4 197bf215546Sopenharmony_cistatic struct pandecode_fbd 198bf215546Sopenharmony_cipandecode_sfbd(uint64_t gpu_va, int job_no, bool is_fragment, unsigned gpu_id) 199bf215546Sopenharmony_ci{ 200bf215546Sopenharmony_ci struct pandecode_mapped_memory *mem = pandecode_find_mapped_gpu_mem_containing(gpu_va); 201bf215546Sopenharmony_ci const void *PANDECODE_PTR_VAR(s, mem, (mali_ptr) gpu_va); 202bf215546Sopenharmony_ci 203bf215546Sopenharmony_ci struct pandecode_fbd info = { 204bf215546Sopenharmony_ci .has_extra = false, 205bf215546Sopenharmony_ci .rt_count = 1 206bf215546Sopenharmony_ci }; 207bf215546Sopenharmony_ci 208bf215546Sopenharmony_ci pandecode_log("Framebuffer:\n"); 209bf215546Sopenharmony_ci pandecode_indent++; 210bf215546Sopenharmony_ci 211bf215546Sopenharmony_ci DUMP_SECTION(FRAMEBUFFER, LOCAL_STORAGE, s, "Local Storage:\n"); 212bf215546Sopenharmony_ci pan_section_unpack(s, FRAMEBUFFER, PARAMETERS, p); 213bf215546Sopenharmony_ci DUMP_UNPACKED(FRAMEBUFFER_PARAMETERS, p, "Parameters:\n"); 214bf215546Sopenharmony_ci 215bf215546Sopenharmony_ci const void *t = pan_section_ptr(s, FRAMEBUFFER, TILER); 216bf215546Sopenharmony_ci const void *w = pan_section_ptr(s, FRAMEBUFFER, TILER_WEIGHTS); 217bf215546Sopenharmony_ci 218bf215546Sopenharmony_ci pandecode_midgard_tiler_descriptor(t, w); 219bf215546Sopenharmony_ci 220bf215546Sopenharmony_ci pandecode_indent--; 221bf215546Sopenharmony_ci 222bf215546Sopenharmony_ci /* Dummy unpack of the padding section to make sure all words are 0. 223bf215546Sopenharmony_ci * No need to call print here since the section is supposed to be empty. 224bf215546Sopenharmony_ci */ 225bf215546Sopenharmony_ci pan_section_unpack(s, FRAMEBUFFER, PADDING_1, padding1); 226bf215546Sopenharmony_ci pan_section_unpack(s, FRAMEBUFFER, PADDING_2, padding2); 227bf215546Sopenharmony_ci pandecode_log("\n"); 228bf215546Sopenharmony_ci 229bf215546Sopenharmony_ci return info; 230bf215546Sopenharmony_ci} 231bf215546Sopenharmony_ci#endif 232bf215546Sopenharmony_ci 233bf215546Sopenharmony_ci#if PAN_ARCH >= 5 234bf215546Sopenharmony_cistatic void 235bf215546Sopenharmony_cipandecode_local_storage(uint64_t gpu_va, int job_no) 236bf215546Sopenharmony_ci{ 237bf215546Sopenharmony_ci struct pandecode_mapped_memory *mem = pandecode_find_mapped_gpu_mem_containing(gpu_va); 238bf215546Sopenharmony_ci const struct mali_local_storage_packed *PANDECODE_PTR_VAR(s, mem, (mali_ptr) gpu_va); 239bf215546Sopenharmony_ci DUMP_CL(LOCAL_STORAGE, s, "Local Storage:\n"); 240bf215546Sopenharmony_ci} 241bf215546Sopenharmony_ci 242bf215546Sopenharmony_cistatic void 243bf215546Sopenharmony_cipandecode_render_target(uint64_t gpu_va, unsigned job_no, unsigned gpu_id, 244bf215546Sopenharmony_ci const struct MALI_FRAMEBUFFER_PARAMETERS *fb) 245bf215546Sopenharmony_ci{ 246bf215546Sopenharmony_ci pandecode_log("Color Render Targets:\n"); 247bf215546Sopenharmony_ci pandecode_indent++; 248bf215546Sopenharmony_ci 249bf215546Sopenharmony_ci for (int i = 0; i < (fb->render_target_count); i++) { 250bf215546Sopenharmony_ci mali_ptr rt_va = gpu_va + i * pan_size(RENDER_TARGET); 251bf215546Sopenharmony_ci struct pandecode_mapped_memory *mem = 252bf215546Sopenharmony_ci pandecode_find_mapped_gpu_mem_containing(rt_va); 253bf215546Sopenharmony_ci const struct mali_render_target_packed *PANDECODE_PTR_VAR(rtp, mem, (mali_ptr) rt_va); 254bf215546Sopenharmony_ci DUMP_CL(RENDER_TARGET, rtp, "Color Render Target %d:\n", i); 255bf215546Sopenharmony_ci } 256bf215546Sopenharmony_ci 257bf215546Sopenharmony_ci pandecode_indent--; 258bf215546Sopenharmony_ci pandecode_log("\n"); 259bf215546Sopenharmony_ci} 260bf215546Sopenharmony_ci#endif 261bf215546Sopenharmony_ci 262bf215546Sopenharmony_ci#if PAN_ARCH >= 6 263bf215546Sopenharmony_cistatic void 264bf215546Sopenharmony_cipandecode_sample_locations(const void *fb, int job_no) 265bf215546Sopenharmony_ci{ 266bf215546Sopenharmony_ci pan_section_unpack(fb, FRAMEBUFFER, PARAMETERS, params); 267bf215546Sopenharmony_ci 268bf215546Sopenharmony_ci struct pandecode_mapped_memory *smem = 269bf215546Sopenharmony_ci pandecode_find_mapped_gpu_mem_containing(params.sample_locations); 270bf215546Sopenharmony_ci 271bf215546Sopenharmony_ci const u16 *PANDECODE_PTR_VAR(samples, smem, params.sample_locations); 272bf215546Sopenharmony_ci 273bf215546Sopenharmony_ci pandecode_log("Sample locations:\n"); 274bf215546Sopenharmony_ci for (int i = 0; i < 33; i++) { 275bf215546Sopenharmony_ci pandecode_log(" (%d, %d),\n", 276bf215546Sopenharmony_ci samples[2 * i] - 128, 277bf215546Sopenharmony_ci samples[2 * i + 1] - 128); 278bf215546Sopenharmony_ci } 279bf215546Sopenharmony_ci} 280bf215546Sopenharmony_ci#endif 281bf215546Sopenharmony_ci 282bf215546Sopenharmony_cistatic void 283bf215546Sopenharmony_cipandecode_dcd(const struct MALI_DRAW *p, 284bf215546Sopenharmony_ci int job_no, enum mali_job_type job_type, 285bf215546Sopenharmony_ci char *suffix, unsigned gpu_id); 286bf215546Sopenharmony_ci 287bf215546Sopenharmony_ci#if PAN_ARCH >= 5 288bf215546Sopenharmony_cistatic struct pandecode_fbd 289bf215546Sopenharmony_cipandecode_mfbd_bfr(uint64_t gpu_va, int job_no, bool is_fragment, unsigned gpu_id) 290bf215546Sopenharmony_ci{ 291bf215546Sopenharmony_ci struct pandecode_mapped_memory *mem = pandecode_find_mapped_gpu_mem_containing(gpu_va); 292bf215546Sopenharmony_ci const void *PANDECODE_PTR_VAR(fb, mem, (mali_ptr) gpu_va); 293bf215546Sopenharmony_ci pan_section_unpack(fb, FRAMEBUFFER, PARAMETERS, params); 294bf215546Sopenharmony_ci 295bf215546Sopenharmony_ci struct pandecode_fbd info; 296bf215546Sopenharmony_ci 297bf215546Sopenharmony_ci#if PAN_ARCH >= 6 298bf215546Sopenharmony_ci pandecode_sample_locations(fb, job_no); 299bf215546Sopenharmony_ci 300bf215546Sopenharmony_ci pan_section_unpack(fb, FRAMEBUFFER, PARAMETERS, bparams); 301bf215546Sopenharmony_ci unsigned dcd_size = pan_size(DRAW); 302bf215546Sopenharmony_ci struct pandecode_mapped_memory *dcdmem = 303bf215546Sopenharmony_ci pandecode_find_mapped_gpu_mem_containing(bparams.frame_shader_dcds); 304bf215546Sopenharmony_ci 305bf215546Sopenharmony_ci if (bparams.pre_frame_0 != MALI_PRE_POST_FRAME_SHADER_MODE_NEVER) { 306bf215546Sopenharmony_ci const void *PANDECODE_PTR_VAR(dcd, dcdmem, bparams.frame_shader_dcds + (0 * dcd_size)); 307bf215546Sopenharmony_ci pan_unpack(dcd, DRAW, draw); 308bf215546Sopenharmony_ci pandecode_log("Pre frame 0:\n"); 309bf215546Sopenharmony_ci pandecode_dcd(&draw, job_no, MALI_JOB_TYPE_FRAGMENT, "", gpu_id); 310bf215546Sopenharmony_ci } 311bf215546Sopenharmony_ci 312bf215546Sopenharmony_ci if (bparams.pre_frame_1 != MALI_PRE_POST_FRAME_SHADER_MODE_NEVER) { 313bf215546Sopenharmony_ci const void *PANDECODE_PTR_VAR(dcd, dcdmem, bparams.frame_shader_dcds + (1 * dcd_size)); 314bf215546Sopenharmony_ci pan_unpack(dcd, DRAW, draw); 315bf215546Sopenharmony_ci pandecode_log("Pre frame 1:\n"); 316bf215546Sopenharmony_ci pandecode_dcd(&draw, job_no, MALI_JOB_TYPE_FRAGMENT, "", gpu_id); 317bf215546Sopenharmony_ci } 318bf215546Sopenharmony_ci 319bf215546Sopenharmony_ci if (bparams.post_frame != MALI_PRE_POST_FRAME_SHADER_MODE_NEVER) { 320bf215546Sopenharmony_ci const void *PANDECODE_PTR_VAR(dcd, dcdmem, bparams.frame_shader_dcds + (2 * dcd_size)); 321bf215546Sopenharmony_ci pan_unpack(dcd, DRAW, draw); 322bf215546Sopenharmony_ci pandecode_log("Post frame:\n"); 323bf215546Sopenharmony_ci pandecode_dcd(&draw, job_no, MALI_JOB_TYPE_FRAGMENT, "", gpu_id); 324bf215546Sopenharmony_ci } 325bf215546Sopenharmony_ci#endif 326bf215546Sopenharmony_ci 327bf215546Sopenharmony_ci pandecode_log("Multi-Target Framebuffer:\n"); 328bf215546Sopenharmony_ci pandecode_indent++; 329bf215546Sopenharmony_ci 330bf215546Sopenharmony_ci#if PAN_ARCH <= 5 331bf215546Sopenharmony_ci DUMP_SECTION(FRAMEBUFFER, LOCAL_STORAGE, fb, "Local Storage:\n"); 332bf215546Sopenharmony_ci#endif 333bf215546Sopenharmony_ci 334bf215546Sopenharmony_ci info.width = params.width; 335bf215546Sopenharmony_ci info.height = params.height; 336bf215546Sopenharmony_ci info.rt_count = params.render_target_count; 337bf215546Sopenharmony_ci DUMP_UNPACKED(FRAMEBUFFER_PARAMETERS, params, "Parameters:\n"); 338bf215546Sopenharmony_ci 339bf215546Sopenharmony_ci#if PAN_ARCH <= 5 340bf215546Sopenharmony_ci const void *t = pan_section_ptr(fb, FRAMEBUFFER, TILER); 341bf215546Sopenharmony_ci const void *w = pan_section_ptr(fb, FRAMEBUFFER, TILER_WEIGHTS); 342bf215546Sopenharmony_ci pandecode_midgard_tiler_descriptor(t, w); 343bf215546Sopenharmony_ci#endif 344bf215546Sopenharmony_ci 345bf215546Sopenharmony_ci pandecode_indent--; 346bf215546Sopenharmony_ci pandecode_log("\n"); 347bf215546Sopenharmony_ci 348bf215546Sopenharmony_ci gpu_va += pan_size(FRAMEBUFFER); 349bf215546Sopenharmony_ci 350bf215546Sopenharmony_ci info.has_extra = params.has_zs_crc_extension; 351bf215546Sopenharmony_ci 352bf215546Sopenharmony_ci if (info.has_extra) { 353bf215546Sopenharmony_ci struct pandecode_mapped_memory *mem = 354bf215546Sopenharmony_ci pandecode_find_mapped_gpu_mem_containing(gpu_va); 355bf215546Sopenharmony_ci const struct mali_zs_crc_extension_packed *PANDECODE_PTR_VAR(zs_crc, mem, (mali_ptr)gpu_va); 356bf215546Sopenharmony_ci DUMP_CL(ZS_CRC_EXTENSION, zs_crc, "ZS CRC Extension:\n"); 357bf215546Sopenharmony_ci pandecode_log("\n"); 358bf215546Sopenharmony_ci 359bf215546Sopenharmony_ci gpu_va += pan_size(ZS_CRC_EXTENSION); 360bf215546Sopenharmony_ci } 361bf215546Sopenharmony_ci 362bf215546Sopenharmony_ci if (is_fragment) 363bf215546Sopenharmony_ci pandecode_render_target(gpu_va, job_no, gpu_id, ¶ms); 364bf215546Sopenharmony_ci 365bf215546Sopenharmony_ci return info; 366bf215546Sopenharmony_ci} 367bf215546Sopenharmony_ci#endif 368bf215546Sopenharmony_ci 369bf215546Sopenharmony_ci#if PAN_ARCH <= 7 370bf215546Sopenharmony_cistatic void 371bf215546Sopenharmony_cipandecode_attributes(const struct pandecode_mapped_memory *mem, 372bf215546Sopenharmony_ci mali_ptr addr, int job_no, char *suffix, 373bf215546Sopenharmony_ci int count, bool varying, enum mali_job_type job_type) 374bf215546Sopenharmony_ci{ 375bf215546Sopenharmony_ci char *prefix = varying ? "Varying" : "Attribute"; 376bf215546Sopenharmony_ci assert(addr); 377bf215546Sopenharmony_ci 378bf215546Sopenharmony_ci if (!count) { 379bf215546Sopenharmony_ci pandecode_msg("warn: No %s records\n", prefix); 380bf215546Sopenharmony_ci return; 381bf215546Sopenharmony_ci } 382bf215546Sopenharmony_ci 383bf215546Sopenharmony_ci MAP_ADDR(ATTRIBUTE_BUFFER, addr, cl); 384bf215546Sopenharmony_ci 385bf215546Sopenharmony_ci for (int i = 0; i < count; ++i) { 386bf215546Sopenharmony_ci pan_unpack(cl + i * pan_size(ATTRIBUTE_BUFFER), ATTRIBUTE_BUFFER, temp); 387bf215546Sopenharmony_ci DUMP_UNPACKED(ATTRIBUTE_BUFFER, temp, "%s:\n", prefix); 388bf215546Sopenharmony_ci 389bf215546Sopenharmony_ci switch (temp.type) { 390bf215546Sopenharmony_ci case MALI_ATTRIBUTE_TYPE_1D_NPOT_DIVISOR_WRITE_REDUCTION: 391bf215546Sopenharmony_ci case MALI_ATTRIBUTE_TYPE_1D_NPOT_DIVISOR: { 392bf215546Sopenharmony_ci pan_unpack(cl + (i + 1) * pan_size(ATTRIBUTE_BUFFER), 393bf215546Sopenharmony_ci ATTRIBUTE_BUFFER_CONTINUATION_NPOT, temp2); 394bf215546Sopenharmony_ci pan_print(pandecode_dump_stream, ATTRIBUTE_BUFFER_CONTINUATION_NPOT, 395bf215546Sopenharmony_ci temp2, (pandecode_indent + 1) * 2); 396bf215546Sopenharmony_ci i++; 397bf215546Sopenharmony_ci break; 398bf215546Sopenharmony_ci } 399bf215546Sopenharmony_ci case MALI_ATTRIBUTE_TYPE_3D_LINEAR: 400bf215546Sopenharmony_ci case MALI_ATTRIBUTE_TYPE_3D_INTERLEAVED: { 401bf215546Sopenharmony_ci pan_unpack(cl + (i + 1) * pan_size(ATTRIBUTE_BUFFER_CONTINUATION_3D), 402bf215546Sopenharmony_ci ATTRIBUTE_BUFFER_CONTINUATION_3D, temp2); 403bf215546Sopenharmony_ci pan_print(pandecode_dump_stream, ATTRIBUTE_BUFFER_CONTINUATION_3D, 404bf215546Sopenharmony_ci temp2, (pandecode_indent + 1) * 2); 405bf215546Sopenharmony_ci i++; 406bf215546Sopenharmony_ci break; 407bf215546Sopenharmony_ci } 408bf215546Sopenharmony_ci default: 409bf215546Sopenharmony_ci break; 410bf215546Sopenharmony_ci } 411bf215546Sopenharmony_ci } 412bf215546Sopenharmony_ci pandecode_log("\n"); 413bf215546Sopenharmony_ci} 414bf215546Sopenharmony_ci#endif 415bf215546Sopenharmony_ci 416bf215546Sopenharmony_ci#if PAN_ARCH >= 6 417bf215546Sopenharmony_ci/* Decodes a Bifrost blend constant. See the notes in bifrost_blend_rt */ 418bf215546Sopenharmony_ci 419bf215546Sopenharmony_cistatic mali_ptr 420bf215546Sopenharmony_cipandecode_bifrost_blend(void *descs, int job_no, int rt_no, mali_ptr frag_shader) 421bf215546Sopenharmony_ci{ 422bf215546Sopenharmony_ci pan_unpack(descs + (rt_no * pan_size(BLEND)), BLEND, b); 423bf215546Sopenharmony_ci DUMP_UNPACKED(BLEND, b, "Blend RT %d:\n", rt_no); 424bf215546Sopenharmony_ci if (b.internal.mode != MALI_BLEND_MODE_SHADER) 425bf215546Sopenharmony_ci return 0; 426bf215546Sopenharmony_ci 427bf215546Sopenharmony_ci return (frag_shader & 0xFFFFFFFF00000000ULL) | b.internal.shader.pc; 428bf215546Sopenharmony_ci} 429bf215546Sopenharmony_ci#elif PAN_ARCH == 5 430bf215546Sopenharmony_cistatic mali_ptr 431bf215546Sopenharmony_cipandecode_midgard_blend_mrt(void *descs, int job_no, int rt_no) 432bf215546Sopenharmony_ci{ 433bf215546Sopenharmony_ci pan_unpack(descs + (rt_no * pan_size(BLEND)), BLEND, b); 434bf215546Sopenharmony_ci DUMP_UNPACKED(BLEND, b, "Blend RT %d:\n", rt_no); 435bf215546Sopenharmony_ci return b.blend_shader ? (b.shader_pc & ~0xf) : 0; 436bf215546Sopenharmony_ci} 437bf215546Sopenharmony_ci#endif 438bf215546Sopenharmony_ci 439bf215546Sopenharmony_ci#if PAN_ARCH <= 7 440bf215546Sopenharmony_cistatic unsigned 441bf215546Sopenharmony_cipandecode_attribute_meta(int count, mali_ptr attribute, bool varying) 442bf215546Sopenharmony_ci{ 443bf215546Sopenharmony_ci unsigned max = 0; 444bf215546Sopenharmony_ci 445bf215546Sopenharmony_ci for (int i = 0; i < count; ++i, attribute += pan_size(ATTRIBUTE)) { 446bf215546Sopenharmony_ci MAP_ADDR(ATTRIBUTE, attribute, cl); 447bf215546Sopenharmony_ci pan_unpack(cl, ATTRIBUTE, a); 448bf215546Sopenharmony_ci DUMP_UNPACKED(ATTRIBUTE, a, "%s:\n", varying ? "Varying" : "Attribute"); 449bf215546Sopenharmony_ci max = MAX2(max, a.buffer_index); 450bf215546Sopenharmony_ci } 451bf215546Sopenharmony_ci 452bf215546Sopenharmony_ci pandecode_log("\n"); 453bf215546Sopenharmony_ci return MIN2(max + 1, 256); 454bf215546Sopenharmony_ci} 455bf215546Sopenharmony_ci 456bf215546Sopenharmony_ci/* return bits [lo, hi) of word */ 457bf215546Sopenharmony_cistatic u32 458bf215546Sopenharmony_cibits(u32 word, u32 lo, u32 hi) 459bf215546Sopenharmony_ci{ 460bf215546Sopenharmony_ci if (hi - lo >= 32) 461bf215546Sopenharmony_ci return word; // avoid undefined behavior with the shift 462bf215546Sopenharmony_ci 463bf215546Sopenharmony_ci if (lo >= 32) 464bf215546Sopenharmony_ci return 0; 465bf215546Sopenharmony_ci 466bf215546Sopenharmony_ci return (word >> lo) & ((1 << (hi - lo)) - 1); 467bf215546Sopenharmony_ci} 468bf215546Sopenharmony_ci 469bf215546Sopenharmony_cistatic void 470bf215546Sopenharmony_cipandecode_invocation(const void *i) 471bf215546Sopenharmony_ci{ 472bf215546Sopenharmony_ci /* Decode invocation_count. See the comment before the definition of 473bf215546Sopenharmony_ci * invocation_count for an explanation. 474bf215546Sopenharmony_ci */ 475bf215546Sopenharmony_ci pan_unpack(i, INVOCATION, invocation); 476bf215546Sopenharmony_ci 477bf215546Sopenharmony_ci unsigned size_x = bits(invocation.invocations, 0, invocation.size_y_shift) + 1; 478bf215546Sopenharmony_ci unsigned size_y = bits(invocation.invocations, invocation.size_y_shift, invocation.size_z_shift) + 1; 479bf215546Sopenharmony_ci unsigned size_z = bits(invocation.invocations, invocation.size_z_shift, invocation.workgroups_x_shift) + 1; 480bf215546Sopenharmony_ci 481bf215546Sopenharmony_ci unsigned groups_x = bits(invocation.invocations, invocation.workgroups_x_shift, invocation.workgroups_y_shift) + 1; 482bf215546Sopenharmony_ci unsigned groups_y = bits(invocation.invocations, invocation.workgroups_y_shift, invocation.workgroups_z_shift) + 1; 483bf215546Sopenharmony_ci unsigned groups_z = bits(invocation.invocations, invocation.workgroups_z_shift, 32) + 1; 484bf215546Sopenharmony_ci 485bf215546Sopenharmony_ci pandecode_log("Invocation (%d, %d, %d) x (%d, %d, %d)\n", 486bf215546Sopenharmony_ci size_x, size_y, size_z, 487bf215546Sopenharmony_ci groups_x, groups_y, groups_z); 488bf215546Sopenharmony_ci 489bf215546Sopenharmony_ci DUMP_UNPACKED(INVOCATION, invocation, "Invocation:\n") 490bf215546Sopenharmony_ci} 491bf215546Sopenharmony_ci#endif 492bf215546Sopenharmony_ci 493bf215546Sopenharmony_cistatic void 494bf215546Sopenharmony_cipandecode_primitive(const void *p) 495bf215546Sopenharmony_ci{ 496bf215546Sopenharmony_ci pan_unpack(p, PRIMITIVE, primitive); 497bf215546Sopenharmony_ci DUMP_UNPACKED(PRIMITIVE, primitive, "Primitive:\n"); 498bf215546Sopenharmony_ci 499bf215546Sopenharmony_ci#if PAN_ARCH <= 7 500bf215546Sopenharmony_ci /* Validate an index buffer is present if we need one. TODO: verify 501bf215546Sopenharmony_ci * relationship between invocation_count and index_count */ 502bf215546Sopenharmony_ci 503bf215546Sopenharmony_ci if (primitive.indices) { 504bf215546Sopenharmony_ci /* Grab the size */ 505bf215546Sopenharmony_ci unsigned size = (primitive.index_type == MALI_INDEX_TYPE_UINT32) ? 506bf215546Sopenharmony_ci sizeof(uint32_t) : primitive.index_type; 507bf215546Sopenharmony_ci 508bf215546Sopenharmony_ci /* Ensure we got a size, and if so, validate the index buffer 509bf215546Sopenharmony_ci * is large enough to hold a full set of indices of the given 510bf215546Sopenharmony_ci * size */ 511bf215546Sopenharmony_ci 512bf215546Sopenharmony_ci if (!size) 513bf215546Sopenharmony_ci pandecode_msg("XXX: index size missing\n"); 514bf215546Sopenharmony_ci else 515bf215546Sopenharmony_ci pandecode_validate_buffer(primitive.indices, primitive.index_count * size); 516bf215546Sopenharmony_ci } else if (primitive.index_type) 517bf215546Sopenharmony_ci pandecode_msg("XXX: unexpected index size\n"); 518bf215546Sopenharmony_ci#endif 519bf215546Sopenharmony_ci} 520bf215546Sopenharmony_ci 521bf215546Sopenharmony_cistatic void 522bf215546Sopenharmony_cipandecode_primitive_size(const void *s, bool constant) 523bf215546Sopenharmony_ci{ 524bf215546Sopenharmony_ci pan_unpack(s, PRIMITIVE_SIZE, ps); 525bf215546Sopenharmony_ci if (ps.size_array == 0x0) 526bf215546Sopenharmony_ci return; 527bf215546Sopenharmony_ci 528bf215546Sopenharmony_ci DUMP_UNPACKED(PRIMITIVE_SIZE, ps, "Primitive Size:\n") 529bf215546Sopenharmony_ci} 530bf215546Sopenharmony_ci 531bf215546Sopenharmony_ci#if PAN_ARCH <= 7 532bf215546Sopenharmony_cistatic void 533bf215546Sopenharmony_cipandecode_uniform_buffers(mali_ptr pubufs, int ubufs_count, int job_no) 534bf215546Sopenharmony_ci{ 535bf215546Sopenharmony_ci struct pandecode_mapped_memory *umem = pandecode_find_mapped_gpu_mem_containing(pubufs); 536bf215546Sopenharmony_ci uint64_t *PANDECODE_PTR_VAR(ubufs, umem, pubufs); 537bf215546Sopenharmony_ci 538bf215546Sopenharmony_ci for (int i = 0; i < ubufs_count; i++) { 539bf215546Sopenharmony_ci mali_ptr addr = (ubufs[i] >> 10) << 2; 540bf215546Sopenharmony_ci unsigned size = addr ? (((ubufs[i] & ((1 << 10) - 1)) + 1) * 16) : 0; 541bf215546Sopenharmony_ci 542bf215546Sopenharmony_ci pandecode_validate_buffer(addr, size); 543bf215546Sopenharmony_ci 544bf215546Sopenharmony_ci char *ptr = pointer_as_memory_reference(addr); 545bf215546Sopenharmony_ci pandecode_log("ubuf_%d[%u] = %s;\n", i, size, ptr); 546bf215546Sopenharmony_ci free(ptr); 547bf215546Sopenharmony_ci } 548bf215546Sopenharmony_ci 549bf215546Sopenharmony_ci pandecode_log("\n"); 550bf215546Sopenharmony_ci} 551bf215546Sopenharmony_ci 552bf215546Sopenharmony_cistatic void 553bf215546Sopenharmony_cipandecode_uniforms(mali_ptr uniforms, unsigned uniform_count) 554bf215546Sopenharmony_ci{ 555bf215546Sopenharmony_ci pandecode_validate_buffer(uniforms, uniform_count * 16); 556bf215546Sopenharmony_ci 557bf215546Sopenharmony_ci char *ptr = pointer_as_memory_reference(uniforms); 558bf215546Sopenharmony_ci pandecode_log("vec4 uniforms[%u] = %s;\n", uniform_count, ptr); 559bf215546Sopenharmony_ci free(ptr); 560bf215546Sopenharmony_ci pandecode_log("\n"); 561bf215546Sopenharmony_ci} 562bf215546Sopenharmony_ci#endif 563bf215546Sopenharmony_ci 564bf215546Sopenharmony_cistatic const char * 565bf215546Sopenharmony_cishader_type_for_job(unsigned type) 566bf215546Sopenharmony_ci{ 567bf215546Sopenharmony_ci switch (type) { 568bf215546Sopenharmony_ci#if PAN_ARCH <= 7 569bf215546Sopenharmony_ci case MALI_JOB_TYPE_VERTEX: return "VERTEX"; 570bf215546Sopenharmony_ci#endif 571bf215546Sopenharmony_ci case MALI_JOB_TYPE_TILER: return "FRAGMENT"; 572bf215546Sopenharmony_ci case MALI_JOB_TYPE_FRAGMENT: return "FRAGMENT"; 573bf215546Sopenharmony_ci case MALI_JOB_TYPE_COMPUTE: return "COMPUTE"; 574bf215546Sopenharmony_ci default: return "UNKNOWN"; 575bf215546Sopenharmony_ci } 576bf215546Sopenharmony_ci} 577bf215546Sopenharmony_ci 578bf215546Sopenharmony_cistatic unsigned shader_id = 0; 579bf215546Sopenharmony_ci 580bf215546Sopenharmony_cistatic struct midgard_disasm_stats 581bf215546Sopenharmony_cipandecode_shader_disassemble(mali_ptr shader_ptr, int shader_no, int type, 582bf215546Sopenharmony_ci unsigned gpu_id) 583bf215546Sopenharmony_ci{ 584bf215546Sopenharmony_ci struct pandecode_mapped_memory *mem = pandecode_find_mapped_gpu_mem_containing(shader_ptr); 585bf215546Sopenharmony_ci uint8_t *PANDECODE_PTR_VAR(code, mem, shader_ptr); 586bf215546Sopenharmony_ci 587bf215546Sopenharmony_ci /* Compute maximum possible size */ 588bf215546Sopenharmony_ci size_t sz = mem->length - (shader_ptr - mem->gpu_va); 589bf215546Sopenharmony_ci 590bf215546Sopenharmony_ci /* Print some boilerplate to clearly denote the assembly (which doesn't 591bf215546Sopenharmony_ci * obey indentation rules), and actually do the disassembly! */ 592bf215546Sopenharmony_ci 593bf215546Sopenharmony_ci pandecode_log_cont("\n\n"); 594bf215546Sopenharmony_ci 595bf215546Sopenharmony_ci struct midgard_disasm_stats stats = { 0 }; 596bf215546Sopenharmony_ci 597bf215546Sopenharmony_ci#if PAN_ARCH >= 9 598bf215546Sopenharmony_ci disassemble_valhall(pandecode_dump_stream, (const uint64_t *) code, sz, true); 599bf215546Sopenharmony_ci#elif PAN_ARCH >= 6 && PAN_ARCH <= 7 600bf215546Sopenharmony_ci disassemble_bifrost(pandecode_dump_stream, code, sz, false); 601bf215546Sopenharmony_ci#else 602bf215546Sopenharmony_ci stats = disassemble_midgard(pandecode_dump_stream, 603bf215546Sopenharmony_ci code, sz, gpu_id, true); 604bf215546Sopenharmony_ci#endif 605bf215546Sopenharmony_ci 606bf215546Sopenharmony_ci unsigned nr_threads = 607bf215546Sopenharmony_ci (stats.work_count <= 4) ? 4 : 608bf215546Sopenharmony_ci (stats.work_count <= 8) ? 2 : 609bf215546Sopenharmony_ci 1; 610bf215546Sopenharmony_ci 611bf215546Sopenharmony_ci pandecode_log_cont("shader%d - MESA_SHADER_%s shader: " 612bf215546Sopenharmony_ci "%u inst, %u bundles, %u quadwords, " 613bf215546Sopenharmony_ci "%u registers, %u threads, 0 loops, 0:0 spills:fills\n\n\n", 614bf215546Sopenharmony_ci shader_id++, 615bf215546Sopenharmony_ci shader_type_for_job(type), 616bf215546Sopenharmony_ci stats.instruction_count, stats.bundle_count, stats.quadword_count, 617bf215546Sopenharmony_ci stats.work_count, nr_threads); 618bf215546Sopenharmony_ci 619bf215546Sopenharmony_ci return stats; 620bf215546Sopenharmony_ci} 621bf215546Sopenharmony_ci 622bf215546Sopenharmony_ci#if PAN_ARCH <= 7 623bf215546Sopenharmony_cistatic void 624bf215546Sopenharmony_cipandecode_texture_payload(mali_ptr payload, 625bf215546Sopenharmony_ci enum mali_texture_dimension dim, 626bf215546Sopenharmony_ci enum mali_texture_layout layout, 627bf215546Sopenharmony_ci bool manual_stride, 628bf215546Sopenharmony_ci uint8_t levels, 629bf215546Sopenharmony_ci uint16_t nr_samples, 630bf215546Sopenharmony_ci uint16_t array_size, 631bf215546Sopenharmony_ci struct pandecode_mapped_memory *tmem) 632bf215546Sopenharmony_ci{ 633bf215546Sopenharmony_ci pandecode_log(".payload = {\n"); 634bf215546Sopenharmony_ci pandecode_indent++; 635bf215546Sopenharmony_ci 636bf215546Sopenharmony_ci /* A bunch of bitmap pointers follow. 637bf215546Sopenharmony_ci * We work out the correct number, 638bf215546Sopenharmony_ci * based on the mipmap/cubemap 639bf215546Sopenharmony_ci * properties, but dump extra 640bf215546Sopenharmony_ci * possibilities to futureproof */ 641bf215546Sopenharmony_ci 642bf215546Sopenharmony_ci int bitmap_count = levels; 643bf215546Sopenharmony_ci 644bf215546Sopenharmony_ci /* Miptree for each face */ 645bf215546Sopenharmony_ci if (dim == MALI_TEXTURE_DIMENSION_CUBE) 646bf215546Sopenharmony_ci bitmap_count *= 6; 647bf215546Sopenharmony_ci 648bf215546Sopenharmony_ci /* Array of layers */ 649bf215546Sopenharmony_ci bitmap_count *= nr_samples; 650bf215546Sopenharmony_ci 651bf215546Sopenharmony_ci /* Array of textures */ 652bf215546Sopenharmony_ci bitmap_count *= array_size; 653bf215546Sopenharmony_ci 654bf215546Sopenharmony_ci /* Stride for each element */ 655bf215546Sopenharmony_ci if (manual_stride) 656bf215546Sopenharmony_ci bitmap_count *= 2; 657bf215546Sopenharmony_ci 658bf215546Sopenharmony_ci mali_ptr *pointers_and_strides = pandecode_fetch_gpu_mem(tmem, 659bf215546Sopenharmony_ci payload, sizeof(mali_ptr) * bitmap_count); 660bf215546Sopenharmony_ci for (int i = 0; i < bitmap_count; ++i) { 661bf215546Sopenharmony_ci /* How we dump depends if this is a stride or a pointer */ 662bf215546Sopenharmony_ci 663bf215546Sopenharmony_ci if (manual_stride && (i & 1)) { 664bf215546Sopenharmony_ci /* signed 32-bit snuck in as a 64-bit pointer */ 665bf215546Sopenharmony_ci uint64_t stride_set = pointers_and_strides[i]; 666bf215546Sopenharmony_ci int32_t row_stride = stride_set; 667bf215546Sopenharmony_ci int32_t surface_stride = stride_set >> 32; 668bf215546Sopenharmony_ci pandecode_log("(mali_ptr) %d /* surface stride */ %d /* row stride */, \n", 669bf215546Sopenharmony_ci surface_stride, row_stride); 670bf215546Sopenharmony_ci } else { 671bf215546Sopenharmony_ci char *a = pointer_as_memory_reference(pointers_and_strides[i]); 672bf215546Sopenharmony_ci pandecode_log("%s, \n", a); 673bf215546Sopenharmony_ci free(a); 674bf215546Sopenharmony_ci } 675bf215546Sopenharmony_ci } 676bf215546Sopenharmony_ci 677bf215546Sopenharmony_ci pandecode_indent--; 678bf215546Sopenharmony_ci pandecode_log("},\n"); 679bf215546Sopenharmony_ci} 680bf215546Sopenharmony_ci#endif 681bf215546Sopenharmony_ci 682bf215546Sopenharmony_ci#if PAN_ARCH <= 5 683bf215546Sopenharmony_cistatic void 684bf215546Sopenharmony_cipandecode_texture(mali_ptr u, 685bf215546Sopenharmony_ci struct pandecode_mapped_memory *tmem, 686bf215546Sopenharmony_ci unsigned job_no, unsigned tex) 687bf215546Sopenharmony_ci{ 688bf215546Sopenharmony_ci struct pandecode_mapped_memory *mapped_mem = pandecode_find_mapped_gpu_mem_containing(u); 689bf215546Sopenharmony_ci const uint8_t *cl = pandecode_fetch_gpu_mem(mapped_mem, u, pan_size(TEXTURE)); 690bf215546Sopenharmony_ci 691bf215546Sopenharmony_ci pan_unpack(cl, TEXTURE, temp); 692bf215546Sopenharmony_ci DUMP_UNPACKED(TEXTURE, temp, "Texture:\n") 693bf215546Sopenharmony_ci 694bf215546Sopenharmony_ci pandecode_indent++; 695bf215546Sopenharmony_ci unsigned nr_samples = temp.dimension == MALI_TEXTURE_DIMENSION_3D ? 696bf215546Sopenharmony_ci 1 : temp.sample_count; 697bf215546Sopenharmony_ci pandecode_texture_payload(u + pan_size(TEXTURE), 698bf215546Sopenharmony_ci temp.dimension, temp.texel_ordering, temp.manual_stride, 699bf215546Sopenharmony_ci temp.levels, nr_samples, temp.array_size, mapped_mem); 700bf215546Sopenharmony_ci pandecode_indent--; 701bf215546Sopenharmony_ci} 702bf215546Sopenharmony_ci#else 703bf215546Sopenharmony_cistatic void 704bf215546Sopenharmony_cipandecode_bifrost_texture( 705bf215546Sopenharmony_ci const void *cl, 706bf215546Sopenharmony_ci unsigned job_no, 707bf215546Sopenharmony_ci unsigned tex) 708bf215546Sopenharmony_ci{ 709bf215546Sopenharmony_ci pan_unpack(cl, TEXTURE, temp); 710bf215546Sopenharmony_ci DUMP_UNPACKED(TEXTURE, temp, "Texture:\n") 711bf215546Sopenharmony_ci 712bf215546Sopenharmony_ci pandecode_indent++; 713bf215546Sopenharmony_ci 714bf215546Sopenharmony_ci#if PAN_ARCH >= 9 715bf215546Sopenharmony_ci int plane_count = temp.levels * temp.array_size; 716bf215546Sopenharmony_ci 717bf215546Sopenharmony_ci /* Miptree for each face */ 718bf215546Sopenharmony_ci if (temp.dimension == MALI_TEXTURE_DIMENSION_CUBE) 719bf215546Sopenharmony_ci plane_count *= 6; 720bf215546Sopenharmony_ci 721bf215546Sopenharmony_ci for (unsigned i = 0; i < plane_count; ++i) 722bf215546Sopenharmony_ci DUMP_ADDR(PLANE, temp.surfaces + i * pan_size(PLANE), "Plane %u:\n", i); 723bf215546Sopenharmony_ci#else 724bf215546Sopenharmony_ci struct pandecode_mapped_memory *tmem = pandecode_find_mapped_gpu_mem_containing(temp.surfaces); 725bf215546Sopenharmony_ci unsigned nr_samples = temp.dimension == MALI_TEXTURE_DIMENSION_3D ? 726bf215546Sopenharmony_ci 1 : temp.sample_count; 727bf215546Sopenharmony_ci 728bf215546Sopenharmony_ci pandecode_texture_payload(temp.surfaces, temp.dimension, temp.texel_ordering, 729bf215546Sopenharmony_ci true, temp.levels, nr_samples, temp.array_size, tmem); 730bf215546Sopenharmony_ci#endif 731bf215546Sopenharmony_ci pandecode_indent--; 732bf215546Sopenharmony_ci} 733bf215546Sopenharmony_ci#endif 734bf215546Sopenharmony_ci 735bf215546Sopenharmony_ci#if PAN_ARCH <= 7 736bf215546Sopenharmony_cistatic void 737bf215546Sopenharmony_cipandecode_blend_shader_disassemble(mali_ptr shader, int job_no, int job_type, 738bf215546Sopenharmony_ci unsigned gpu_id) 739bf215546Sopenharmony_ci{ 740bf215546Sopenharmony_ci struct midgard_disasm_stats stats = 741bf215546Sopenharmony_ci pandecode_shader_disassemble(shader, job_no, job_type, gpu_id); 742bf215546Sopenharmony_ci 743bf215546Sopenharmony_ci bool has_texture = (stats.texture_count > 0); 744bf215546Sopenharmony_ci bool has_sampler = (stats.sampler_count > 0); 745bf215546Sopenharmony_ci bool has_attribute = (stats.attribute_count > 0); 746bf215546Sopenharmony_ci bool has_varying = (stats.varying_count > 0); 747bf215546Sopenharmony_ci bool has_uniform = (stats.uniform_count > 0); 748bf215546Sopenharmony_ci bool has_ubo = (stats.uniform_buffer_count > 0); 749bf215546Sopenharmony_ci 750bf215546Sopenharmony_ci if (has_texture || has_sampler) 751bf215546Sopenharmony_ci pandecode_msg("XXX: blend shader accessing textures\n"); 752bf215546Sopenharmony_ci 753bf215546Sopenharmony_ci if (has_attribute || has_varying) 754bf215546Sopenharmony_ci pandecode_msg("XXX: blend shader accessing interstage\n"); 755bf215546Sopenharmony_ci 756bf215546Sopenharmony_ci if (has_uniform || has_ubo) 757bf215546Sopenharmony_ci pandecode_msg("XXX: blend shader accessing uniforms\n"); 758bf215546Sopenharmony_ci} 759bf215546Sopenharmony_ci 760bf215546Sopenharmony_cistatic void 761bf215546Sopenharmony_cipandecode_textures(mali_ptr textures, unsigned texture_count, int job_no) 762bf215546Sopenharmony_ci{ 763bf215546Sopenharmony_ci struct pandecode_mapped_memory *mmem = pandecode_find_mapped_gpu_mem_containing(textures); 764bf215546Sopenharmony_ci 765bf215546Sopenharmony_ci if (!mmem) 766bf215546Sopenharmony_ci return; 767bf215546Sopenharmony_ci 768bf215546Sopenharmony_ci pandecode_log("Textures %"PRIx64"_%d:\n", textures, job_no); 769bf215546Sopenharmony_ci pandecode_indent++; 770bf215546Sopenharmony_ci 771bf215546Sopenharmony_ci#if PAN_ARCH >= 6 772bf215546Sopenharmony_ci const void *cl = 773bf215546Sopenharmony_ci pandecode_fetch_gpu_mem(mmem, 774bf215546Sopenharmony_ci textures, 775bf215546Sopenharmony_ci pan_size(TEXTURE) * 776bf215546Sopenharmony_ci texture_count); 777bf215546Sopenharmony_ci 778bf215546Sopenharmony_ci for (unsigned tex = 0; tex < texture_count; ++tex) { 779bf215546Sopenharmony_ci pandecode_bifrost_texture(cl + pan_size(TEXTURE) * tex, 780bf215546Sopenharmony_ci job_no, tex); 781bf215546Sopenharmony_ci } 782bf215546Sopenharmony_ci#else 783bf215546Sopenharmony_ci mali_ptr *PANDECODE_PTR_VAR(u, mmem, textures); 784bf215546Sopenharmony_ci 785bf215546Sopenharmony_ci for (int tex = 0; tex < texture_count; ++tex) { 786bf215546Sopenharmony_ci mali_ptr *PANDECODE_PTR_VAR(u, mmem, textures + tex * sizeof(mali_ptr)); 787bf215546Sopenharmony_ci char *a = pointer_as_memory_reference(*u); 788bf215546Sopenharmony_ci pandecode_log("%s,\n", a); 789bf215546Sopenharmony_ci free(a); 790bf215546Sopenharmony_ci } 791bf215546Sopenharmony_ci 792bf215546Sopenharmony_ci /* Now, finally, descend down into the texture descriptor */ 793bf215546Sopenharmony_ci for (unsigned tex = 0; tex < texture_count; ++tex) { 794bf215546Sopenharmony_ci mali_ptr *PANDECODE_PTR_VAR(u, mmem, textures + tex * sizeof(mali_ptr)); 795bf215546Sopenharmony_ci struct pandecode_mapped_memory *tmem = pandecode_find_mapped_gpu_mem_containing(*u); 796bf215546Sopenharmony_ci if (tmem) 797bf215546Sopenharmony_ci pandecode_texture(*u, tmem, job_no, tex); 798bf215546Sopenharmony_ci } 799bf215546Sopenharmony_ci#endif 800bf215546Sopenharmony_ci pandecode_indent--; 801bf215546Sopenharmony_ci pandecode_log("\n"); 802bf215546Sopenharmony_ci} 803bf215546Sopenharmony_ci 804bf215546Sopenharmony_cistatic void 805bf215546Sopenharmony_cipandecode_samplers(mali_ptr samplers, unsigned sampler_count, int job_no) 806bf215546Sopenharmony_ci{ 807bf215546Sopenharmony_ci pandecode_log("Samplers %"PRIx64"_%d:\n", samplers, job_no); 808bf215546Sopenharmony_ci pandecode_indent++; 809bf215546Sopenharmony_ci 810bf215546Sopenharmony_ci for (int i = 0; i < sampler_count; ++i) 811bf215546Sopenharmony_ci DUMP_ADDR(SAMPLER, samplers + (pan_size(SAMPLER) * i), "Sampler %d:\n", i); 812bf215546Sopenharmony_ci 813bf215546Sopenharmony_ci pandecode_indent--; 814bf215546Sopenharmony_ci pandecode_log("\n"); 815bf215546Sopenharmony_ci} 816bf215546Sopenharmony_ci 817bf215546Sopenharmony_cistatic void 818bf215546Sopenharmony_cipandecode_dcd(const struct MALI_DRAW *p, 819bf215546Sopenharmony_ci int job_no, enum mali_job_type job_type, 820bf215546Sopenharmony_ci char *suffix, unsigned gpu_id) 821bf215546Sopenharmony_ci{ 822bf215546Sopenharmony_ci struct pandecode_mapped_memory *attr_mem; 823bf215546Sopenharmony_ci 824bf215546Sopenharmony_ci#if PAN_ARCH >= 5 825bf215546Sopenharmony_ci struct pandecode_fbd fbd_info = { 826bf215546Sopenharmony_ci /* Default for Bifrost */ 827bf215546Sopenharmony_ci .rt_count = 1 828bf215546Sopenharmony_ci }; 829bf215546Sopenharmony_ci#endif 830bf215546Sopenharmony_ci 831bf215546Sopenharmony_ci#if PAN_ARCH >= 6 832bf215546Sopenharmony_ci pandecode_local_storage(p->thread_storage & ~1, job_no); 833bf215546Sopenharmony_ci#elif PAN_ARCH == 5 834bf215546Sopenharmony_ci if (job_type != MALI_JOB_TYPE_TILER) { 835bf215546Sopenharmony_ci pandecode_local_storage(p->thread_storage & ~1, job_no); 836bf215546Sopenharmony_ci } else { 837bf215546Sopenharmony_ci assert(p->fbd & MALI_FBD_TAG_IS_MFBD); 838bf215546Sopenharmony_ci fbd_info = pandecode_mfbd_bfr((u64) ((uintptr_t) p->fbd) & ~MALI_FBD_TAG_MASK, 839bf215546Sopenharmony_ci job_no, false, gpu_id); 840bf215546Sopenharmony_ci } 841bf215546Sopenharmony_ci#else 842bf215546Sopenharmony_ci pandecode_sfbd((u64) (uintptr_t) p->fbd, job_no, false, gpu_id); 843bf215546Sopenharmony_ci#endif 844bf215546Sopenharmony_ci 845bf215546Sopenharmony_ci int varying_count = 0, attribute_count = 0, uniform_count = 0, uniform_buffer_count = 0; 846bf215546Sopenharmony_ci int texture_count = 0, sampler_count = 0; 847bf215546Sopenharmony_ci 848bf215546Sopenharmony_ci if (p->state) { 849bf215546Sopenharmony_ci struct pandecode_mapped_memory *smem = pandecode_find_mapped_gpu_mem_containing(p->state); 850bf215546Sopenharmony_ci uint32_t *cl = pandecode_fetch_gpu_mem(smem, p->state, pan_size(RENDERER_STATE)); 851bf215546Sopenharmony_ci 852bf215546Sopenharmony_ci pan_unpack(cl, RENDERER_STATE, state); 853bf215546Sopenharmony_ci 854bf215546Sopenharmony_ci if (state.shader.shader & ~0xF) 855bf215546Sopenharmony_ci pandecode_shader_disassemble(state.shader.shader & ~0xF, job_no, job_type, gpu_id); 856bf215546Sopenharmony_ci 857bf215546Sopenharmony_ci#if PAN_ARCH >= 6 858bf215546Sopenharmony_ci bool idvs = (job_type == MALI_JOB_TYPE_INDEXED_VERTEX); 859bf215546Sopenharmony_ci 860bf215546Sopenharmony_ci if (idvs && state.secondary_shader) 861bf215546Sopenharmony_ci pandecode_shader_disassemble(state.secondary_shader, job_no, job_type, gpu_id); 862bf215546Sopenharmony_ci#endif 863bf215546Sopenharmony_ci DUMP_UNPACKED(RENDERER_STATE, state, "State:\n"); 864bf215546Sopenharmony_ci pandecode_indent++; 865bf215546Sopenharmony_ci 866bf215546Sopenharmony_ci /* Save for dumps */ 867bf215546Sopenharmony_ci attribute_count = state.shader.attribute_count; 868bf215546Sopenharmony_ci varying_count = state.shader.varying_count; 869bf215546Sopenharmony_ci texture_count = state.shader.texture_count; 870bf215546Sopenharmony_ci sampler_count = state.shader.sampler_count; 871bf215546Sopenharmony_ci uniform_buffer_count = state.properties.uniform_buffer_count; 872bf215546Sopenharmony_ci 873bf215546Sopenharmony_ci#if PAN_ARCH >= 6 874bf215546Sopenharmony_ci uniform_count = state.preload.uniform_count; 875bf215546Sopenharmony_ci#else 876bf215546Sopenharmony_ci uniform_count = state.properties.uniform_count; 877bf215546Sopenharmony_ci#endif 878bf215546Sopenharmony_ci 879bf215546Sopenharmony_ci#if PAN_ARCH == 4 880bf215546Sopenharmony_ci mali_ptr shader = state.blend_shader & ~0xF; 881bf215546Sopenharmony_ci if (state.multisample_misc.blend_shader && shader) 882bf215546Sopenharmony_ci pandecode_blend_shader_disassemble(shader, job_no, job_type, gpu_id); 883bf215546Sopenharmony_ci#endif 884bf215546Sopenharmony_ci pandecode_indent--; 885bf215546Sopenharmony_ci pandecode_log("\n"); 886bf215546Sopenharmony_ci 887bf215546Sopenharmony_ci /* MRT blend fields are used whenever MFBD is used, with 888bf215546Sopenharmony_ci * per-RT descriptors */ 889bf215546Sopenharmony_ci 890bf215546Sopenharmony_ci#if PAN_ARCH >= 5 891bf215546Sopenharmony_ci if ((job_type == MALI_JOB_TYPE_TILER || job_type == MALI_JOB_TYPE_FRAGMENT) && 892bf215546Sopenharmony_ci (PAN_ARCH >= 6 || p->thread_storage & MALI_FBD_TAG_IS_MFBD)) { 893bf215546Sopenharmony_ci void* blend_base = ((void *) cl) + pan_size(RENDERER_STATE); 894bf215546Sopenharmony_ci 895bf215546Sopenharmony_ci for (unsigned i = 0; i < fbd_info.rt_count; i++) { 896bf215546Sopenharmony_ci mali_ptr shader = 0; 897bf215546Sopenharmony_ci 898bf215546Sopenharmony_ci#if PAN_ARCH >= 6 899bf215546Sopenharmony_ci shader = pandecode_bifrost_blend(blend_base, job_no, i, 900bf215546Sopenharmony_ci state.shader.shader); 901bf215546Sopenharmony_ci#else 902bf215546Sopenharmony_ci shader = pandecode_midgard_blend_mrt(blend_base, job_no, i); 903bf215546Sopenharmony_ci#endif 904bf215546Sopenharmony_ci if (shader & ~0xF) 905bf215546Sopenharmony_ci pandecode_blend_shader_disassemble(shader, job_no, job_type, 906bf215546Sopenharmony_ci gpu_id); 907bf215546Sopenharmony_ci } 908bf215546Sopenharmony_ci } 909bf215546Sopenharmony_ci#endif 910bf215546Sopenharmony_ci } else 911bf215546Sopenharmony_ci pandecode_msg("XXX: missing shader descriptor\n"); 912bf215546Sopenharmony_ci 913bf215546Sopenharmony_ci if (p->viewport) { 914bf215546Sopenharmony_ci DUMP_ADDR(VIEWPORT, p->viewport, "Viewport:\n"); 915bf215546Sopenharmony_ci pandecode_log("\n"); 916bf215546Sopenharmony_ci } 917bf215546Sopenharmony_ci 918bf215546Sopenharmony_ci unsigned max_attr_index = 0; 919bf215546Sopenharmony_ci 920bf215546Sopenharmony_ci if (p->attributes) 921bf215546Sopenharmony_ci max_attr_index = pandecode_attribute_meta(attribute_count, p->attributes, false); 922bf215546Sopenharmony_ci 923bf215546Sopenharmony_ci if (p->attribute_buffers) { 924bf215546Sopenharmony_ci attr_mem = pandecode_find_mapped_gpu_mem_containing(p->attribute_buffers); 925bf215546Sopenharmony_ci pandecode_attributes(attr_mem, p->attribute_buffers, job_no, suffix, max_attr_index, false, job_type); 926bf215546Sopenharmony_ci } 927bf215546Sopenharmony_ci 928bf215546Sopenharmony_ci if (p->varyings) { 929bf215546Sopenharmony_ci varying_count = pandecode_attribute_meta(varying_count, p->varyings, true); 930bf215546Sopenharmony_ci } 931bf215546Sopenharmony_ci 932bf215546Sopenharmony_ci if (p->varying_buffers) { 933bf215546Sopenharmony_ci attr_mem = pandecode_find_mapped_gpu_mem_containing(p->varying_buffers); 934bf215546Sopenharmony_ci pandecode_attributes(attr_mem, p->varying_buffers, job_no, suffix, varying_count, true, job_type); 935bf215546Sopenharmony_ci } 936bf215546Sopenharmony_ci 937bf215546Sopenharmony_ci if (p->uniform_buffers) { 938bf215546Sopenharmony_ci if (uniform_buffer_count) 939bf215546Sopenharmony_ci pandecode_uniform_buffers(p->uniform_buffers, uniform_buffer_count, job_no); 940bf215546Sopenharmony_ci else 941bf215546Sopenharmony_ci pandecode_msg("warn: UBOs specified but not referenced\n"); 942bf215546Sopenharmony_ci } else if (uniform_buffer_count) 943bf215546Sopenharmony_ci pandecode_msg("XXX: UBOs referenced but not specified\n"); 944bf215546Sopenharmony_ci 945bf215546Sopenharmony_ci /* We don't want to actually dump uniforms, but we do need to validate 946bf215546Sopenharmony_ci * that the counts we were given are sane */ 947bf215546Sopenharmony_ci 948bf215546Sopenharmony_ci if (p->push_uniforms) { 949bf215546Sopenharmony_ci if (uniform_count) 950bf215546Sopenharmony_ci pandecode_uniforms(p->push_uniforms, uniform_count); 951bf215546Sopenharmony_ci else 952bf215546Sopenharmony_ci pandecode_msg("warn: Uniforms specified but not referenced\n"); 953bf215546Sopenharmony_ci } else if (uniform_count) 954bf215546Sopenharmony_ci pandecode_msg("XXX: Uniforms referenced but not specified\n"); 955bf215546Sopenharmony_ci 956bf215546Sopenharmony_ci if (p->textures) 957bf215546Sopenharmony_ci pandecode_textures(p->textures, texture_count, job_no); 958bf215546Sopenharmony_ci 959bf215546Sopenharmony_ci if (p->samplers) 960bf215546Sopenharmony_ci pandecode_samplers(p->samplers, sampler_count, job_no); 961bf215546Sopenharmony_ci} 962bf215546Sopenharmony_ci 963bf215546Sopenharmony_cistatic void 964bf215546Sopenharmony_cipandecode_vertex_compute_geometry_job(const struct MALI_JOB_HEADER *h, 965bf215546Sopenharmony_ci const struct pandecode_mapped_memory *mem, 966bf215546Sopenharmony_ci mali_ptr job, int job_no, unsigned gpu_id) 967bf215546Sopenharmony_ci{ 968bf215546Sopenharmony_ci struct mali_compute_job_packed *PANDECODE_PTR_VAR(p, mem, job); 969bf215546Sopenharmony_ci pan_section_unpack(p, COMPUTE_JOB, DRAW, draw); 970bf215546Sopenharmony_ci pandecode_dcd(&draw, job_no, h->type, "", gpu_id); 971bf215546Sopenharmony_ci 972bf215546Sopenharmony_ci pandecode_log("Vertex Job Payload:\n"); 973bf215546Sopenharmony_ci pandecode_indent++; 974bf215546Sopenharmony_ci pandecode_invocation(pan_section_ptr(p, COMPUTE_JOB, INVOCATION)); 975bf215546Sopenharmony_ci DUMP_SECTION(COMPUTE_JOB, PARAMETERS, p, "Vertex Job Parameters:\n"); 976bf215546Sopenharmony_ci DUMP_UNPACKED(DRAW, draw, "Draw:\n"); 977bf215546Sopenharmony_ci pandecode_indent--; 978bf215546Sopenharmony_ci pandecode_log("\n"); 979bf215546Sopenharmony_ci} 980bf215546Sopenharmony_ci#endif 981bf215546Sopenharmony_ci 982bf215546Sopenharmony_ci#if PAN_ARCH >= 6 983bf215546Sopenharmony_cistatic void 984bf215546Sopenharmony_cipandecode_bifrost_tiler_heap(mali_ptr gpu_va, int job_no) 985bf215546Sopenharmony_ci{ 986bf215546Sopenharmony_ci struct pandecode_mapped_memory *mem = pandecode_find_mapped_gpu_mem_containing(gpu_va); 987bf215546Sopenharmony_ci pan_unpack(PANDECODE_PTR(mem, gpu_va, void), TILER_HEAP, h); 988bf215546Sopenharmony_ci DUMP_UNPACKED(TILER_HEAP, h, "Bifrost Tiler Heap:\n"); 989bf215546Sopenharmony_ci} 990bf215546Sopenharmony_ci 991bf215546Sopenharmony_cistatic void 992bf215546Sopenharmony_cipandecode_bifrost_tiler(mali_ptr gpu_va, int job_no) 993bf215546Sopenharmony_ci{ 994bf215546Sopenharmony_ci struct pandecode_mapped_memory *mem = pandecode_find_mapped_gpu_mem_containing(gpu_va); 995bf215546Sopenharmony_ci pan_unpack(PANDECODE_PTR(mem, gpu_va, void), TILER_CONTEXT, t); 996bf215546Sopenharmony_ci 997bf215546Sopenharmony_ci if (t.heap) 998bf215546Sopenharmony_ci pandecode_bifrost_tiler_heap(t.heap, job_no); 999bf215546Sopenharmony_ci 1000bf215546Sopenharmony_ci DUMP_UNPACKED(TILER_CONTEXT, t, "Bifrost Tiler:\n"); 1001bf215546Sopenharmony_ci} 1002bf215546Sopenharmony_ci 1003bf215546Sopenharmony_ci#if PAN_ARCH <= 7 1004bf215546Sopenharmony_cistatic void 1005bf215546Sopenharmony_cipandecode_indexed_vertex_job(const struct MALI_JOB_HEADER *h, 1006bf215546Sopenharmony_ci const struct pandecode_mapped_memory *mem, 1007bf215546Sopenharmony_ci mali_ptr job, int job_no, unsigned gpu_id) 1008bf215546Sopenharmony_ci{ 1009bf215546Sopenharmony_ci struct mali_indexed_vertex_job_packed *PANDECODE_PTR_VAR(p, mem, job); 1010bf215546Sopenharmony_ci 1011bf215546Sopenharmony_ci pandecode_log("Vertex:\n"); 1012bf215546Sopenharmony_ci pan_section_unpack(p, INDEXED_VERTEX_JOB, VERTEX_DRAW, vert_draw); 1013bf215546Sopenharmony_ci pandecode_dcd(&vert_draw, job_no, h->type, "", gpu_id); 1014bf215546Sopenharmony_ci DUMP_UNPACKED(DRAW, vert_draw, "Vertex Draw:\n"); 1015bf215546Sopenharmony_ci 1016bf215546Sopenharmony_ci pandecode_log("Fragment:\n"); 1017bf215546Sopenharmony_ci pan_section_unpack(p, INDEXED_VERTEX_JOB, FRAGMENT_DRAW, frag_draw); 1018bf215546Sopenharmony_ci pandecode_dcd(&frag_draw, job_no, MALI_JOB_TYPE_FRAGMENT, "", gpu_id); 1019bf215546Sopenharmony_ci DUMP_UNPACKED(DRAW, frag_draw, "Fragment Draw:\n"); 1020bf215546Sopenharmony_ci 1021bf215546Sopenharmony_ci pan_section_unpack(p, INDEXED_VERTEX_JOB, TILER, tiler_ptr); 1022bf215546Sopenharmony_ci pandecode_log("Tiler Job Payload:\n"); 1023bf215546Sopenharmony_ci pandecode_indent++; 1024bf215546Sopenharmony_ci pandecode_bifrost_tiler(tiler_ptr.address, job_no); 1025bf215546Sopenharmony_ci pandecode_indent--; 1026bf215546Sopenharmony_ci 1027bf215546Sopenharmony_ci pandecode_invocation(pan_section_ptr(p, INDEXED_VERTEX_JOB, INVOCATION)); 1028bf215546Sopenharmony_ci pandecode_primitive(pan_section_ptr(p, INDEXED_VERTEX_JOB, PRIMITIVE)); 1029bf215546Sopenharmony_ci 1030bf215546Sopenharmony_ci /* TODO: gl_PointSize on Bifrost */ 1031bf215546Sopenharmony_ci pandecode_primitive_size(pan_section_ptr(p, INDEXED_VERTEX_JOB, PRIMITIVE_SIZE), true); 1032bf215546Sopenharmony_ci 1033bf215546Sopenharmony_ci pan_section_unpack(p, INDEXED_VERTEX_JOB, PADDING, padding); 1034bf215546Sopenharmony_ci} 1035bf215546Sopenharmony_ci#endif 1036bf215546Sopenharmony_ci#endif 1037bf215546Sopenharmony_ci 1038bf215546Sopenharmony_cistatic void 1039bf215546Sopenharmony_cipandecode_tiler_job(const struct MALI_JOB_HEADER *h, 1040bf215546Sopenharmony_ci const struct pandecode_mapped_memory *mem, 1041bf215546Sopenharmony_ci mali_ptr job, int job_no, unsigned gpu_id) 1042bf215546Sopenharmony_ci{ 1043bf215546Sopenharmony_ci struct mali_tiler_job_packed *PANDECODE_PTR_VAR(p, mem, job); 1044bf215546Sopenharmony_ci pan_section_unpack(p, TILER_JOB, DRAW, draw); 1045bf215546Sopenharmony_ci pandecode_dcd(&draw, job_no, h->type, "", gpu_id); 1046bf215546Sopenharmony_ci pandecode_log("Tiler Job Payload:\n"); 1047bf215546Sopenharmony_ci pandecode_indent++; 1048bf215546Sopenharmony_ci 1049bf215546Sopenharmony_ci#if PAN_ARCH <= 7 1050bf215546Sopenharmony_ci pandecode_invocation(pan_section_ptr(p, TILER_JOB, INVOCATION)); 1051bf215546Sopenharmony_ci#endif 1052bf215546Sopenharmony_ci 1053bf215546Sopenharmony_ci pandecode_primitive(pan_section_ptr(p, TILER_JOB, PRIMITIVE)); 1054bf215546Sopenharmony_ci DUMP_UNPACKED(DRAW, draw, "Draw:\n"); 1055bf215546Sopenharmony_ci 1056bf215546Sopenharmony_ci#if PAN_ARCH >= 6 1057bf215546Sopenharmony_ci pan_section_unpack(p, TILER_JOB, TILER, tiler_ptr); 1058bf215546Sopenharmony_ci pandecode_bifrost_tiler(tiler_ptr.address, job_no); 1059bf215546Sopenharmony_ci 1060bf215546Sopenharmony_ci /* TODO: gl_PointSize on Bifrost */ 1061bf215546Sopenharmony_ci pandecode_primitive_size(pan_section_ptr(p, TILER_JOB, PRIMITIVE_SIZE), true); 1062bf215546Sopenharmony_ci 1063bf215546Sopenharmony_ci#if PAN_ARCH >= 9 1064bf215546Sopenharmony_ci DUMP_SECTION(TILER_JOB, INSTANCE_COUNT, p, "Instance count:\n"); 1065bf215546Sopenharmony_ci DUMP_SECTION(TILER_JOB, VERTEX_COUNT, p, "Vertex count:\n"); 1066bf215546Sopenharmony_ci DUMP_SECTION(TILER_JOB, SCISSOR, p, "Scissor:\n"); 1067bf215546Sopenharmony_ci DUMP_SECTION(TILER_JOB, INDICES, p, "Indices:\n"); 1068bf215546Sopenharmony_ci#else 1069bf215546Sopenharmony_ci pan_section_unpack(p, TILER_JOB, PADDING, padding); 1070bf215546Sopenharmony_ci#endif 1071bf215546Sopenharmony_ci 1072bf215546Sopenharmony_ci#else 1073bf215546Sopenharmony_ci pan_section_unpack(p, TILER_JOB, PRIMITIVE, primitive); 1074bf215546Sopenharmony_ci pandecode_primitive_size(pan_section_ptr(p, TILER_JOB, PRIMITIVE_SIZE), 1075bf215546Sopenharmony_ci primitive.point_size_array_format == MALI_POINT_SIZE_ARRAY_FORMAT_NONE); 1076bf215546Sopenharmony_ci#endif 1077bf215546Sopenharmony_ci pandecode_indent--; 1078bf215546Sopenharmony_ci pandecode_log("\n"); 1079bf215546Sopenharmony_ci} 1080bf215546Sopenharmony_ci 1081bf215546Sopenharmony_cistatic void 1082bf215546Sopenharmony_cipandecode_fragment_job(const struct pandecode_mapped_memory *mem, 1083bf215546Sopenharmony_ci mali_ptr job, int job_no, unsigned gpu_id) 1084bf215546Sopenharmony_ci{ 1085bf215546Sopenharmony_ci struct mali_fragment_job_packed *PANDECODE_PTR_VAR(p, mem, job); 1086bf215546Sopenharmony_ci pan_section_unpack(p, FRAGMENT_JOB, PAYLOAD, s); 1087bf215546Sopenharmony_ci 1088bf215546Sopenharmony_ci 1089bf215546Sopenharmony_ci#if PAN_ARCH == 4 1090bf215546Sopenharmony_ci pandecode_sfbd(s.framebuffer, job_no, true, gpu_id); 1091bf215546Sopenharmony_ci#else 1092bf215546Sopenharmony_ci assert(s.framebuffer & MALI_FBD_TAG_IS_MFBD); 1093bf215546Sopenharmony_ci 1094bf215546Sopenharmony_ci struct pandecode_fbd info; 1095bf215546Sopenharmony_ci 1096bf215546Sopenharmony_ci info = pandecode_mfbd_bfr(s.framebuffer & ~MALI_FBD_TAG_MASK, job_no, 1097bf215546Sopenharmony_ci true, gpu_id); 1098bf215546Sopenharmony_ci#endif 1099bf215546Sopenharmony_ci 1100bf215546Sopenharmony_ci#if PAN_ARCH >= 5 1101bf215546Sopenharmony_ci unsigned expected_tag = 0; 1102bf215546Sopenharmony_ci 1103bf215546Sopenharmony_ci /* Compute the tag for the tagged pointer. This contains the type of 1104bf215546Sopenharmony_ci * FBD (MFBD/SFBD), and in the case of an MFBD, information about which 1105bf215546Sopenharmony_ci * additional structures follow the MFBD header (an extra payload or 1106bf215546Sopenharmony_ci * not, as well as a count of render targets) */ 1107bf215546Sopenharmony_ci 1108bf215546Sopenharmony_ci expected_tag = MALI_FBD_TAG_IS_MFBD; 1109bf215546Sopenharmony_ci if (info.has_extra) 1110bf215546Sopenharmony_ci expected_tag |= MALI_FBD_TAG_HAS_ZS_RT; 1111bf215546Sopenharmony_ci 1112bf215546Sopenharmony_ci expected_tag |= MALI_FBD_TAG_IS_MFBD | (MALI_POSITIVE(info.rt_count) << 2); 1113bf215546Sopenharmony_ci#endif 1114bf215546Sopenharmony_ci 1115bf215546Sopenharmony_ci DUMP_UNPACKED(FRAGMENT_JOB_PAYLOAD, s, "Fragment Job Payload:\n"); 1116bf215546Sopenharmony_ci 1117bf215546Sopenharmony_ci#if PAN_ARCH >= 5 1118bf215546Sopenharmony_ci /* The FBD is a tagged pointer */ 1119bf215546Sopenharmony_ci 1120bf215546Sopenharmony_ci unsigned tag = (s.framebuffer & MALI_FBD_TAG_MASK); 1121bf215546Sopenharmony_ci 1122bf215546Sopenharmony_ci if (tag != expected_tag) 1123bf215546Sopenharmony_ci pandecode_msg("XXX: expected FBD tag %X but got %X\n", expected_tag, tag); 1124bf215546Sopenharmony_ci#endif 1125bf215546Sopenharmony_ci 1126bf215546Sopenharmony_ci pandecode_log("\n"); 1127bf215546Sopenharmony_ci} 1128bf215546Sopenharmony_ci 1129bf215546Sopenharmony_cistatic void 1130bf215546Sopenharmony_cipandecode_write_value_job(const struct pandecode_mapped_memory *mem, 1131bf215546Sopenharmony_ci mali_ptr job, int job_no) 1132bf215546Sopenharmony_ci{ 1133bf215546Sopenharmony_ci struct mali_write_value_job_packed *PANDECODE_PTR_VAR(p, mem, job); 1134bf215546Sopenharmony_ci pan_section_unpack(p, WRITE_VALUE_JOB, PAYLOAD, u); 1135bf215546Sopenharmony_ci DUMP_SECTION(WRITE_VALUE_JOB, PAYLOAD, p, "Write Value Payload:\n"); 1136bf215546Sopenharmony_ci pandecode_log("\n"); 1137bf215546Sopenharmony_ci} 1138bf215546Sopenharmony_ci 1139bf215546Sopenharmony_cistatic void 1140bf215546Sopenharmony_cipandecode_cache_flush_job(const struct pandecode_mapped_memory *mem, 1141bf215546Sopenharmony_ci mali_ptr job, int job_no) 1142bf215546Sopenharmony_ci{ 1143bf215546Sopenharmony_ci struct mali_cache_flush_job_packed *PANDECODE_PTR_VAR(p, mem, job); 1144bf215546Sopenharmony_ci pan_section_unpack(p, CACHE_FLUSH_JOB, PAYLOAD, u); 1145bf215546Sopenharmony_ci DUMP_SECTION(CACHE_FLUSH_JOB, PAYLOAD, p, "Cache Flush Payload:\n"); 1146bf215546Sopenharmony_ci pandecode_log("\n"); 1147bf215546Sopenharmony_ci} 1148bf215546Sopenharmony_ci 1149bf215546Sopenharmony_ci#if PAN_ARCH >= 9 1150bf215546Sopenharmony_cistatic void 1151bf215546Sopenharmony_cidump_fau(mali_ptr addr, unsigned count, const char *name) 1152bf215546Sopenharmony_ci{ 1153bf215546Sopenharmony_ci struct pandecode_mapped_memory *mem = 1154bf215546Sopenharmony_ci pandecode_find_mapped_gpu_mem_containing(addr); 1155bf215546Sopenharmony_ci const uint32_t *PANDECODE_PTR_VAR(raw, mem, addr); 1156bf215546Sopenharmony_ci 1157bf215546Sopenharmony_ci pandecode_validate_buffer(addr, count * 8); 1158bf215546Sopenharmony_ci 1159bf215546Sopenharmony_ci fprintf(pandecode_dump_stream, "%s:\n", name); 1160bf215546Sopenharmony_ci for (unsigned i = 0; i < count; ++i) { 1161bf215546Sopenharmony_ci fprintf(pandecode_dump_stream, " %08X %08X\n", 1162bf215546Sopenharmony_ci raw[2*i], raw[2*i + 1]); 1163bf215546Sopenharmony_ci } 1164bf215546Sopenharmony_ci fprintf(pandecode_dump_stream, "\n"); 1165bf215546Sopenharmony_ci} 1166bf215546Sopenharmony_ci 1167bf215546Sopenharmony_cistatic mali_ptr 1168bf215546Sopenharmony_cipandecode_shader(mali_ptr addr, const char *label, unsigned gpu_id) 1169bf215546Sopenharmony_ci{ 1170bf215546Sopenharmony_ci MAP_ADDR(SHADER_PROGRAM, addr, cl); 1171bf215546Sopenharmony_ci pan_unpack(cl, SHADER_PROGRAM, desc); 1172bf215546Sopenharmony_ci 1173bf215546Sopenharmony_ci assert(desc.type == 8); 1174bf215546Sopenharmony_ci 1175bf215546Sopenharmony_ci DUMP_UNPACKED(SHADER_PROGRAM, desc, "%s Shader:\n", label); 1176bf215546Sopenharmony_ci pandecode_shader_disassemble(desc.binary, 0, 0, gpu_id); 1177bf215546Sopenharmony_ci return desc.binary; 1178bf215546Sopenharmony_ci} 1179bf215546Sopenharmony_ci 1180bf215546Sopenharmony_cistatic void 1181bf215546Sopenharmony_cipandecode_resources(mali_ptr addr, unsigned size) 1182bf215546Sopenharmony_ci{ 1183bf215546Sopenharmony_ci struct pandecode_mapped_memory *mem = pandecode_find_mapped_gpu_mem_containing(addr); 1184bf215546Sopenharmony_ci const uint8_t *cl = pandecode_fetch_gpu_mem(mem, addr, size); 1185bf215546Sopenharmony_ci assert((size % 0x20) == 0); 1186bf215546Sopenharmony_ci 1187bf215546Sopenharmony_ci for (unsigned i = 0; i < size; i += 0x20) { 1188bf215546Sopenharmony_ci unsigned type = (cl[i] & 0xF); 1189bf215546Sopenharmony_ci 1190bf215546Sopenharmony_ci switch (type) { 1191bf215546Sopenharmony_ci case MALI_DESCRIPTOR_TYPE_SAMPLER: 1192bf215546Sopenharmony_ci DUMP_CL(SAMPLER, cl + i, "Sampler:\n"); 1193bf215546Sopenharmony_ci break; 1194bf215546Sopenharmony_ci case MALI_DESCRIPTOR_TYPE_TEXTURE: 1195bf215546Sopenharmony_ci pandecode_bifrost_texture(cl + i, 0, i); 1196bf215546Sopenharmony_ci break; 1197bf215546Sopenharmony_ci case MALI_DESCRIPTOR_TYPE_ATTRIBUTE: 1198bf215546Sopenharmony_ci DUMP_CL(ATTRIBUTE, cl + i, "Attribute:\n"); 1199bf215546Sopenharmony_ci break; 1200bf215546Sopenharmony_ci case MALI_DESCRIPTOR_TYPE_BUFFER: 1201bf215546Sopenharmony_ci DUMP_CL(BUFFER, cl + i, "Buffer:\n"); 1202bf215546Sopenharmony_ci break; 1203bf215546Sopenharmony_ci default: 1204bf215546Sopenharmony_ci fprintf(pandecode_dump_stream, "Unknown descriptor type %X\n", type); 1205bf215546Sopenharmony_ci break; 1206bf215546Sopenharmony_ci } 1207bf215546Sopenharmony_ci } 1208bf215546Sopenharmony_ci} 1209bf215546Sopenharmony_ci 1210bf215546Sopenharmony_cistatic void 1211bf215546Sopenharmony_cipandecode_resource_tables(mali_ptr addr, const char *label) 1212bf215546Sopenharmony_ci{ 1213bf215546Sopenharmony_ci unsigned count = addr & 0x3F; 1214bf215546Sopenharmony_ci addr = addr & ~0x3F; 1215bf215546Sopenharmony_ci 1216bf215546Sopenharmony_ci struct pandecode_mapped_memory *mem = pandecode_find_mapped_gpu_mem_containing(addr); 1217bf215546Sopenharmony_ci const uint8_t *cl = pandecode_fetch_gpu_mem(mem, addr, MALI_RESOURCE_LENGTH * count); 1218bf215546Sopenharmony_ci 1219bf215546Sopenharmony_ci for (unsigned i = 0; i < count; ++i) { 1220bf215546Sopenharmony_ci pan_unpack(cl + i * MALI_RESOURCE_LENGTH, RESOURCE, entry); 1221bf215546Sopenharmony_ci DUMP_UNPACKED(RESOURCE, entry, "Entry %u:\n", i); 1222bf215546Sopenharmony_ci 1223bf215546Sopenharmony_ci pandecode_indent += 2; 1224bf215546Sopenharmony_ci if (entry.address) 1225bf215546Sopenharmony_ci pandecode_resources(entry.address, entry.size); 1226bf215546Sopenharmony_ci pandecode_indent -= 2; 1227bf215546Sopenharmony_ci } 1228bf215546Sopenharmony_ci} 1229bf215546Sopenharmony_ci 1230bf215546Sopenharmony_cistatic void 1231bf215546Sopenharmony_cipandecode_depth_stencil(mali_ptr addr) 1232bf215546Sopenharmony_ci{ 1233bf215546Sopenharmony_ci MAP_ADDR(DEPTH_STENCIL, addr, cl); 1234bf215546Sopenharmony_ci pan_unpack(cl, DEPTH_STENCIL, desc); 1235bf215546Sopenharmony_ci DUMP_UNPACKED(DEPTH_STENCIL, desc, "Depth/stencil"); 1236bf215546Sopenharmony_ci} 1237bf215546Sopenharmony_ci 1238bf215546Sopenharmony_cistatic void 1239bf215546Sopenharmony_cipandecode_shader_environment(const struct MALI_SHADER_ENVIRONMENT *p, 1240bf215546Sopenharmony_ci unsigned gpu_id) 1241bf215546Sopenharmony_ci{ 1242bf215546Sopenharmony_ci if (p->shader) 1243bf215546Sopenharmony_ci pandecode_shader(p->shader, "Shader", gpu_id); 1244bf215546Sopenharmony_ci 1245bf215546Sopenharmony_ci if (p->resources) 1246bf215546Sopenharmony_ci pandecode_resource_tables(p->resources, "Resources"); 1247bf215546Sopenharmony_ci 1248bf215546Sopenharmony_ci if (p->thread_storage) 1249bf215546Sopenharmony_ci pandecode_local_storage(p->thread_storage, 0); 1250bf215546Sopenharmony_ci 1251bf215546Sopenharmony_ci if (p->fau) 1252bf215546Sopenharmony_ci dump_fau(p->fau, p->fau_count, "FAU"); 1253bf215546Sopenharmony_ci} 1254bf215546Sopenharmony_ci 1255bf215546Sopenharmony_cistatic void 1256bf215546Sopenharmony_cipandecode_dcd(const struct MALI_DRAW *p, 1257bf215546Sopenharmony_ci int job_no, enum mali_job_type job_type, 1258bf215546Sopenharmony_ci char *suffix, unsigned gpu_id) 1259bf215546Sopenharmony_ci{ 1260bf215546Sopenharmony_ci mali_ptr frag_shader = 0; 1261bf215546Sopenharmony_ci 1262bf215546Sopenharmony_ci pandecode_depth_stencil(p->depth_stencil); 1263bf215546Sopenharmony_ci 1264bf215546Sopenharmony_ci for (unsigned i = 0; i < p->blend_count; ++i) { 1265bf215546Sopenharmony_ci struct pandecode_mapped_memory *blend_mem = 1266bf215546Sopenharmony_ci pandecode_find_mapped_gpu_mem_containing(p->blend); 1267bf215546Sopenharmony_ci 1268bf215546Sopenharmony_ci struct mali_blend_packed *PANDECODE_PTR_VAR(blend_descs, blend_mem, p->blend); 1269bf215546Sopenharmony_ci 1270bf215546Sopenharmony_ci mali_ptr blend_shader = pandecode_bifrost_blend(blend_descs, 0, i, frag_shader); 1271bf215546Sopenharmony_ci if (blend_shader) { 1272bf215546Sopenharmony_ci fprintf(pandecode_dump_stream, "Blend shader %u", i); 1273bf215546Sopenharmony_ci pandecode_shader_disassemble(blend_shader, 0, 0, gpu_id); 1274bf215546Sopenharmony_ci } 1275bf215546Sopenharmony_ci } 1276bf215546Sopenharmony_ci 1277bf215546Sopenharmony_ci pandecode_shader_environment(&p->shader, gpu_id); 1278bf215546Sopenharmony_ci DUMP_UNPACKED(DRAW, *p, "Draw:\n"); 1279bf215546Sopenharmony_ci} 1280bf215546Sopenharmony_ci 1281bf215546Sopenharmony_cistatic void 1282bf215546Sopenharmony_cipandecode_malloc_vertex_job(const struct pandecode_mapped_memory *mem, 1283bf215546Sopenharmony_ci mali_ptr job, unsigned gpu_id) 1284bf215546Sopenharmony_ci{ 1285bf215546Sopenharmony_ci struct mali_malloc_vertex_job_packed *PANDECODE_PTR_VAR(p, mem, job); 1286bf215546Sopenharmony_ci 1287bf215546Sopenharmony_ci DUMP_SECTION(MALLOC_VERTEX_JOB, PRIMITIVE, p, "Primitive:\n"); 1288bf215546Sopenharmony_ci DUMP_SECTION(MALLOC_VERTEX_JOB, INSTANCE_COUNT, p, "Instance count:\n"); 1289bf215546Sopenharmony_ci DUMP_SECTION(MALLOC_VERTEX_JOB, ALLOCATION, p, "Allocation:\n"); 1290bf215546Sopenharmony_ci DUMP_SECTION(MALLOC_VERTEX_JOB, TILER, p, "Tiler:\n"); 1291bf215546Sopenharmony_ci DUMP_SECTION(MALLOC_VERTEX_JOB, SCISSOR, p, "Scissor:\n"); 1292bf215546Sopenharmony_ci DUMP_SECTION(MALLOC_VERTEX_JOB, PRIMITIVE_SIZE, p, "Primitive Size:\n"); 1293bf215546Sopenharmony_ci DUMP_SECTION(MALLOC_VERTEX_JOB, INDICES, p, "Indices:\n"); 1294bf215546Sopenharmony_ci 1295bf215546Sopenharmony_ci pan_section_unpack(p, MALLOC_VERTEX_JOB, DRAW, dcd); 1296bf215546Sopenharmony_ci 1297bf215546Sopenharmony_ci pan_section_unpack(p, MALLOC_VERTEX_JOB, TILER, tiler_ptr); 1298bf215546Sopenharmony_ci pandecode_log("Tiler Job Payload:\n"); 1299bf215546Sopenharmony_ci pandecode_indent++; 1300bf215546Sopenharmony_ci if (tiler_ptr.address) 1301bf215546Sopenharmony_ci pandecode_bifrost_tiler(tiler_ptr.address, 0); 1302bf215546Sopenharmony_ci else 1303bf215546Sopenharmony_ci pandecode_log("<omitted>\n"); 1304bf215546Sopenharmony_ci pandecode_indent--; 1305bf215546Sopenharmony_ci 1306bf215546Sopenharmony_ci pandecode_dcd(&dcd, 0, 0, NULL, gpu_id); 1307bf215546Sopenharmony_ci 1308bf215546Sopenharmony_ci pan_section_unpack(p, MALLOC_VERTEX_JOB, POSITION, position); 1309bf215546Sopenharmony_ci pan_section_unpack(p, MALLOC_VERTEX_JOB, VARYING, varying); 1310bf215546Sopenharmony_ci pandecode_shader_environment(&position, gpu_id); 1311bf215546Sopenharmony_ci pandecode_shader_environment(&varying, gpu_id); 1312bf215546Sopenharmony_ci} 1313bf215546Sopenharmony_ci 1314bf215546Sopenharmony_cistatic void 1315bf215546Sopenharmony_cipandecode_compute_job(const struct pandecode_mapped_memory *mem, mali_ptr job, unsigned gpu_id) 1316bf215546Sopenharmony_ci{ 1317bf215546Sopenharmony_ci struct mali_compute_job_packed *PANDECODE_PTR_VAR(p, mem, job); 1318bf215546Sopenharmony_ci pan_section_unpack(p, COMPUTE_JOB, PAYLOAD, payload); 1319bf215546Sopenharmony_ci 1320bf215546Sopenharmony_ci pandecode_shader(payload.compute.shader, "Shader", gpu_id); 1321bf215546Sopenharmony_ci if (payload.compute.thread_storage) 1322bf215546Sopenharmony_ci pandecode_local_storage(payload.compute.thread_storage, 0); 1323bf215546Sopenharmony_ci if (payload.compute.fau) 1324bf215546Sopenharmony_ci dump_fau(payload.compute.fau, payload.compute.fau_count, "FAU"); 1325bf215546Sopenharmony_ci if (payload.compute.resources) 1326bf215546Sopenharmony_ci pandecode_resource_tables(payload.compute.resources, "Resources"); 1327bf215546Sopenharmony_ci 1328bf215546Sopenharmony_ci DUMP_UNPACKED(COMPUTE_PAYLOAD, payload, "Compute:\n"); 1329bf215546Sopenharmony_ci} 1330bf215546Sopenharmony_ci#endif 1331bf215546Sopenharmony_ci 1332bf215546Sopenharmony_ci/* Entrypoint to start tracing. jc_gpu_va is the GPU address for the first job 1333bf215546Sopenharmony_ci * in the chain; later jobs are found by walking the chain. Bifrost is, well, 1334bf215546Sopenharmony_ci * if it's bifrost or not. GPU ID is the more finegrained ID (at some point, we 1335bf215546Sopenharmony_ci * might wish to combine this with the bifrost parameter) because some details 1336bf215546Sopenharmony_ci * are model-specific even within a particular architecture. */ 1337bf215546Sopenharmony_ci 1338bf215546Sopenharmony_civoid 1339bf215546Sopenharmony_ciGENX(pandecode_jc)(mali_ptr jc_gpu_va, unsigned gpu_id) 1340bf215546Sopenharmony_ci{ 1341bf215546Sopenharmony_ci pandecode_dump_file_open(); 1342bf215546Sopenharmony_ci 1343bf215546Sopenharmony_ci unsigned job_descriptor_number = 0; 1344bf215546Sopenharmony_ci mali_ptr next_job = 0; 1345bf215546Sopenharmony_ci 1346bf215546Sopenharmony_ci do { 1347bf215546Sopenharmony_ci struct pandecode_mapped_memory *mem = 1348bf215546Sopenharmony_ci pandecode_find_mapped_gpu_mem_containing(jc_gpu_va); 1349bf215546Sopenharmony_ci 1350bf215546Sopenharmony_ci pan_unpack(PANDECODE_PTR(mem, jc_gpu_va, struct mali_job_header_packed), 1351bf215546Sopenharmony_ci JOB_HEADER, h); 1352bf215546Sopenharmony_ci next_job = h.next; 1353bf215546Sopenharmony_ci 1354bf215546Sopenharmony_ci int job_no = job_descriptor_number++; 1355bf215546Sopenharmony_ci 1356bf215546Sopenharmony_ci DUMP_UNPACKED(JOB_HEADER, h, "Job Header (%" PRIx64 "):\n", jc_gpu_va); 1357bf215546Sopenharmony_ci pandecode_log("\n"); 1358bf215546Sopenharmony_ci 1359bf215546Sopenharmony_ci switch (h.type) { 1360bf215546Sopenharmony_ci case MALI_JOB_TYPE_WRITE_VALUE: 1361bf215546Sopenharmony_ci pandecode_write_value_job(mem, jc_gpu_va, job_no); 1362bf215546Sopenharmony_ci break; 1363bf215546Sopenharmony_ci 1364bf215546Sopenharmony_ci case MALI_JOB_TYPE_CACHE_FLUSH: 1365bf215546Sopenharmony_ci pandecode_cache_flush_job(mem, jc_gpu_va, job_no); 1366bf215546Sopenharmony_ci break; 1367bf215546Sopenharmony_ci 1368bf215546Sopenharmony_ci case MALI_JOB_TYPE_TILER: 1369bf215546Sopenharmony_ci pandecode_tiler_job(&h, mem, jc_gpu_va, job_no, gpu_id); 1370bf215546Sopenharmony_ci break; 1371bf215546Sopenharmony_ci 1372bf215546Sopenharmony_ci#if PAN_ARCH <= 7 1373bf215546Sopenharmony_ci case MALI_JOB_TYPE_VERTEX: 1374bf215546Sopenharmony_ci case MALI_JOB_TYPE_COMPUTE: 1375bf215546Sopenharmony_ci pandecode_vertex_compute_geometry_job(&h, mem, jc_gpu_va, job_no, gpu_id); 1376bf215546Sopenharmony_ci break; 1377bf215546Sopenharmony_ci 1378bf215546Sopenharmony_ci#if PAN_ARCH >= 6 1379bf215546Sopenharmony_ci case MALI_JOB_TYPE_INDEXED_VERTEX: 1380bf215546Sopenharmony_ci pandecode_indexed_vertex_job(&h, mem, jc_gpu_va, job_no, gpu_id); 1381bf215546Sopenharmony_ci break; 1382bf215546Sopenharmony_ci#endif 1383bf215546Sopenharmony_ci#else 1384bf215546Sopenharmony_ci case MALI_JOB_TYPE_COMPUTE: 1385bf215546Sopenharmony_ci pandecode_compute_job(mem, jc_gpu_va, gpu_id); 1386bf215546Sopenharmony_ci break; 1387bf215546Sopenharmony_ci 1388bf215546Sopenharmony_ci case MALI_JOB_TYPE_MALLOC_VERTEX: 1389bf215546Sopenharmony_ci pandecode_malloc_vertex_job(mem, jc_gpu_va, gpu_id); 1390bf215546Sopenharmony_ci break; 1391bf215546Sopenharmony_ci#endif 1392bf215546Sopenharmony_ci 1393bf215546Sopenharmony_ci case MALI_JOB_TYPE_FRAGMENT: 1394bf215546Sopenharmony_ci pandecode_fragment_job(mem, jc_gpu_va, job_no, gpu_id); 1395bf215546Sopenharmony_ci break; 1396bf215546Sopenharmony_ci 1397bf215546Sopenharmony_ci default: 1398bf215546Sopenharmony_ci break; 1399bf215546Sopenharmony_ci } 1400bf215546Sopenharmony_ci } while ((jc_gpu_va = next_job)); 1401bf215546Sopenharmony_ci 1402bf215546Sopenharmony_ci fflush(pandecode_dump_stream); 1403bf215546Sopenharmony_ci pandecode_map_read_write(); 1404bf215546Sopenharmony_ci} 1405bf215546Sopenharmony_ci 1406bf215546Sopenharmony_civoid 1407bf215546Sopenharmony_ciGENX(pandecode_abort_on_fault)(mali_ptr jc_gpu_va) 1408bf215546Sopenharmony_ci{ 1409bf215546Sopenharmony_ci mali_ptr next_job = 0; 1410bf215546Sopenharmony_ci 1411bf215546Sopenharmony_ci do { 1412bf215546Sopenharmony_ci struct pandecode_mapped_memory *mem = 1413bf215546Sopenharmony_ci pandecode_find_mapped_gpu_mem_containing(jc_gpu_va); 1414bf215546Sopenharmony_ci 1415bf215546Sopenharmony_ci pan_unpack(PANDECODE_PTR(mem, jc_gpu_va, struct mali_job_header_packed), 1416bf215546Sopenharmony_ci JOB_HEADER, h); 1417bf215546Sopenharmony_ci next_job = h.next; 1418bf215546Sopenharmony_ci 1419bf215546Sopenharmony_ci /* Ensure the job is marked COMPLETE */ 1420bf215546Sopenharmony_ci if (h.exception_status != 0x1) { 1421bf215546Sopenharmony_ci fprintf(stderr, "Incomplete job or timeout\n"); 1422bf215546Sopenharmony_ci fflush(NULL); 1423bf215546Sopenharmony_ci abort(); 1424bf215546Sopenharmony_ci } 1425bf215546Sopenharmony_ci } while ((jc_gpu_va = next_job)); 1426bf215546Sopenharmony_ci 1427bf215546Sopenharmony_ci pandecode_map_read_write(); 1428bf215546Sopenharmony_ci} 1429