1/* 2 * Copyright (c) 2012 Rob Clark <robdclark@gmail.com> 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 FROM, 20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 * SOFTWARE. 22 */ 23 24#include <fcntl.h> 25#include <stdint.h> 26#include <stdio.h> 27#include <stdlib.h> 28#include <string.h> 29#include <unistd.h> 30#include <sys/stat.h> 31#include <sys/types.h> 32 33#include "disasm.h" 34#include "io.h" 35#include "redump.h" 36 37#define ASCII_XOR 0xff 38#include "util.h" 39 40struct pgm_header { 41 uint32_t size; 42 uint32_t unknown1; 43 uint32_t unknown2; 44 uint32_t revision; 45 uint32_t unknown4; 46 uint32_t unknown5; 47 uint32_t unknown6; 48 uint32_t unknown7; 49 uint32_t unknown8; 50 uint32_t num_attribs; 51 uint32_t num_uniforms; 52 uint32_t num_samplers; 53 uint32_t num_varyings; 54 uint32_t num_uniformblocks; 55}; 56 57struct vs_header { 58 uint32_t unknown1; /* seems to be # of sections up to and including shader */ 59 uint32_t unknown2; /* seems to be low byte or so of SQ_PROGRAM_CNTL */ 60 uint32_t unknown3; 61 uint32_t unknown4; 62 uint32_t unknown5; 63 uint32_t unknown6; 64 uint32_t unknown7; 65 uint32_t unknown8; 66 uint32_t unknown9; /* seems to be # of sections following shader */ 67}; 68 69struct fs_header { 70 uint32_t unknown1; 71}; 72/* 73 // Covers a lot of type_info 74 // varying, attribute, uniform, sampler 75 type_info & 0xFF 76 if ((type_info >> 8) == 0x8b) // vector 77 0x50 = vec2 78 0x51 = vec3 79 0x52 = vec4 80 0x53 = ivec2 81 0x54 = ivec3 82 0x55 = ivec4 83 0x56 = bool // Why is this in vector? 84 0x57 = bvec2 85 0x58 = bvec3 86 0x59 = bvec4 87 0x5a = mat2 88 0x5b = mat3 89 0x5c = mat4 90 0x5a = mat2x2 // Same as mat2 91 0x65 = mat2x3 92 0x66 = mat2x4 93 0x67 = mat3x2 94 0x5b = mat3x3 // Same as mat3 95 0x68 = mat3x4 96 0x69 = mat4x2 97 0x6a = mat4x3 98 0x5c = mat4x4 // same as mat4 99 0x5e = sampler2D 100 0x5f = sampler3D 101 0x60 = samplerCube // XXX: Doesn't work 102 0x62 = sampler2DShadow 103 0xc6 = uvec2 104 0xc7 = uvec3 105 0xc8 = uvec4 106 else if ((type_info >> 8) == 0x8d) // GLES3 samplers 107 0xC1 = sampler2DArray 108 0xC4 = sampler2DArrayShadow 109 0xC5 = samplerCubeShadow 110 0xCA = isampler2D 111 0xCB = isampler3D 112 0xCC = isamplerCube 113 0xD2 = usampler2D 114 0xD3 = usampler3D 115 0xD4 = usamplerCube 116 0xD7 = isampler2DArray 117 0xD7 = usampler2DArray // Is the same as isampler2DArray? 118 else // 0x14 = single 119 0x04 = int 120 0x05 = uint 121 0x06 = float 122*/ 123struct attribute { 124 uint32_t type_info; 125 uint32_t reg; /* seems to be the register the fetch instruction loads to */ 126 uint32_t const_idx; /* the CONST() indx value for sampler */ 127 uint32_t unknown2; 128 uint32_t unknown3; 129 uint32_t unknown4; 130 uint32_t unknown5; 131 char name[]; 132}; 133 134struct uniform { 135 uint32_t type_info; 136 uint32_t unknown2; 137 uint32_t unknown3; 138 uint32_t unknown4; 139 uint32_t const_base; /* const base register (for uniforms that take more than 140 one const reg, ie. matrices) */ 141 uint32_t unknown6; 142 uint32_t const_reg; /* the const register holding the value */ 143 uint32_t unknown7; 144 uint32_t unknown8; 145 uint32_t unknown9; 146 union { 147 struct { 148 char name[1]; 149 } v1; 150 struct { 151 uint32_t unknown10; 152 uint32_t unknown11; 153 uint32_t unknown12; 154 char name[]; 155 } v2; 156 }; 157}; 158 159struct uniformblockmember { 160 uint32_t type_info; 161 uint32_t is_array; 162 uint32_t array_size; /* elements in the array */ 163 uint32_t unknown2; /* Same as array_size */ 164 uint32_t 165 unknown3; /* Seems to be a offset within UBO in vertex (by components) */ 166 uint32_t unknown4; 167 uint32_t 168 unknown5; /* Seems to be a offset within UBO in fragment (by vec4) */ 169 uint32_t unknown6; 170 uint32_t unknown7; 171 uint32_t unknown8; 172 uint32_t unknown9; /* UBO block index? */ 173 uint32_t unknown10; 174 uint32_t unknown11; 175 uint32_t unknown12; 176 char name[]; 177}; 178 179struct uniformblock { 180 uint32_t type_info; 181 uint32_t unknown1; 182 uint32_t unknown2; 183 uint32_t unknown3; 184 uint32_t unknown4; 185 uint32_t num_members; 186 uint32_t num_members2; 187 uint32_t unknown5; 188 uint32_t unknown6; 189 uint32_t unknown7; 190 char name[]; 191}; 192 193struct sampler { 194 uint32_t type_info; 195 uint32_t is_array; 196 uint32_t array_size; /* elements in the array */ 197 uint32_t unknown4; /* same as array_size */ 198 uint32_t unknown5; 199 uint32_t unknown6; 200 uint32_t const_idx; /* the CONST() indx value for the sampler */ 201 uint32_t unknown7; 202 char name[]; 203}; 204 205struct varying { 206 uint32_t type_info; 207 uint32_t unknown2; 208 uint32_t unknown3; 209 uint32_t reg; /* the register holding the value (on entry to the shader) */ 210 char name[]; 211}; 212 213struct output { 214 uint32_t type_info; 215 uint32_t unknown2; 216 uint32_t unknown3; 217 uint32_t unknown4; 218 uint32_t unknown5; 219 uint32_t unknown6; 220 uint32_t unknown7; 221 uint32_t unknown8; 222 char name[]; 223}; 224 225struct constant { 226 uint32_t unknown1; 227 uint32_t unknown2; 228 uint32_t unknown3; 229 uint32_t const_idx; 230 float val[]; 231}; 232 233struct state { 234 char *buf; 235 int sz; 236 struct pgm_header *hdr; 237 struct attribute *attribs[32]; /* don't really know the upper limit.. */ 238 struct uniform *uniforms[32]; 239 struct sampler *samplers[32]; 240 struct varying *varyings[32]; 241 struct { 242 struct uniformblock *header; 243 struct uniformblockmember **members; /* GL ES 3.0 spec mandates minimum 244 16K support. a3xx supports 65K */ 245 } uniformblocks[24]; /* Maximum a330 supports */ 246 struct output *outputs[0]; /* I guess only one?? */ 247}; 248 249static const char *infile; 250static int full_dump = 1; 251static int dump_shaders = 0; 252static int gpu_id; 253 254static char * 255find_sect_end(char *buf, int sz) 256{ 257 uint8_t *ptr = (uint8_t *)buf; 258 uint8_t *end = ptr + sz - 3; 259 260 while (ptr < end) { 261 uint32_t d = 0; 262 263 d |= ptr[0] << 0; 264 d |= ptr[1] << 8; 265 d |= ptr[2] << 16; 266 d |= ptr[3] << 24; 267 268 /* someone at QC likes baseball */ 269 if (d == 0xba5eba11) 270 return (char *)ptr; 271 272 ptr++; 273 } 274 return NULL; 275} 276 277static void * 278next_sect(struct state *state, int *sect_size) 279{ 280 char *end = find_sect_end(state->buf, state->sz); 281 void *sect; 282 283 if (!end) 284 return NULL; 285 286 *sect_size = end - state->buf; 287 288 /* copy the section to keep things nicely 32b aligned: */ 289 sect = malloc(ALIGN(*sect_size, 4)); 290 memcpy(sect, state->buf, *sect_size); 291 292 state->sz -= *sect_size + 4; 293 state->buf = end + 4; 294 295 return sect; 296} 297 298static int 299valid_type(uint32_t type_info) 300{ 301 switch ((type_info >> 8) & 0xff) { 302 case 0x8b: /* vector */ 303 case 0x8d: /* GLES3 samplers */ 304 case 0x14: /* float */ 305 return 1; 306 default: 307 return 0; 308 } 309} 310 311#if 0 312static int valid_uniformblock(uint32_t type_info) 313{ 314 if (type_info == 0x128) 315 return 1; 316 return 0; 317} 318#endif 319 320static void 321dump_attribute(struct attribute *attrib) 322{ 323 printf("\tR%d, CONST(%d): %s\n", attrib->reg, attrib->const_idx, 324 attrib->name); 325} 326 327static inline int 328is_uniform_v2(struct uniform *uniform) 329{ 330 /* TODO maybe this should be based on revision #? */ 331 if (uniform->v2.unknown10 == 0) 332 return 1; 333 return 0; 334} 335 336static void 337dump_uniform(struct uniform *uniform) 338{ 339 char *name = is_uniform_v2(uniform) ? uniform->v2.name : uniform->v1.name; 340 if (uniform->const_reg == -1) { 341 printf("\tC%d+: %s\n", uniform->const_base, name); 342 } else { 343 printf("\tC%d: %s\n", uniform->const_reg, name); 344 } 345} 346 347static void 348dump_sampler(struct sampler *sampler) 349{ 350 printf("\tCONST(%d): %s\n", sampler->const_idx, sampler->name); 351} 352 353static void 354dump_varying(struct varying *varying) 355{ 356 printf("\tR%d: %s\n", varying->reg, varying->name); 357} 358 359static void 360dump_uniformblock(struct uniformblock *uniformblock) 361{ 362 printf("\tUniform Block: %s(%d)\n", uniformblock->name, 363 uniformblock->num_members); 364} 365 366static void 367dump_uniformblockmember(struct uniformblockmember *member) 368{ 369 printf("Uniform Block member: %s\n", member->name); 370} 371 372static void 373dump_output(struct output *output) 374{ 375 printf("\tR?: %s\n", output->name); 376} 377 378static void 379dump_constant(struct constant *constant) 380{ 381 printf("\tC%d: %f, %f, %f, %f\n", constant->const_idx, constant->val[0], 382 constant->val[1], constant->val[2], constant->val[3]); 383} 384 385/* dump attr/uniform/sampler/varying/const summary: */ 386static void 387dump_short_summary(struct state *state, int nconsts, 388 struct constant **constants) 389{ 390 int i; 391 392 /* dump attr/uniform/sampler/varying/const summary: */ 393 for (i = 0; i < state->hdr->num_varyings; i++) { 394 dump_varying(state->varyings[i]); 395 } 396 for (i = 0; i < state->hdr->num_attribs; i++) { 397 dump_attribute(state->attribs[i]); 398 } 399 for (i = 0; i < state->hdr->num_uniforms; i++) { 400 dump_uniform(state->uniforms[i]); 401 } 402 for (i = 0; i < state->hdr->num_samplers; i++) { 403 dump_sampler(state->samplers[i]); 404 } 405 for (i = 0; i < nconsts - 1; i++) { 406 if (constants[i]->unknown2 == 0) { 407 dump_constant(constants[i]); 408 } 409 } 410 printf("\n"); 411} 412 413static void 414dump_raw_shader(uint32_t *dwords, uint32_t sizedwords, int n, char *ext) 415{ 416 static char filename[256]; 417 int fd; 418 419 if (!dump_shaders) 420 return; 421 422 sprintf(filename, "%.*s-%d.%s", (int)strlen(infile) - 3, infile, n, ext); 423 fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, 0644); 424 if (fd != -1) { 425 write(fd, dwords, sizedwords * 4); 426 close(fd); 427 } 428} 429 430static void 431dump_shaders_a2xx(struct state *state) 432{ 433 int i, sect_size; 434 uint8_t *ptr; 435 436 /* dump vertex shaders: */ 437 for (i = 0; i < 3; i++) { 438 struct vs_header *vs_hdr = next_sect(state, §_size); 439 struct constant *constants[32]; 440 int j, level = 0; 441 442 printf("\n"); 443 444 if (full_dump) { 445 printf("#######################################################\n"); 446 printf("######## VS%d HEADER: (size %d)\n", i, sect_size); 447 dump_hex((void *)vs_hdr, sect_size); 448 } 449 450 for (j = 0; j < (int)vs_hdr->unknown1 - 1; j++) { 451 constants[j] = next_sect(state, §_size); 452 if (full_dump) { 453 printf("######## VS%d CONST: (size=%d)\n", i, sect_size); 454 dump_constant(constants[j]); 455 dump_hex((char *)constants[j], sect_size); 456 } 457 } 458 459 ptr = next_sect(state, §_size); 460 printf("######## VS%d SHADER: (size=%d)\n", i, sect_size); 461 if (full_dump) { 462 dump_hex(ptr, sect_size); 463 level = 1; 464 } else { 465 dump_short_summary(state, vs_hdr->unknown1 - 1, constants); 466 } 467 disasm_a2xx((uint32_t *)(ptr + 32), (sect_size - 32) / 4, level + 1, 468 MESA_SHADER_VERTEX); 469 dump_raw_shader((uint32_t *)(ptr + 32), (sect_size - 32) / 4, i, "vo"); 470 free(ptr); 471 472 for (j = 0; j < vs_hdr->unknown9; j++) { 473 ptr = next_sect(state, §_size); 474 if (full_dump) { 475 printf("######## VS%d CONST?: (size=%d)\n", i, sect_size); 476 dump_hex(ptr, sect_size); 477 } 478 free(ptr); 479 } 480 481 for (j = 0; j < vs_hdr->unknown1 - 1; j++) { 482 free(constants[j]); 483 } 484 485 free(vs_hdr); 486 } 487 488 /* dump fragment shaders: */ 489 for (i = 0; i < 1; i++) { 490 struct fs_header *fs_hdr = next_sect(state, §_size); 491 struct constant *constants[32]; 492 int j, level = 0; 493 494 printf("\n"); 495 496 if (full_dump) { 497 printf("#######################################################\n"); 498 printf("######## FS%d HEADER: (size %d)\n", i, sect_size); 499 dump_hex((void *)fs_hdr, sect_size); 500 } 501 502 for (j = 0; j < fs_hdr->unknown1 - 1; j++) { 503 constants[j] = next_sect(state, §_size); 504 if (full_dump) { 505 printf("######## FS%d CONST: (size=%d)\n", i, sect_size); 506 dump_constant(constants[j]); 507 dump_hex((char *)constants[j], sect_size); 508 } 509 } 510 511 ptr = next_sect(state, §_size); 512 printf("######## FS%d SHADER: (size=%d)\n", i, sect_size); 513 if (full_dump) { 514 dump_hex(ptr, sect_size); 515 level = 1; 516 } else { 517 dump_short_summary(state, fs_hdr->unknown1 - 1, constants); 518 } 519 disasm_a2xx((uint32_t *)(ptr + 32), (sect_size - 32) / 4, level + 1, 520 MESA_SHADER_FRAGMENT); 521 dump_raw_shader((uint32_t *)(ptr + 32), (sect_size - 32) / 4, i, "fo"); 522 free(ptr); 523 524 for (j = 0; j < fs_hdr->unknown1 - 1; j++) { 525 free(constants[j]); 526 } 527 528 free(fs_hdr); 529 } 530} 531 532static void 533dump_shaders_a3xx(struct state *state) 534{ 535 int i, j; 536 537 /* dump vertex shaders: */ 538 for (i = 0; i < 2; i++) { 539 int instrs_size, hdr_size, sect_size, nconsts = 0, level = 0, compact = 0; 540 uint8_t *vs_hdr; 541 struct constant *constants[32]; 542 uint8_t *instrs = NULL; 543 544 vs_hdr = next_sect(state, &hdr_size); 545 printf("hdr_size=%d\n", hdr_size); 546 547 /* seems like there are two cases, either: 548 * 1) 152 byte header, 549 * 2) zero or more 32 byte compiler const sections 550 * 3) followed by shader instructions 551 * or, if there are no compiler consts, this can be 552 * all smashed in one large section 553 */ 554 int n; 555 if (state->hdr->revision >= 0xb) 556 n = 160; 557 else if (state->hdr->revision >= 7) 558 n = 156; 559 else 560 n = 152; 561 if (hdr_size > n) { 562 instrs = &vs_hdr[n]; 563 instrs_size = hdr_size - n; 564 hdr_size = n; 565 compact = 1; 566 } else { 567 while (1) { 568 void *ptr = next_sect(state, §_size); 569 570 if ((sect_size != 32) && (sect_size != 44)) { 571 /* end of constants: */ 572 instrs = ptr; 573 instrs_size = sect_size; 574 break; 575 } 576 dump_hex_ascii(ptr, sect_size, 0); 577 constants[nconsts++] = ptr; 578 } 579 } 580 581 printf("\n"); 582 583 if (full_dump) { 584 printf("#######################################################\n"); 585 printf("######## VS%d HEADER: (size %d)\n", i, hdr_size); 586 dump_hex((void *)vs_hdr, hdr_size); 587 for (j = 0; j < nconsts; j++) { 588 printf("######## VS%d CONST: (size=%d)\n", i, 589 (int)sizeof(constants[i])); 590 dump_constant(constants[j]); 591 dump_hex((char *)constants[j], sizeof(constants[j])); 592 } 593 } 594 595 printf("######## VS%d SHADER: (size=%d)\n", i, instrs_size); 596 if (full_dump) { 597 dump_hex(instrs, instrs_size); 598 level = 1; 599 } else { 600 dump_short_summary(state, nconsts, constants); 601 } 602 603 if (!compact) { 604 if (state->hdr->revision >= 7) { 605 instrs += ALIGN(instrs_size, 8) - instrs_size; 606 instrs_size = ALIGN(instrs_size, 8); 607 } 608 instrs += 32; 609 instrs_size -= 32; 610 } 611 612 disasm_a3xx((uint32_t *)instrs, instrs_size / 4, level + 1, stdout, 613 gpu_id); 614 dump_raw_shader((uint32_t *)instrs, instrs_size / 4, i, "vo3"); 615 free(vs_hdr); 616 } 617 618 /* dump fragment shaders: */ 619 for (i = 0; i < 1; i++) { 620 int instrs_size, hdr_size, sect_size, nconsts = 0, level = 0, compact = 0; 621 uint8_t *fs_hdr; 622 struct constant *constants[32]; 623 uint8_t *instrs = NULL; 624 625 fs_hdr = next_sect(state, &hdr_size); 626 627 printf("hdr_size=%d\n", hdr_size); 628 /* two cases, similar to vertex shader, but magic # is 200 629 * (or 208 for newer?).. 630 */ 631 int n; 632 if (state->hdr->revision >= 0xb) 633 n = 256; 634 else if (state->hdr->revision >= 8) 635 n = 208; 636 else if (state->hdr->revision == 7) 637 n = 204; 638 else 639 n = 200; 640 641 if (hdr_size > n) { 642 instrs = &fs_hdr[n]; 643 instrs_size = hdr_size - n; 644 hdr_size = n; 645 compact = 1; 646 } else { 647 while (1) { 648 void *ptr = next_sect(state, §_size); 649 650 if ((sect_size != 32) && (sect_size != 44)) { 651 /* end of constants: */ 652 instrs = ptr; 653 instrs_size = sect_size; 654 break; 655 } 656 657 dump_hex_ascii(ptr, sect_size, 0); 658 constants[nconsts++] = ptr; 659 } 660 } 661 662 printf("\n"); 663 664 if (full_dump) { 665 printf("#######################################################\n"); 666 printf("######## FS%d HEADER: (size %d)\n", i, hdr_size); 667 dump_hex((void *)fs_hdr, hdr_size); 668 for (j = 0; j < nconsts; j++) { 669 printf("######## FS%d CONST: (size=%d)\n", i, 670 (int)sizeof(constants[i])); 671 dump_constant(constants[j]); 672 dump_hex((char *)constants[j], sizeof(constants[j])); 673 } 674 } 675 676 printf("######## FS%d SHADER: (size=%d)\n", i, instrs_size); 677 if (full_dump) { 678 dump_hex(instrs, instrs_size); 679 level = 1; 680 } else { 681 dump_short_summary(state, nconsts, constants); 682 } 683 684 if (!compact) { 685 if (state->hdr->revision >= 7) { 686 instrs += 44; 687 instrs_size -= 44; 688 } else { 689 instrs += 32; 690 instrs_size -= 32; 691 } 692 } 693 disasm_a3xx((uint32_t *)instrs, instrs_size / 4, level + 1, stdout, 694 gpu_id); 695 dump_raw_shader((uint32_t *)instrs, instrs_size / 4, i, "fo3"); 696 free(fs_hdr); 697 } 698} 699 700static void 701dump_program(struct state *state) 702{ 703 int i, sect_size; 704 uint8_t *ptr; 705 706 state->hdr = next_sect(state, §_size); 707 708 printf("######## HEADER: (size %d)\n", sect_size); 709 printf("\tsize: %d\n", state->hdr->size); 710 printf("\trevision: %d\n", state->hdr->revision); 711 printf("\tattributes: %d\n", state->hdr->num_attribs); 712 printf("\tuniforms: %d\n", state->hdr->num_uniforms); 713 printf("\tsamplers: %d\n", state->hdr->num_samplers); 714 printf("\tvaryings: %d\n", state->hdr->num_varyings); 715 printf("\tuniform blocks: %d\n", state->hdr->num_uniformblocks); 716 if (full_dump) 717 dump_hex((void *)state->hdr, sect_size); 718 printf("\n"); 719 720 /* there seems to be two 0xba5eba11's at the end of the header, possibly 721 * with some other stuff between them: 722 */ 723 ptr = next_sect(state, §_size); 724 if (full_dump) { 725 dump_hex_ascii(ptr, sect_size, 0); 726 } 727 728 for (i = 0; (i < state->hdr->num_attribs) && (state->sz > 0); i++) { 729 state->attribs[i] = next_sect(state, §_size); 730 731 /* hmm, for a3xx (or maybe just newer driver version), we have some 732 * extra sections that don't seem useful, so skip these: 733 */ 734 while (!valid_type(state->attribs[i]->type_info)) { 735 dump_hex_ascii(state->attribs[i], sect_size, 0); 736 state->attribs[i] = next_sect(state, §_size); 737 } 738 739 clean_ascii(state->attribs[i]->name, sect_size - 28); 740 if (full_dump) { 741 printf("######## ATTRIBUTE: (size %d)\n", sect_size); 742 dump_attribute(state->attribs[i]); 743 dump_hex((char *)state->attribs[i], sect_size); 744 } 745 } 746 747 for (i = 0; (i < state->hdr->num_uniforms) && (state->sz > 0); i++) { 748 state->uniforms[i] = next_sect(state, §_size); 749 750 /* hmm, for a3xx (or maybe just newer driver version), we have some 751 * extra sections that don't seem useful, so skip these: 752 */ 753 while (!valid_type(state->uniforms[i]->type_info)) { 754 dump_hex_ascii(state->uniforms[i], sect_size, 0); 755 state->uniforms[i] = next_sect(state, §_size); 756 } 757 758 if (is_uniform_v2(state->uniforms[i])) { 759 clean_ascii(state->uniforms[i]->v2.name, sect_size - 53); 760 } else { 761 clean_ascii(state->uniforms[i]->v1.name, sect_size - 41); 762 } 763 764 if (full_dump) { 765 printf("######## UNIFORM: (size %d)\n", sect_size); 766 dump_uniform(state->uniforms[i]); 767 dump_hex((char *)state->uniforms[i], sect_size); 768 } 769 } 770 771 for (i = 0; (i < state->hdr->num_samplers) && (state->sz > 0); i++) { 772 state->samplers[i] = next_sect(state, §_size); 773 774 /* hmm, for a3xx (or maybe just newer driver version), we have some 775 * extra sections that don't seem useful, so skip these: 776 */ 777 while (!valid_type(state->samplers[i]->type_info)) { 778 dump_hex_ascii(state->samplers[i], sect_size, 0); 779 state->samplers[i] = next_sect(state, §_size); 780 } 781 782 clean_ascii(state->samplers[i]->name, sect_size - 33); 783 if (full_dump) { 784 printf("######## SAMPLER: (size %d)\n", sect_size); 785 dump_sampler(state->samplers[i]); 786 dump_hex((char *)state->samplers[i], sect_size); 787 } 788 } 789 790 // These sections show up after all of the other sampler sections 791 // Loops through them all since we don't deal with them 792 if (state->hdr->revision >= 7) { 793 for (i = 0; (i < state->hdr->num_samplers) && (state->sz > 0); i++) { 794 ptr = next_sect(state, §_size); 795 dump_hex_ascii(ptr, sect_size, 0); 796 } 797 } 798 799 for (i = 0; (i < state->hdr->num_varyings) && (state->sz > 0); i++) { 800 state->varyings[i] = next_sect(state, §_size); 801 802 /* hmm, for a3xx (or maybe just newer driver version), we have some 803 * extra sections that don't seem useful, so skip these: 804 */ 805 while (!valid_type(state->varyings[i]->type_info)) { 806 dump_hex_ascii(state->varyings[i], sect_size, 0); 807 state->varyings[i] = next_sect(state, §_size); 808 } 809 810 clean_ascii(state->varyings[i]->name, sect_size - 16); 811 if (full_dump) { 812 printf("######## VARYING: (size %d)\n", sect_size); 813 dump_varying(state->varyings[i]); 814 dump_hex((char *)state->varyings[i], sect_size); 815 } 816 } 817 818 /* show up again for revision >= 14?? */ 819 if (state->hdr->revision >= 14) { 820 for (i = 0; (i < state->hdr->num_varyings) && (state->sz > 0); i++) { 821 ptr = next_sect(state, §_size); 822 dump_hex_ascii(ptr, sect_size, 0); 823 } 824 } 825 826 /* not sure exactly which revision started this, but seems at least 827 * rev7 and rev8 implicitly include a new section for gl_FragColor: 828 */ 829 if (state->hdr->revision >= 7) { 830 /* I guess only one? */ 831 state->outputs[0] = next_sect(state, §_size); 832 833 clean_ascii(state->outputs[0]->name, sect_size - 32); 834 if (full_dump) { 835 printf("######## OUTPUT: (size %d)\n", sect_size); 836 dump_output(state->outputs[0]); 837 dump_hex((char *)state->outputs[0], sect_size); 838 } 839 } 840 841 for (i = 0; (i < state->hdr->num_uniformblocks) && (state->sz > 0); i++) { 842 state->uniformblocks[i].header = next_sect(state, §_size); 843 844 clean_ascii(state->uniformblocks[i].header->name, sect_size - 40); 845 if (full_dump) { 846 printf("######## UNIFORM BLOCK: (size %d)\n", sect_size); 847 dump_uniformblock(state->uniformblocks[i].header); 848 dump_hex((char *)state->uniformblocks[i].header, sect_size); 849 } 850 851 /* 852 * OpenGL ES 3.0 spec mandates a minimum amount of 16K members supported 853 * a330 supports a minimum of 65K 854 */ 855 state->uniformblocks[i].members = 856 malloc(state->uniformblocks[i].header->num_members * sizeof(void *)); 857 858 int member = 0; 859 for (member = 0; (member < state->uniformblocks[i].header->num_members) && 860 (state->sz > 0); 861 member++) { 862 state->uniformblocks[i].members[member] = next_sect(state, §_size); 863 864 clean_ascii(state->uniformblocks[i].members[member]->name, 865 sect_size - 56); 866 if (full_dump) { 867 printf("######## UNIFORM BLOCK MEMBER: (size %d)\n", sect_size); 868 dump_uniformblockmember(state->uniformblocks[i].members[member]); 869 dump_hex((char *)state->uniformblocks[i].members[member], 870 sect_size); 871 } 872 } 873 /* 874 * Qualcomm saves the UBO members twice for each UBO 875 * Don't ask me why 876 */ 877 for (member = 0; (member < state->uniformblocks[i].header->num_members) && 878 (state->sz > 0); 879 member++) { 880 state->uniformblocks[i].members[member] = next_sect(state, §_size); 881 882 clean_ascii(state->uniformblocks[i].members[member]->name, 883 sect_size - 56); 884 if (full_dump) { 885 printf("######## UNIFORM BLOCK MEMBER2: (size %d)\n", sect_size); 886 dump_uniformblockmember(state->uniformblocks[i].members[member]); 887 dump_hex((char *)state->uniformblocks[i].members[member], 888 sect_size); 889 } 890 } 891 } 892 893 if (gpu_id >= 300) { 894 dump_shaders_a3xx(state); 895 } else { 896 dump_shaders_a2xx(state); 897 } 898 899 if (!full_dump) 900 return; 901 902 /* dump ascii version of shader program: */ 903 ptr = next_sect(state, §_size); 904 printf("\n#######################################################\n"); 905 printf("######## SHADER SRC: (size=%d)\n", sect_size); 906 dump_ascii(ptr, sect_size); 907 free(ptr); 908 909 /* dump remaining sections (there shouldn't be any): */ 910 while (state->sz > 0) { 911 ptr = next_sect(state, §_size); 912 printf("######## section (size=%d)\n", sect_size); 913 printf("as hex:\n"); 914 dump_hex(ptr, sect_size); 915 printf("as float:\n"); 916 dump_float(ptr, sect_size); 917 printf("as ascii:\n"); 918 dump_ascii(ptr, sect_size); 919 free(ptr); 920 } 921 /* cleanup the uniform buffer members we allocated */ 922 if (state->hdr->num_uniformblocks > 0) 923 free(state->uniformblocks[i].members); 924} 925 926int 927main(int argc, char **argv) 928{ 929 enum rd_sect_type type = RD_NONE; 930 enum debug_t debug = PRINT_RAW | PRINT_STATS; 931 void *buf = NULL; 932 int sz; 933 struct io *io; 934 int raw_program = 0; 935 936 /* lame argument parsing: */ 937 938 while (1) { 939 if ((argc > 1) && !strcmp(argv[1], "--verbose")) { 940 debug |= PRINT_RAW | PRINT_VERBOSE; 941 argv++; 942 argc--; 943 continue; 944 } 945 if ((argc > 1) && !strcmp(argv[1], "--expand")) { 946 debug |= EXPAND_REPEAT; 947 argv++; 948 argc--; 949 continue; 950 } 951 if ((argc > 1) && !strcmp(argv[1], "--short")) { 952 /* only short dump, original shader, symbol table, and disassembly */ 953 full_dump = 0; 954 argv++; 955 argc--; 956 continue; 957 } 958 if ((argc > 1) && !strcmp(argv[1], "--dump-shaders")) { 959 dump_shaders = 1; 960 argv++; 961 argc--; 962 continue; 963 } 964 if ((argc > 1) && !strcmp(argv[1], "--raw")) { 965 raw_program = 1; 966 argv++; 967 argc--; 968 continue; 969 } 970 if ((argc > 1) && !strcmp(argv[1], "--gpu300")) { 971 gpu_id = 320; 972 argv++; 973 argc--; 974 continue; 975 } 976 break; 977 } 978 979 if (argc != 2) { 980 fprintf( 981 stderr, 982 "usage: pgmdump [--verbose] [--short] [--dump-shaders] testlog.rd\n"); 983 return -1; 984 } 985 986 disasm_a2xx_set_debug(debug); 987 disasm_a3xx_set_debug(debug); 988 989 infile = argv[1]; 990 991 io = io_open(infile); 992 if (!io) { 993 fprintf(stderr, "could not open: %s\n", infile); 994 return -1; 995 } 996 997 if (raw_program) { 998 io_readn(io, &sz, 4); 999 free(buf); 1000 1001 /* note: allow hex dumps to go a bit past the end of the buffer.. 1002 * might see some garbage, but better than missing the last few bytes.. 1003 */ 1004 buf = calloc(1, sz + 3); 1005 io_readn(io, buf + 4, sz); 1006 (*(int *)buf) = sz; 1007 1008 struct state state = { 1009 .buf = buf, 1010 .sz = sz, 1011 }; 1012 printf("############################################################\n"); 1013 printf("program:\n"); 1014 dump_program(&state); 1015 printf("############################################################\n"); 1016 return 0; 1017 } 1018 1019 /* figure out what sort of input we are dealing with: */ 1020 if (!(check_extension(infile, ".rd") || check_extension(infile, ".rd.gz"))) { 1021 gl_shader_stage shader = ~0; 1022 int ret; 1023 if (check_extension(infile, ".vo")) { 1024 shader = MESA_SHADER_VERTEX; 1025 } else if (check_extension(infile, ".fo")) { 1026 shader = MESA_SHADER_FRAGMENT; 1027 } else if (check_extension(infile, ".vo3")) { 1028 } else if (check_extension(infile, ".fo3")) { 1029 } else if (check_extension(infile, ".co3")) { 1030 } else { 1031 fprintf(stderr, "invalid input file: %s\n", infile); 1032 return -1; 1033 } 1034 buf = calloc(1, 100 * 1024); 1035 ret = io_readn(io, buf, 100 * 1024); 1036 if (ret < 0) { 1037 fprintf(stderr, "error: %m"); 1038 return -1; 1039 } 1040 if (shader != ~0) { 1041 return disasm_a2xx(buf, ret / 4, 0, shader); 1042 } else { 1043 /* disassembly does not depend on shader stage on a3xx+: */ 1044 return disasm_a3xx(buf, ret / 4, 0, stdout, gpu_id); 1045 } 1046 } 1047 1048 while ((io_readn(io, &type, sizeof(type)) > 0) && 1049 (io_readn(io, &sz, 4) > 0)) { 1050 free(buf); 1051 1052 /* note: allow hex dumps to go a bit past the end of the buffer.. 1053 * might see some garbage, but better than missing the last few bytes.. 1054 */ 1055 buf = calloc(1, sz + 3); 1056 io_readn(io, buf, sz); 1057 1058 switch (type) { 1059 case RD_TEST: 1060 if (full_dump) 1061 printf("test: %s\n", (char *)buf); 1062 break; 1063 case RD_VERT_SHADER: 1064 printf("vertex shader:\n%s\n", (char *)buf); 1065 break; 1066 case RD_FRAG_SHADER: 1067 printf("fragment shader:\n%s\n", (char *)buf); 1068 break; 1069 case RD_PROGRAM: { 1070 struct state state = { 1071 .buf = buf, 1072 .sz = sz, 1073 }; 1074 printf( 1075 "############################################################\n"); 1076 printf("program:\n"); 1077 dump_program(&state); 1078 printf( 1079 "############################################################\n"); 1080 break; 1081 } 1082 case RD_GPU_ID: 1083 gpu_id = *((unsigned int *)buf); 1084 printf("gpu_id: %d\n", gpu_id); 1085 break; 1086 default: 1087 break; 1088 } 1089 } 1090 1091 io_close(io); 1092 1093 return 0; 1094} 1095