7fec7dcbd10acc146f82e6e56b9cb5a8cb89c400
2 * Copyright (c) 2012 Rob Clark <robdclark@gmail.com>
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:
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
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
34 #include <sys/types.h>
52 static struct cffdec_options options
= {
56 static bool needs_wfi
= false;
57 static bool is_blob
= false;
58 static int show_comp
= false;
59 static int interactive
;
62 static int handle_file(const char *filename
, int start
, int end
, int draw
);
64 static void print_usage(const char *name
)
66 fprintf(stderr
, "Usage:\n\n"
67 "\t%s [OPTSIONS]... FILE...\n\n"
69 "\t-v, --verbose - more verbose disassembly\n"
70 "\t--dump-shaders - dump each shader to a raw file\n"
71 "\t--no-color - disable colorized output (default for non-console\n"
73 "\t--color - enable colorized output (default for tty output)\n"
74 "\t--no-pager - disable pager (default for non-console output)\n"
75 "\t--pager - enable pager (default for tty output)\n"
76 "\t-s, --summary - don't show individual register writes, but just\n"
77 "\t register values on draws\n"
78 "\t-a, --allregs - show all registers (including ones not written\n"
79 "\t since previous draw) on each draw\n"
80 "\t-S, --start=N - start decoding from frame N\n"
81 "\t-E, --end=N - stop decoding after frame N\n"
82 "\t-F, --frame=N - decode only frame N\n"
83 "\t-D, --draw=N - decode only draw N\n"
84 "\t--textures - dump texture contents (if possible)\n"
85 "\t-L, --script=LUA - run specified lua script to analyze state\n"
86 "\t-q, --query=REG - query mode, dump only specified query registers on\n"
87 "\t each draw; multiple --query/-q args can be given to\n"
88 "\t dump multiple registers; register can be specified\n"
89 "\t either by name or numeric offset\n"
90 "\t--query-all - in query mode, show all queried regs on each draw\n"
91 "\t (default query mode)\n"
92 "\t--query-written - in query mode, show queried regs on draws if any of\n"
93 "\t them have been written since previous draw\n"
94 "\t--query-delta - in query mode, show queried regs on draws if any of\n"
95 "\t them have changed since previous draw\n"
96 "\t--query-compare - dump registers for BINNING vs GMEM/BYPASS per draw;\n"
97 "\t only applicable for regs set via SDS group (a6xx+),\n"
98 "\t implies --once, can be combined with --query-all,\n"
99 "\t --query-written, or --query-delta\n"
100 "\t--once - decode cmdstream only once (per draw mode); if same\n"
101 "\t cmdstream is executed for each tile, this will decode\n"
102 "\t it only for the first tile and skip the remainder,\n"
103 "\t which can be useful when looking at state that does\n"
104 "\t not change per tile\n"
105 "\t--not-once - decode cmdstream for each IB (default)\n"
106 "\t-h, --help - show this message\n"
111 static const struct option opts
[] = {
112 /* Long opts that simply set a flag (no corresponding short alias: */
113 { "dump-shaders", no_argument
, &options
.dump_shaders
, 1 },
114 { "no-color", no_argument
, &options
.color
, 0 },
115 { "color", no_argument
, &options
.color
, 1 },
116 { "no-pager", no_argument
, &interactive
, 0 },
117 { "pager", no_argument
, &interactive
, 1 },
118 { "textures", no_argument
, &options
.dump_textures
, 1 },
119 { "show-compositor", no_argument
, &show_comp
, 1 },
120 { "query-all", no_argument
, &options
.query_mode
, QUERY_ALL
},
121 { "query-written", no_argument
, &options
.query_mode
, QUERY_WRITTEN
},
122 { "query-delta", no_argument
, &options
.query_mode
, QUERY_DELTA
},
123 { "query-compare", no_argument
, &options
.query_compare
, 1 },
124 { "once", no_argument
, &options
.once
, 1 },
125 { "not-once", no_argument
, &options
.once
, 0 },
127 /* Long opts with short alias: */
128 { "verbose", no_argument
, 0, 'v' },
129 { "summary", no_argument
, 0, 's' },
130 { "allregs", no_argument
, 0, 'a' },
131 { "start", required_argument
, 0, 'S' },
132 { "end", required_argument
, 0, 'E' },
133 { "frame", required_argument
, 0, 'F' },
134 { "draw", required_argument
, 0, 'D' },
135 { "script", required_argument
, 0, 'L' },
136 { "query", required_argument
, 0, 'q' },
137 { "help", no_argument
, 0, 'h' },
140 int main(int argc
, char **argv
)
143 int start
= 0, end
= 0x7ffffff, draw
= -1;
146 interactive
= isatty(STDOUT_FILENO
);
148 options
.color
= interactive
;
150 while ((c
= getopt_long(argc
, argv
, "vsaS:E:F:D:L:q:h", opts
, NULL
)) != -1) {
153 /* option that set a flag, nothing to do */
156 disasm_set_debug(PRINT_RAW
| EXPAND_REPEAT
| PRINT_VERBOSE
);
159 options
.summary
= true;
162 options
.allregs
= true;
165 start
= atoi(optarg
);
171 start
= end
= atoi(optarg
);
177 options
.script
= optarg
;
178 if (script_load(options
.script
)) {
179 errx(-1, "error loading %s\n", options
.script
);
183 options
.querystrs
= realloc(options
.querystrs
,
184 (options
.nquery
+ 1) * sizeof(*options
.querystrs
));
185 options
.querystrs
[options
.nquery
] = optarg
;
191 print_usage(argv
[0]);
199 while (optind
< argc
) {
200 ret
= handle_file(argv
[optind
], start
, end
, draw
);
202 fprintf(stderr
, "error reading: %s\n", argv
[optind
]);
203 fprintf(stderr
, "continuing..\n");
209 print_usage(argv
[0]);
211 if ((options
.query_mode
|| options
.query_compare
) && !options
.nquery
) {
212 fprintf(stderr
, "query options only valid in query mode!\n");
213 print_usage(argv
[0]);
225 static void parse_addr(uint32_t *buf
, int sz
, unsigned int *len
, uint64_t *gpuaddr
)
230 *gpuaddr
|= ((uint64_t)(buf
[2])) << 32;
233 static int handle_file(const char *filename
, int start
, int end
, int draw
)
235 enum rd_sect_type type
= RD_NONE
;
238 int submit
= 0, got_gpu_id
= 0;
240 bool needs_reset
= false;
243 options
.draw_filter
= draw
;
245 cffdec_init(&options
);
247 printf("Reading %s...\n", filename
);
249 script_start_cmdstream(filename
);
251 if (!strcmp(filename
, "-"))
254 io
= io_open(filename
);
257 fprintf(stderr
, "could not open: %s\n", filename
);
269 ret
= io_readn(io
, arr
, 8);
273 while ((arr
[0] == 0xffffffff) && (arr
[1] == 0xffffffff)) {
274 ret
= io_readn(io
, arr
, 8);
291 buf
= malloc(sz
+ 1);
292 ((char *)buf
)[sz
] = '\0';
293 ret
= io_readn(io
, buf
, sz
);
299 printl(1, "test: %s\n", (char *)buf
);
303 printl(2, "cmd: %s\n", (char *)buf
);
306 skip
|= (strstr(buf
, "fdperf") == buf
);
307 skip
|= (strstr(buf
, "chrome") == buf
);
308 skip
|= (strstr(buf
, "surfaceflinger") == buf
);
309 skip
|= ((char *)buf
)[0] == 'X';
313 printl(2, "vertex shader:\n%s\n", (char *)buf
);
316 printl(2, "fragment shader:\n%s\n", (char *)buf
);
323 parse_addr(buf
, sz
, &gpuaddr
.len
, &gpuaddr
.gpuaddr
);
325 case RD_BUFFER_CONTENTS
:
326 add_buffer(gpuaddr
.gpuaddr
, gpuaddr
.len
, buf
);
329 case RD_CMDSTREAM_ADDR
:
330 if ((start
<= submit
) && (submit
<= end
)) {
331 unsigned int sizedwords
;
333 parse_addr(buf
, sz
, &sizedwords
, &gpuaddr
);
334 printl(2, "############################################################\n");
335 printl(2, "cmdstream: %d dwords\n", sizedwords
);
337 script_start_submit();
338 dump_commands(hostptr(gpuaddr
), sizedwords
, 0);
341 printl(2, "############################################################\n");
342 printl(2, "vertices: %d\n", vertices
);
349 options
.gpu_id
= *((unsigned int *)buf
);
350 printl(2, "gpu_id: %d\n", options
.gpu_id
);
351 cffdec_init(&options
);
361 script_end_cmdstream();
367 printf("corrupt file\n");