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