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