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