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