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, &sect_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, &sect_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, &sect_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, &sect_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, &sect_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, &sect_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, &sect_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, &sect_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, &sect_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, &sect_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, &sect_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, &sect_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, &sect_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, &sect_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, &sect_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, &sect_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, &sect_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, &sect_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, &sect_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, &sect_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, &sect_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, &sect_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, &sect_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, &sect_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, &sect_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, &sect_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, &sect_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