freedreno: slurp in decode tools
[mesa.git] / src / freedreno / decode / pgmdump.c
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
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
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
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
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
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
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
339 static void dump_sampler(struct sampler *sampler)
340 {
341 printf("\tCONST(%d): %s\n", sampler->const_idx, sampler->name);
342 }
343
344 static void dump_varying(struct varying *varying)
345 {
346 printf("\tR%d: %s\n", varying->reg, varying->name);
347 }
348
349 static void dump_uniformblock(struct uniformblock *uniformblock)
350 {
351 printf("\tUniform Block: %s(%d)\n", uniformblock->name, uniformblock->num_members);
352 }
353
354 static void dump_uniformblockmember(struct uniformblockmember *member)
355 {
356 printf("Uniform Block member: %s\n", member->name);
357 }
358
359 static void dump_output(struct output *output)
360 {
361 printf("\tR?: %s\n", output->name);
362 }
363
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: */
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
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 write(fd, dwords, sizedwords * 4);
409 }
410
411 static void dump_shaders_a2xx(struct state *state)
412 {
413 int i, sect_size;
414 uint8_t *ptr;
415
416 /* dump vertex shaders: */
417 for (i = 0; i < 3; i++) {
418 struct vs_header *vs_hdr = next_sect(state, &sect_size);
419 struct constant *constants[32];
420 int j, level = 0;
421
422 printf("\n");
423
424 if (full_dump) {
425 printf("#######################################################\n");
426 printf("######## VS%d HEADER: (size %d)\n", i, sect_size);
427 dump_hex((void *)vs_hdr, sect_size);
428 }
429
430 for (j = 0; j < (int)vs_hdr->unknown1 - 1; j++) {
431 constants[j] = next_sect(state, &sect_size);
432 if (full_dump) {
433 printf("######## VS%d CONST: (size=%d)\n", i, sect_size);
434 dump_constant(constants[j]);
435 dump_hex((char *)constants[j], sect_size);
436 }
437 }
438
439 ptr = next_sect(state, &sect_size);
440 printf("######## VS%d SHADER: (size=%d)\n", i, sect_size);
441 if (full_dump) {
442 dump_hex(ptr, sect_size);
443 level = 1;
444 } else {
445 dump_short_summary(state, vs_hdr->unknown1 - 1, constants);
446 }
447 disasm_a2xx((uint32_t *)(ptr + 32), (sect_size - 32) / 4, level+1, SHADER_VERTEX);
448 dump_raw_shader((uint32_t *)(ptr + 32), (sect_size - 32) / 4, i, "vo");
449 free(ptr);
450
451 for (j = 0; j < vs_hdr->unknown9; j++) {
452 ptr = next_sect(state, &sect_size);
453 if (full_dump) {
454 printf("######## VS%d CONST?: (size=%d)\n", i, sect_size);
455 dump_hex(ptr, sect_size);
456 }
457 free(ptr);
458 }
459
460 for (j = 0; j < vs_hdr->unknown1 - 1; j++) {
461 free(constants[j]);
462 }
463
464 free(vs_hdr);
465 }
466
467 /* dump fragment shaders: */
468 for (i = 0; i < 1; i++) {
469 struct fs_header *fs_hdr = next_sect(state, &sect_size);
470 struct constant *constants[32];
471 int j, level = 0;
472
473 printf("\n");
474
475 if (full_dump) {
476 printf("#######################################################\n");
477 printf("######## FS%d HEADER: (size %d)\n", i, sect_size);
478 dump_hex((void *)fs_hdr, sect_size);
479 }
480
481 for (j = 0; j < fs_hdr->unknown1 - 1; j++) {
482 constants[j] = next_sect(state, &sect_size);
483 if (full_dump) {
484 printf("######## FS%d CONST: (size=%d)\n", i, sect_size);
485 dump_constant(constants[j]);
486 dump_hex((char *)constants[j], sect_size);
487 }
488 }
489
490 ptr = next_sect(state, &sect_size);
491 printf("######## FS%d SHADER: (size=%d)\n", i, sect_size);
492 if (full_dump) {
493 dump_hex(ptr, sect_size);
494 level = 1;
495 } else {
496 dump_short_summary(state, fs_hdr->unknown1 - 1, constants);
497 }
498 disasm_a2xx((uint32_t *)(ptr + 32), (sect_size - 32) / 4, level+1, SHADER_FRAGMENT);
499 dump_raw_shader((uint32_t *)(ptr + 32), (sect_size - 32) / 4, i, "fo");
500 free(ptr);
501
502 for (j = 0; j < fs_hdr->unknown1 - 1; j++) {
503 free(constants[j]);
504 }
505
506 free(fs_hdr);
507 }
508 }
509
510 static void dump_shaders_a3xx(struct state *state)
511 {
512 int i, j;
513
514 /* dump vertex shaders: */
515 for (i = 0; i < 2; i++) {
516 int instrs_size, hdr_size, sect_size, nconsts = 0, level = 0, compact = 0;
517 uint8_t *vs_hdr;
518 struct constant *constants[32];
519 uint8_t *instrs = NULL;
520
521 vs_hdr = next_sect(state, &hdr_size);
522 printf("hdr_size=%d\n", hdr_size);
523
524 /* seems like there are two cases, either:
525 * 1) 152 byte header,
526 * 2) zero or more 32 byte compiler const sections
527 * 3) followed by shader instructions
528 * or, if there are no compiler consts, this can be
529 * all smashed in one large section
530 */
531 int n;
532 if (state->hdr->revision >= 0xb)
533 n = 160;
534 else if (state->hdr->revision >= 7)
535 n = 156;
536 else
537 n = 152;
538 if (hdr_size > n) {
539 instrs = &vs_hdr[n];
540 instrs_size = hdr_size - n;
541 hdr_size = n;
542 compact = 1;
543 } else {
544 while (1) {
545 void *ptr = next_sect(state, &sect_size);
546
547 if ((sect_size != 32) && (sect_size != 44)) {
548 /* end of constants: */
549 instrs = ptr;
550 instrs_size = sect_size;
551 break;
552 }
553 dump_hex_ascii(ptr, sect_size, 0);
554 constants[nconsts++] = ptr;
555 }
556 }
557
558 printf("\n");
559
560 if (full_dump) {
561 printf("#######################################################\n");
562 printf("######## VS%d HEADER: (size %d)\n", i, hdr_size);
563 dump_hex((void *)vs_hdr, hdr_size);
564 for (j = 0; j < nconsts; j++) {
565 printf("######## VS%d CONST: (size=%d)\n", i, (int)sizeof(constants[i]));
566 dump_constant(constants[j]);
567 dump_hex((char *)constants[j], sizeof(constants[j]));
568 }
569 }
570
571 printf("######## VS%d SHADER: (size=%d)\n", i, instrs_size);
572 if (full_dump) {
573 dump_hex(instrs, instrs_size);
574 level = 1;
575 } else {
576 dump_short_summary(state, nconsts, constants);
577 }
578
579 if (!compact) {
580 if (state->hdr->revision >= 7) {
581 instrs += ALIGN(instrs_size, 8) - instrs_size;
582 instrs_size = ALIGN(instrs_size, 8);
583 }
584 instrs += 32;
585 instrs_size -= 32;
586 }
587
588 disasm_a3xx((uint32_t *)instrs, instrs_size / 4, level+1, SHADER_VERTEX, gpu_id);
589 dump_raw_shader((uint32_t *)instrs, instrs_size / 4, i, "vo3");
590 free(vs_hdr);
591 }
592
593 /* dump fragment shaders: */
594 for (i = 0; i < 1; i++) {
595 int instrs_size, hdr_size, sect_size, nconsts = 0, level = 0, compact = 0;
596 uint8_t *fs_hdr;
597 struct constant *constants[32];
598 uint8_t *instrs = NULL;
599
600 fs_hdr = next_sect(state, &hdr_size);
601
602 printf("hdr_size=%d\n", hdr_size);
603 /* two cases, similar to vertex shader, but magic # is 200
604 * (or 208 for newer?)..
605 */
606 int n;
607 if (state->hdr->revision >= 0xb)
608 n = 256;
609 else if (state->hdr->revision >= 8)
610 n = 208;
611 else if (state->hdr->revision == 7)
612 n = 204;
613 else
614 n = 200;
615
616 if (hdr_size > n) {
617 instrs = &fs_hdr[n];
618 instrs_size = hdr_size - n;
619 hdr_size = n;
620 compact = 1;
621 } else {
622 while (1) {
623 void *ptr = next_sect(state, &sect_size);
624
625 if ((sect_size != 32) && (sect_size != 44)) {
626 /* end of constants: */
627 instrs = ptr;
628 instrs_size = sect_size;
629 break;
630 }
631
632 dump_hex_ascii(ptr, sect_size, 0);
633 constants[nconsts++] = ptr;
634 }
635 }
636
637 printf("\n");
638
639 if (full_dump) {
640 printf("#######################################################\n");
641 printf("######## FS%d HEADER: (size %d)\n", i, hdr_size);
642 dump_hex((void *)fs_hdr, hdr_size);
643 for (j = 0; j < nconsts; j++) {
644 printf("######## FS%d CONST: (size=%d)\n", i, (int)sizeof(constants[i]));
645 dump_constant(constants[j]);
646 dump_hex((char *)constants[j], sizeof(constants[j]));
647 }
648 }
649
650 printf("######## FS%d SHADER: (size=%d)\n", i, instrs_size);
651 if (full_dump) {
652 dump_hex(instrs, instrs_size);
653 level = 1;
654 } else {
655 dump_short_summary(state, nconsts, constants);
656 }
657
658 if (!compact) {
659 if (state->hdr->revision >= 7) {
660 instrs += 44;
661 instrs_size -= 44;
662 } else {
663 instrs += 32;
664 instrs_size -= 32;
665 }
666 }
667 disasm_a3xx((uint32_t *)instrs, instrs_size / 4, level+1, stdout, gpu_id);
668 dump_raw_shader((uint32_t *)instrs, instrs_size / 4, i, "fo3");
669 free(fs_hdr);
670 }
671 }
672
673 static void dump_program(struct state *state)
674 {
675 int i, sect_size;
676 uint8_t *ptr;
677
678 state->hdr = next_sect(state, &sect_size);
679
680 printf("######## HEADER: (size %d)\n", sect_size);
681 printf("\tsize: %d\n", state->hdr->size);
682 printf("\trevision: %d\n", state->hdr->revision);
683 printf("\tattributes: %d\n", state->hdr->num_attribs);
684 printf("\tuniforms: %d\n", state->hdr->num_uniforms);
685 printf("\tsamplers: %d\n", state->hdr->num_samplers);
686 printf("\tvaryings: %d\n", state->hdr->num_varyings);
687 printf("\tuniform blocks: %d\n", state->hdr->num_uniformblocks);
688 if (full_dump)
689 dump_hex((void *)state->hdr, sect_size);
690 printf("\n");
691
692 /* there seems to be two 0xba5eba11's at the end of the header, possibly
693 * with some other stuff between them:
694 */
695 ptr = next_sect(state, &sect_size);
696 if (full_dump) {
697 dump_hex_ascii(ptr, sect_size, 0);
698 }
699
700 for (i = 0; (i < state->hdr->num_attribs) && (state->sz > 0); i++) {
701 state->attribs[i] = next_sect(state, &sect_size);
702
703 /* hmm, for a3xx (or maybe just newer driver version), we have some
704 * extra sections that don't seem useful, so skip these:
705 */
706 while (!valid_type(state->attribs[i]->type_info)) {
707 dump_hex_ascii(state->attribs[i], sect_size, 0);
708 state->attribs[i] = next_sect(state, &sect_size);
709 }
710
711 clean_ascii(state->attribs[i]->name, sect_size - 28);
712 if (full_dump) {
713 printf("######## ATTRIBUTE: (size %d)\n", sect_size);
714 dump_attribute(state->attribs[i]);
715 dump_hex((char *)state->attribs[i], sect_size);
716 }
717 }
718
719 for (i = 0; (i < state->hdr->num_uniforms) && (state->sz > 0); i++) {
720 state->uniforms[i] = next_sect(state, &sect_size);
721
722 /* hmm, for a3xx (or maybe just newer driver version), we have some
723 * extra sections that don't seem useful, so skip these:
724 */
725 while (!valid_type(state->uniforms[i]->type_info)) {
726 dump_hex_ascii(state->uniforms[i], sect_size, 0);
727 state->uniforms[i] = next_sect(state, &sect_size);
728 }
729
730 if (is_uniform_v2(state->uniforms[i])) {
731 clean_ascii(state->uniforms[i]->v2.name, sect_size - 53);
732 } else {
733 clean_ascii(state->uniforms[i]->v1.name, sect_size - 41);
734 }
735
736 if (full_dump) {
737 printf("######## UNIFORM: (size %d)\n", sect_size);
738 dump_uniform(state->uniforms[i]);
739 dump_hex((char *)state->uniforms[i], sect_size);
740 }
741 }
742
743 for (i = 0; (i < state->hdr->num_samplers) && (state->sz > 0); i++) {
744 state->samplers[i] = next_sect(state, &sect_size);
745
746 /* hmm, for a3xx (or maybe just newer driver version), we have some
747 * extra sections that don't seem useful, so skip these:
748 */
749 while (!valid_type(state->samplers[i]->type_info)) {
750 dump_hex_ascii(state->samplers[i], sect_size, 0);
751 state->samplers[i] = next_sect(state, &sect_size);
752 }
753
754 clean_ascii(state->samplers[i]->name, sect_size - 33);
755 if (full_dump) {
756 printf("######## SAMPLER: (size %d)\n", sect_size);
757 dump_sampler(state->samplers[i]);
758 dump_hex((char *)state->samplers[i], sect_size);
759 }
760
761 }
762
763 // These sections show up after all of the other sampler sections
764 // Loops through them all since we don't deal with them
765 if (state->hdr->revision >= 7) {
766 for (i = 0; (i < state->hdr->num_samplers) && (state->sz > 0); i++) {
767 ptr = next_sect(state, &sect_size);
768 dump_hex_ascii(ptr, sect_size, 0);
769 }
770 }
771
772
773 for (i = 0; (i < state->hdr->num_varyings) && (state->sz > 0); i++) {
774 state->varyings[i] = next_sect(state, &sect_size);
775
776 /* hmm, for a3xx (or maybe just newer driver version), we have some
777 * extra sections that don't seem useful, so skip these:
778 */
779 while (!valid_type(state->varyings[i]->type_info)) {
780 dump_hex_ascii(state->varyings[i], sect_size, 0);
781 state->varyings[i] = next_sect(state, &sect_size);
782 }
783
784 clean_ascii(state->varyings[i]->name, sect_size - 16);
785 if (full_dump) {
786 printf("######## VARYING: (size %d)\n", sect_size);
787 dump_varying(state->varyings[i]);
788 dump_hex((char *)state->varyings[i], sect_size);
789 }
790 }
791
792 /* show up again for revision >= 14?? */
793 if (state->hdr->revision >= 14) {
794 for (i = 0; (i < state->hdr->num_varyings) && (state->sz > 0); i++) {
795 ptr = next_sect(state, &sect_size);
796 dump_hex_ascii(ptr, sect_size, 0);
797 }
798 }
799
800 /* not sure exactly which revision started this, but seems at least
801 * rev7 and rev8 implicitly include a new section for gl_FragColor:
802 */
803 if (state->hdr->revision >= 7) {
804 /* I guess only one? */
805 state->outputs[0] = next_sect(state, &sect_size);
806
807 clean_ascii(state->outputs[0]->name, sect_size - 32);
808 if (full_dump) {
809 printf("######## OUTPUT: (size %d)\n", sect_size);
810 dump_output(state->outputs[0]);
811 dump_hex((char *)state->outputs[0], sect_size);
812 }
813 }
814
815 for (i = 0; (i < state->hdr->num_uniformblocks) && (state->sz > 0); i++) {
816 state->uniformblocks[i].header = next_sect(state, &sect_size);
817
818 clean_ascii(state->uniformblocks[i].header->name, sect_size - 40);
819 if (full_dump) {
820 printf("######## UNIFORM BLOCK: (size %d)\n", sect_size);
821 dump_uniformblock(state->uniformblocks[i].header);
822 dump_hex((char *)state->uniformblocks[i].header, sect_size);
823 }
824
825 /*
826 * OpenGL ES 3.0 spec mandates a minimum amount of 16K members supported
827 * a330 supports a minimum of 65K
828 */
829 state->uniformblocks[i].members = malloc(state->uniformblocks[i].header->num_members * sizeof(void*));
830
831 int member = 0;
832 for (member = 0; (member < state->uniformblocks[i].header->num_members) && (state->sz > 0); member++) {
833 state->uniformblocks[i].members[member] = next_sect(state, &sect_size);
834
835 clean_ascii(state->uniformblocks[i].members[member]->name, sect_size - 56);
836 if (full_dump) {
837 printf("######## UNIFORM BLOCK MEMBER: (size %d)\n", sect_size);
838 dump_uniformblockmember(state->uniformblocks[i].members[member]);
839 dump_hex((char *)state->uniformblocks[i].members[member], sect_size);
840 }
841 }
842 /*
843 * Qualcomm saves the UBO members twice for each UBO
844 * Don't ask me why
845 */
846 for (member = 0; (member < state->uniformblocks[i].header->num_members) && (state->sz > 0); member++) {
847 state->uniformblocks[i].members[member] = next_sect(state, &sect_size);
848
849 clean_ascii(state->uniformblocks[i].members[member]->name, sect_size - 56);
850 if (full_dump) {
851 printf("######## UNIFORM BLOCK MEMBER2: (size %d)\n", sect_size);
852 dump_uniformblockmember(state->uniformblocks[i].members[member]);
853 dump_hex((char *)state->uniformblocks[i].members[member], sect_size);
854 }
855 }
856 }
857
858 if (gpu_id >= 300) {
859 dump_shaders_a3xx(state);
860 } else {
861 dump_shaders_a2xx(state);
862 }
863
864 if (!full_dump)
865 return;
866
867 /* dump ascii version of shader program: */
868 ptr = next_sect(state, &sect_size);
869 printf("\n#######################################################\n");
870 printf("######## SHADER SRC: (size=%d)\n", sect_size);
871 dump_ascii(ptr, sect_size);
872 free(ptr);
873
874 /* dump remaining sections (there shouldn't be any): */
875 while (state->sz > 0) {
876 ptr = next_sect(state, &sect_size);
877 printf("######## section (size=%d)\n", sect_size);
878 printf("as hex:\n");
879 dump_hex(ptr, sect_size);
880 printf("as float:\n");
881 dump_float(ptr, sect_size);
882 printf("as ascii:\n");
883 dump_ascii(ptr, sect_size);
884 free(ptr);
885 }
886 /* cleanup the uniform buffer members we allocated */
887 if (state->hdr->num_uniformblocks > 0)
888 free (state->uniformblocks[i].members);
889 }
890
891 int main(int argc, char **argv)
892 {
893 enum rd_sect_type type = RD_NONE;
894 enum debug_t debug = 0;
895 void *buf = NULL;
896 int sz;
897 struct io *io;
898 int raw_program = 0;
899
900 /* lame argument parsing: */
901
902 while (1) {
903 if ((argc > 1) && !strcmp(argv[1], "--verbose")) {
904 debug |= PRINT_RAW | PRINT_VERBOSE;
905 argv++;
906 argc--;
907 continue;
908 }
909 if ((argc > 1) && !strcmp(argv[1], "--expand")) {
910 debug |= EXPAND_REPEAT;
911 argv++;
912 argc--;
913 continue;
914 }
915 if ((argc > 1) && !strcmp(argv[1], "--short")) {
916 /* only short dump, original shader, symbol table, and disassembly */
917 full_dump = 0;
918 argv++;
919 argc--;
920 continue;
921 }
922 if ((argc > 1) && !strcmp(argv[1], "--dump-shaders")) {
923 dump_shaders = 1;
924 argv++;
925 argc--;
926 continue;
927 }
928 if ((argc > 1) && !strcmp(argv[1], "--raw")) {
929 raw_program = 1;
930 argv++;
931 argc--;
932 continue;
933 }
934 if ((argc > 1) && !strcmp(argv[1], "--gpu300")) {
935 gpu_id = 320;
936 argv++;
937 argc--;
938 continue;
939 }
940 break;
941 }
942
943 if (argc != 2) {
944 fprintf(stderr, "usage: pgmdump [--verbose] [--short] [--dump-shaders] testlog.rd\n");
945 return -1;
946 }
947
948 disasm_set_debug(debug);
949
950 infile = argv[1];
951
952 io = io_open(infile);
953 if (!io) {
954 fprintf(stderr, "could not open: %s\n", infile);
955 return -1;
956 }
957
958 if (raw_program)
959 {
960 io_readn(io, &sz, 4);
961 free(buf);
962
963 /* note: allow hex dumps to go a bit past the end of the buffer..
964 * might see some garbage, but better than missing the last few bytes..
965 */
966 buf = calloc(1, sz + 3);
967 io_readn(io, buf + 4, sz);
968 (*(int*)buf) = sz;
969
970 struct state state = {
971 .buf = buf,
972 .sz = sz,
973 };
974 printf("############################################################\n");
975 printf("program:\n");
976 dump_program(&state);
977 printf("############################################################\n");
978 return 0;
979 }
980
981 /* figure out what sort of input we are dealing with: */
982 if (!(check_extension(infile, ".rd") || check_extension(infile, ".rd.gz"))) {
983 enum shader_t shader = ~0;
984 int ret;
985 if (check_extension(infile, ".vo")) {
986 shader = SHADER_VERTEX;
987 } else if (check_extension(infile, ".fo")) {
988 shader = SHADER_FRAGMENT;
989 } else if (check_extension(infile, ".vo3")) {
990 } else if (check_extension(infile, ".fo3")) {
991 } else if (check_extension(infile, ".co3")) {
992 } else {
993 fprintf(stderr, "invalid input file: %s\n", infile);
994 return -1;
995 }
996 buf = calloc(1, 100 * 1024);
997 ret = io_readn(io, buf, 100 * 1024);
998 if (ret < 0) {
999 fprintf(stderr, "error: %m");
1000 return -1;
1001 }
1002 if (shader != ~0) {
1003 return disasm_a2xx(buf, ret/4, 0, shader);
1004 } else {
1005 /* disassembly does not depend on shader stage on a3xx+: */
1006 return disasm_a3xx(buf, ret/4, 0, stdout, gpu_id);
1007 }
1008 }
1009
1010 while ((io_readn(io, &type, sizeof(type)) > 0) && (io_readn(io, &sz, 4) > 0)) {
1011 free(buf);
1012
1013 /* note: allow hex dumps to go a bit past the end of the buffer..
1014 * might see some garbage, but better than missing the last few bytes..
1015 */
1016 buf = calloc(1, sz + 3);
1017 io_readn(io, buf, sz);
1018
1019 switch(type) {
1020 case RD_TEST:
1021 if (full_dump)
1022 printf("test: %s\n", (char *)buf);
1023 break;
1024 case RD_VERT_SHADER:
1025 printf("vertex shader:\n%s\n", (char *)buf);
1026 break;
1027 case RD_FRAG_SHADER:
1028 printf("fragment shader:\n%s\n", (char *)buf);
1029 break;
1030 case RD_PROGRAM: {
1031 struct state state = {
1032 .buf = buf,
1033 .sz = sz,
1034 };
1035 printf("############################################################\n");
1036 printf("program:\n");
1037 dump_program(&state);
1038 printf("############################################################\n");
1039 break;
1040 }
1041 case RD_GPU_ID:
1042 gpu_id = *((unsigned int *)buf);
1043 printf("gpu_id: %d\n", gpu_id);
1044 break;
1045 default:
1046 break;
1047 }
1048 }
1049
1050 io_close(io);
1051
1052 return 0;
1053 }
1054