1 /* 2 * Copyright 2014 Broadcom 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 * IN THE SOFTWARE. 22 */ 23 24 #include "util/u_math.h" 25 #include "util/u_prim.h" 26 #include "util/macros.h" 27 #include "vc4_context.h" 28 29 #define dump_VC4_PACKET_LINE_WIDTH dump_float 30 #define dump_VC4_PACKET_POINT_SIZE dump_float 31 32 static void 33 dump_float(void *cl, uint32_t offset, uint32_t hw_offset) 34 { 35 void *f = cl + offset; 36 37 fprintf(stderr, "0x%08x 0x%08x: %f (0x%08x)\n", 38 offset, hw_offset, uif(*(uint32_t *)f), *(uint32_t *)f); 39 } 40 41 static void 42 dump_VC4_PACKET_BRANCH_TO_SUB_LIST(void *cl, uint32_t offset, uint32_t hw_offset) 43 { 44 uint32_t *addr = cl + offset; 45 46 fprintf(stderr, "0x%08x 0x%08x: addr 0x%08x\n", 47 offset, hw_offset, *addr); 48 } 49 50 static void 51 dump_loadstore_full(void *cl, uint32_t offset, uint32_t hw_offset) 52 { 53 uint32_t bits = *(uint32_t *)(cl + offset); 54 55 fprintf(stderr, "0x%08x 0x%08x: addr 0x%08x%s%s%s%s\n", 56 offset, hw_offset, 57 bits & ~0xf, 58 (bits & VC4_LOADSTORE_FULL_RES_DISABLE_CLEAR_ALL) ? "" : " clear", 59 (bits & VC4_LOADSTORE_FULL_RES_DISABLE_ZS) ? "" : " zs", 60 (bits & VC4_LOADSTORE_FULL_RES_DISABLE_COLOR) ? "" : " color", 61 (bits & VC4_LOADSTORE_FULL_RES_EOF) ? " eof" : ""); 62 } 63 64 static void 65 dump_VC4_PACKET_LOAD_FULL_RES_TILE_BUFFER(void *cl, uint32_t offset, uint32_t hw_offset) 66 { 67 dump_loadstore_full(cl, offset, hw_offset); 68 } 69 70 static void 71 dump_VC4_PACKET_STORE_FULL_RES_TILE_BUFFER(void *cl, uint32_t offset, uint32_t hw_offset) 72 { 73 dump_loadstore_full(cl, offset, hw_offset); 74 } 75 76 static void 77 dump_loadstore_general(void *cl, uint32_t offset, uint32_t hw_offset) 78 { 79 uint8_t *bytes = cl + offset; 80 uint32_t *addr = cl + offset + 2; 81 82 const char *fullvg = ""; 83 const char *fullzs = ""; 84 const char *fullcolor = ""; 85 const char *buffer = "???"; 86 87 switch ((bytes[0] & 0x7)){ 88 case 0: 89 buffer = "none"; 90 break; 91 case 1: 92 buffer = "color"; 93 break; 94 case 2: 95 buffer = "zs"; 96 break; 97 case 3: 98 buffer = "z"; 99 break; 100 case 4: 101 buffer = "vgmask"; 102 break; 103 case 5: 104 buffer = "full"; 105 if (*addr & (1 << 0)) 106 fullcolor = " !color"; 107 if (*addr & (1 << 1)) 108 fullzs = " !zs"; 109 if (*addr & (1 << 2)) 110 fullvg = " !vgmask"; 111 break; 112 } 113 114 const char *tiling = "???"; 115 switch ((bytes[0] >> 4) & 7) { 116 case 0: 117 tiling = "linear"; 118 break; 119 case 1: 120 tiling = "T"; 121 break; 122 case 2: 123 tiling = "LT"; 124 break; 125 } 126 127 const char *format = "???"; 128 switch (bytes[1] & 3) { 129 case 0: 130 format = "RGBA8888"; 131 break; 132 case 1: 133 format = "BGR565_DITHER"; 134 break; 135 case 2: 136 format = "BGR565"; 137 break; 138 } 139 140 fprintf(stderr, "0x%08x 0x%08x: 0x%02x %s %s\n", 141 offset + 0, hw_offset + 0, bytes[0], 142 buffer, tiling); 143 144 fprintf(stderr, "0x%08x 0x%08x: 0x%02x %s\n", 145 offset + 1, hw_offset + 1, bytes[1], 146 format); 147 148 fprintf(stderr, "0x%08x 0x%08x: addr 0x%08x %s%s%s%s\n", 149 offset + 2, hw_offset + 2, *addr & ~15, 150 fullcolor, fullzs, fullvg, 151 (*addr & (1 << 3)) ? " EOF" : ""); 152 } 153 154 static void 155 dump_VC4_PACKET_STORE_TILE_BUFFER_GENERAL(void *cl, uint32_t offset, uint32_t hw_offset) 156 { 157 dump_loadstore_general(cl, offset, hw_offset); 158 } 159 160 static void 161 dump_VC4_PACKET_LOAD_TILE_BUFFER_GENERAL(void *cl, uint32_t offset, uint32_t hw_offset) 162 { 163 dump_loadstore_general(cl, offset, hw_offset); 164 } 165 166 static void 167 dump_VC4_PACKET_GL_INDEXED_PRIMITIVE(void *cl, uint32_t offset, uint32_t hw_offset) 168 { 169 uint8_t *b = cl + offset; 170 uint32_t *count = cl + offset + 1; 171 uint32_t *ib_offset = cl + offset + 5; 172 uint32_t *max_index = cl + offset + 9; 173 174 fprintf(stderr, "0x%08x 0x%08x: 0x%02x %s %s\n", 175 offset, hw_offset, 176 b[0], (b[0] & VC4_INDEX_BUFFER_U16) ? "16-bit" : "8-bit", 177 u_prim_name(b[0] & 0x7)); 178 fprintf(stderr, "0x%08x 0x%08x: %d verts\n", 179 offset + 1, hw_offset + 1, *count); 180 fprintf(stderr, "0x%08x 0x%08x: 0x%08x IB offset\n", 181 offset + 5, hw_offset + 5, *ib_offset); 182 fprintf(stderr, "0x%08x 0x%08x: 0x%08x max index\n", 183 offset + 9, hw_offset + 9, *max_index); 184 } 185 186 static void 187 dump_VC4_PACKET_GL_ARRAY_PRIMITIVE(void *cl, uint32_t offset, uint32_t hw_offset) 188 { 189 uint8_t *b = cl + offset; 190 uint32_t *count = cl + offset + 1; 191 uint32_t *start = cl + offset + 5; 192 193 fprintf(stderr, "0x%08x 0x%08x: 0x%02x %s\n", 194 offset, hw_offset, b[0], u_prim_name(b[0] & 0x7)); 195 fprintf(stderr, "0x%08x 0x%08x: %d verts\n", 196 offset + 1, hw_offset + 1, *count); 197 fprintf(stderr, "0x%08x 0x%08x: 0x%08x start\n", 198 offset + 5, hw_offset + 5, *start); 199 } 200 201 static void 202 dump_VC4_PACKET_FLAT_SHADE_FLAGS(void *cl, uint32_t offset, uint32_t hw_offset) 203 { 204 uint32_t *bits = cl + offset; 205 206 fprintf(stderr, "0x%08x 0x%08x: bits 0x%08x\n", 207 offset, hw_offset, *bits); 208 } 209 210 static void 211 dump_VC4_PACKET_VIEWPORT_OFFSET(void *cl, uint32_t offset, uint32_t hw_offset) 212 { 213 uint16_t *o = cl + offset; 214 215 fprintf(stderr, "0x%08x 0x%08x: %f, %f (0x%04x, 0x%04x)\n", 216 offset, hw_offset, 217 o[0] / 16.0, o[1] / 16.0, 218 o[0], o[1]); 219 } 220 221 static void 222 dump_VC4_PACKET_CLIPPER_XY_SCALING(void *cl, uint32_t offset, uint32_t hw_offset) 223 { 224 uint32_t *scale = cl + offset; 225 226 fprintf(stderr, "0x%08x 0x%08x: %f, %f (%f, %f, 0x%08x, 0x%08x)\n", 227 offset, hw_offset, 228 uif(scale[0]) / 16.0, uif(scale[1]) / 16.0, 229 uif(scale[0]), uif(scale[1]), 230 scale[0], scale[1]); 231 } 232 233 static void 234 dump_VC4_PACKET_CLIPPER_Z_SCALING(void *cl, uint32_t offset, uint32_t hw_offset) 235 { 236 uint32_t *translate = cl + offset; 237 uint32_t *scale = cl + offset + 8; 238 239 fprintf(stderr, "0x%08x 0x%08x: %f, %f (0x%08x, 0x%08x)\n", 240 offset, hw_offset, 241 uif(translate[0]), uif(translate[1]), 242 translate[0], translate[1]); 243 244 fprintf(stderr, "0x%08x 0x%08x: %f, %f (0x%08x, 0x%08x)\n", 245 offset + 8, hw_offset + 8, 246 uif(scale[0]), uif(scale[1]), 247 scale[0], scale[1]); 248 } 249 250 static void 251 dump_VC4_PACKET_TILE_BINNING_MODE_CONFIG(void *cl, uint32_t offset, uint32_t hw_offset) 252 { 253 uint32_t *tile_alloc_addr = cl + offset; 254 uint32_t *tile_alloc_size = cl + offset + 4; 255 uint32_t *tile_state_addr = cl + offset + 8; 256 uint8_t *bin_x = cl + offset + 12; 257 uint8_t *bin_y = cl + offset + 13; 258 uint8_t *flags = cl + offset + 14; 259 260 fprintf(stderr, "0x%08x 0x%08x: tile alloc addr 0x%08x\n", 261 offset, hw_offset, 262 *tile_alloc_addr); 263 264 fprintf(stderr, "0x%08x 0x%08x: tile alloc size %db\n", 265 offset + 4, hw_offset + 4, 266 *tile_alloc_size); 267 268 fprintf(stderr, "0x%08x 0x%08x: tile state addr 0x%08x\n", 269 offset + 8, hw_offset + 8, 270 *tile_state_addr); 271 272 fprintf(stderr, "0x%08x 0x%08x: tiles (%d, %d)\n", 273 offset + 12, hw_offset + 12, 274 *bin_x, *bin_y); 275 276 fprintf(stderr, "0x%08x 0x%08x: flags 0x%02x\n", 277 offset + 14, hw_offset + 14, 278 *flags); 279 } 280 281 static void 282 dump_VC4_PACKET_TILE_RENDERING_MODE_CONFIG(void *cl, uint32_t offset, uint32_t hw_offset) 283 { 284 uint32_t *render_offset = cl + offset; 285 uint16_t *shorts = cl + offset + 4; 286 uint8_t *bytes = cl + offset + 8; 287 288 fprintf(stderr, "0x%08x 0x%08x: color offset 0x%08x\n", 289 offset, hw_offset, 290 *render_offset); 291 292 fprintf(stderr, "0x%08x 0x%08x: width %d\n", 293 offset + 4, hw_offset + 4, 294 shorts[0]); 295 296 fprintf(stderr, "0x%08x 0x%08x: height %d\n", 297 offset + 6, hw_offset + 6, 298 shorts[1]); 299 300 const char *format = "???"; 301 switch (VC4_GET_FIELD(shorts[2], VC4_RENDER_CONFIG_FORMAT)) { 302 case VC4_RENDER_CONFIG_FORMAT_BGR565_DITHERED: 303 format = "BGR565_DITHERED"; 304 break; 305 case VC4_RENDER_CONFIG_FORMAT_RGBA8888: 306 format = "RGBA8888"; 307 break; 308 case VC4_RENDER_CONFIG_FORMAT_BGR565: 309 format = "BGR565"; 310 break; 311 } 312 if (shorts[2] & VC4_RENDER_CONFIG_TILE_BUFFER_64BIT) 313 format = "64bit"; 314 315 const char *tiling = "???"; 316 switch (VC4_GET_FIELD(shorts[2], VC4_RENDER_CONFIG_MEMORY_FORMAT)) { 317 case VC4_TILING_FORMAT_LINEAR: 318 tiling = "linear"; 319 break; 320 case VC4_TILING_FORMAT_T: 321 tiling = "T"; 322 break; 323 case VC4_TILING_FORMAT_LT: 324 tiling = "LT"; 325 break; 326 } 327 328 fprintf(stderr, "0x%08x 0x%08x: 0x%02x %s %s %s %s\n", 329 offset + 8, hw_offset + 8, 330 bytes[0], 331 format, tiling, 332 (shorts[2] & VC4_RENDER_CONFIG_MS_MODE_4X) ? "ms" : "ss", 333 (shorts[2] & VC4_RENDER_CONFIG_DECIMATE_MODE_4X) ? 334 "ms_decimate" : "ss_decimate"); 335 336 const char *earlyz = ""; 337 if (shorts[2] & VC4_RENDER_CONFIG_EARLY_Z_COVERAGE_DISABLE) { 338 earlyz = "early_z disabled"; 339 } else { 340 if (shorts[2] & VC4_RENDER_CONFIG_EARLY_Z_DIRECTION_G) 341 earlyz = "early_z >"; 342 else 343 earlyz = "early_z <"; 344 } 345 346 fprintf(stderr, "0x%08x 0x%08x: 0x%02x %s\n", 347 offset + 9, hw_offset + 9, 348 bytes[1], 349 earlyz); 350 } 351 352 static void 353 dump_VC4_PACKET_TILE_COORDINATES(void *cl, uint32_t offset, uint32_t hw_offset) 354 { 355 uint8_t *tilecoords = cl + offset; 356 357 fprintf(stderr, "0x%08x 0x%08x: %d, %d\n", 358 offset, hw_offset, tilecoords[0], tilecoords[1]); 359 } 360 361 static void 362 dump_VC4_PACKET_GEM_HANDLES(void *cl, uint32_t offset, uint32_t hw_offset) 363 { 364 uint32_t *handles = cl + offset; 365 366 fprintf(stderr, "0x%08x 0x%08x: handle 0: %d, handle 1: %d\n", 367 offset, hw_offset, handles[0], handles[1]); 368 } 369 370 #define PACKET_DUMP(name) [name] = { #name, name ## _SIZE, dump_##name } 371 #define PACKET(name) [name] = { #name, name ## _SIZE, NULL } 372 373 static const struct packet_info { 374 const char *name; 375 uint8_t size; 376 void (*dump_func)(void *cl, uint32_t offset, uint32_t hw_offset); 377 } packet_info[] = { 378 PACKET(VC4_PACKET_HALT), 379 PACKET(VC4_PACKET_NOP), 380 381 PACKET(VC4_PACKET_FLUSH), 382 PACKET(VC4_PACKET_FLUSH_ALL), 383 PACKET(VC4_PACKET_START_TILE_BINNING), 384 PACKET(VC4_PACKET_INCREMENT_SEMAPHORE), 385 PACKET(VC4_PACKET_WAIT_ON_SEMAPHORE), 386 387 PACKET(VC4_PACKET_BRANCH), 388 PACKET_DUMP(VC4_PACKET_BRANCH_TO_SUB_LIST), 389 390 PACKET(VC4_PACKET_STORE_MS_TILE_BUFFER), 391 PACKET(VC4_PACKET_STORE_MS_TILE_BUFFER_AND_EOF), 392 PACKET_DUMP(VC4_PACKET_STORE_FULL_RES_TILE_BUFFER), 393 PACKET_DUMP(VC4_PACKET_LOAD_FULL_RES_TILE_BUFFER), 394 PACKET_DUMP(VC4_PACKET_STORE_TILE_BUFFER_GENERAL), 395 PACKET_DUMP(VC4_PACKET_LOAD_TILE_BUFFER_GENERAL), 396 397 PACKET_DUMP(VC4_PACKET_GL_INDEXED_PRIMITIVE), 398 PACKET_DUMP(VC4_PACKET_GL_ARRAY_PRIMITIVE), 399 400 PACKET(VC4_PACKET_COMPRESSED_PRIMITIVE), 401 PACKET(VC4_PACKET_CLIPPED_COMPRESSED_PRIMITIVE), 402 403 PACKET(VC4_PACKET_PRIMITIVE_LIST_FORMAT), 404 405 PACKET(VC4_PACKET_GL_SHADER_STATE), 406 PACKET(VC4_PACKET_NV_SHADER_STATE), 407 PACKET(VC4_PACKET_VG_SHADER_STATE), 408 409 PACKET(VC4_PACKET_CONFIGURATION_BITS), 410 PACKET_DUMP(VC4_PACKET_FLAT_SHADE_FLAGS), 411 PACKET_DUMP(VC4_PACKET_POINT_SIZE), 412 PACKET_DUMP(VC4_PACKET_LINE_WIDTH), 413 PACKET(VC4_PACKET_RHT_X_BOUNDARY), 414 PACKET(VC4_PACKET_DEPTH_OFFSET), 415 PACKET(VC4_PACKET_CLIP_WINDOW), 416 PACKET_DUMP(VC4_PACKET_VIEWPORT_OFFSET), 417 PACKET(VC4_PACKET_Z_CLIPPING), 418 PACKET_DUMP(VC4_PACKET_CLIPPER_XY_SCALING), 419 PACKET_DUMP(VC4_PACKET_CLIPPER_Z_SCALING), 420 421 PACKET_DUMP(VC4_PACKET_TILE_BINNING_MODE_CONFIG), 422 PACKET_DUMP(VC4_PACKET_TILE_RENDERING_MODE_CONFIG), 423 PACKET(VC4_PACKET_CLEAR_COLORS), 424 PACKET_DUMP(VC4_PACKET_TILE_COORDINATES), 425 426 PACKET_DUMP(VC4_PACKET_GEM_HANDLES), 427 }; 428 429 void 430 vc4_dump_cl(void *cl, uint32_t size, bool is_render) 431 { 432 uint32_t offset = 0, hw_offset = 0; 433 uint8_t *cmds = cl; 434 435 while (offset < size) { 436 uint8_t header = cmds[offset]; 437 438 if (header >= ARRAY_SIZE(packet_info) || 439 !packet_info[header].name) { 440 fprintf(stderr, "0x%08x 0x%08x: Unknown packet 0x%02x (%d)!\n", 441 offset, hw_offset, header, header); 442 return; 443 } 444 445 const struct packet_info *p = packet_info + header; 446 fprintf(stderr, "0x%08x 0x%08x: 0x%02x %s\n", 447 offset, 448 header != VC4_PACKET_GEM_HANDLES ? hw_offset : 0, 449 header, p->name); 450 451 if (offset + p->size <= size && 452 p->dump_func) { 453 p->dump_func(cmds, offset + 1, hw_offset + 1); 454 } else { 455 for (uint32_t i = 1; i < p->size; i++) { 456 if (offset + i >= size) { 457 fprintf(stderr, "0x%08x 0x%08x: CL overflow!\n", 458 offset + i, hw_offset + i); 459 return; 460 } 461 fprintf(stderr, "0x%08x 0x%08x: 0x%02x\n", 462 offset + i, 463 header != VC4_PACKET_GEM_HANDLES ? hw_offset + i : 0, 464 cmds[offset + i]); 465 } 466 } 467 468 switch (header) { 469 case VC4_PACKET_HALT: 470 case VC4_PACKET_STORE_MS_TILE_BUFFER_AND_EOF: 471 return; 472 default: 473 break; 474 } 475 476 offset += p->size; 477 if (header != VC4_PACKET_GEM_HANDLES) 478 hw_offset += p->size; 479 } 480 } 481 482