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