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
40 struct 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
57 struct 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
69 struct 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 */
123 struct 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
134 struct 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
159 struct 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
179 struct 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
193 struct 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
205 struct 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
213 struct 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
225 struct constant {
226 uint32_t unknown1;
227 uint32_t unknown2;
228 uint32_t unknown3;
229 uint32_t const_idx;
230 float val[];
231 };
232
233 struct 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
249 static const char *infile;
250 static int full_dump = 1;
251 static int dump_shaders = 0;
252 static int gpu_id;
253
254 static char *
find_sect_end(char * buf,int sz)255 find_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
277 static void *
next_sect(struct state * state,int * sect_size)278 next_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
298 static int
valid_type(uint32_t type_info)299 valid_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
312 static int valid_uniformblock(uint32_t type_info)
313 {
314 if (type_info == 0x128)
315 return 1;
316 return 0;
317 }
318 #endif
319
320 static void
dump_attribute(struct attribute * attrib)321 dump_attribute(struct attribute *attrib)
322 {
323 printf("\tR%d, CONST(%d): %s\n", attrib->reg, attrib->const_idx,
324 attrib->name);
325 }
326
327 static inline int
is_uniform_v2(struct uniform * uniform)328 is_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
336 static void
dump_uniform(struct uniform * uniform)337 dump_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
347 static void
dump_sampler(struct sampler * sampler)348 dump_sampler(struct sampler *sampler)
349 {
350 printf("\tCONST(%d): %s\n", sampler->const_idx, sampler->name);
351 }
352
353 static void
dump_varying(struct varying * varying)354 dump_varying(struct varying *varying)
355 {
356 printf("\tR%d: %s\n", varying->reg, varying->name);
357 }
358
359 static void
dump_uniformblock(struct uniformblock * uniformblock)360 dump_uniformblock(struct uniformblock *uniformblock)
361 {
362 printf("\tUniform Block: %s(%d)\n", uniformblock->name,
363 uniformblock->num_members);
364 }
365
366 static void
dump_uniformblockmember(struct uniformblockmember * member)367 dump_uniformblockmember(struct uniformblockmember *member)
368 {
369 printf("Uniform Block member: %s\n", member->name);
370 }
371
372 static void
dump_output(struct output * output)373 dump_output(struct output *output)
374 {
375 printf("\tR?: %s\n", output->name);
376 }
377
378 static void
dump_constant(struct constant * constant)379 dump_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: */
386 static void
dump_short_summary(struct state * state,int nconsts,struct constant ** constants)387 dump_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
413 static void
dump_raw_shader(uint32_t * dwords,uint32_t sizedwords,int n,char * ext)414 dump_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
430 static void
dump_shaders_a2xx(struct state * state)431 dump_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
532 static void
dump_shaders_a3xx(struct state * state)533 dump_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
700 static void
dump_program(struct state * state)701 dump_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
926 int
main(int argc,char ** argv)927 main(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