1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
|
#!/usr/bin/env python3
import re
import sys
import gzip
import io
class GMEMPass:
def __init__(self):
self.cleared = None
self.gmem_reason = None
self.num_draws = None
self.samples = None
self.width = None
self.height = None
self.nbinx = None
self.nbiny = None
self.formats = [] # format per MRT + zsbuf
self.lrz_clear_time = 0
self.binning_time = 0
self.restore_clear_time = 0
self.draw_time = 0
self.resolve_time = 0
self.elapsed_time = 0
def dump_gmem_passes(gmem_passes, blit_time, sysmem_time, total_time):
i = 0
lrz_clear_time = 0
binning_time = 0
restore_clear_time = 0
draw_time = 0
resolve_time = 0
elapsed_time = 0
for gmem in gmem_passes:
print(" GMEM[{}]: {}x{} ({}x{} tiles), {} draws, lrz clear: {:,} ns, binning: {:,} ns, restore/clear: {:,} ns, draw: {:,} ns, resolve: {:,} ns, total: {:,} ns, rt/zs: {}".format(
i, gmem.width, gmem.height, gmem.nbinx, gmem.nbiny, gmem.num_draws,
gmem.lrz_clear_time, gmem.binning_time, gmem.restore_clear_time,
gmem.draw_time, gmem.resolve_time, gmem.elapsed_time,
", ".join(gmem.formats)
))
lrz_clear_time += gmem.lrz_clear_time
binning_time += gmem.binning_time
restore_clear_time += gmem.restore_clear_time
draw_time += gmem.draw_time
resolve_time += gmem.resolve_time
elapsed_time += gmem.elapsed_time
i += 1
print(" TOTAL: lrz clear: {:,} ns ({}%), binning: {:,} ns ({}%), restore/clear: {:,} ns ({}%), draw: {:,} ns ({}%), resolve: {:,} ns ({}%), blit: {:,} ns ({}%), sysmem: {:,} ns ({}%), total: {:,} ns\n".format(
lrz_clear_time, 100.0 * lrz_clear_time / total_time,
binning_time, 100.0 * binning_time / total_time,
restore_clear_time, 100.0 * restore_clear_time / total_time,
draw_time, 100.0 * draw_time / total_time,
resolve_time, 100.0 * resolve_time / total_time,
blit_time, 100.0 * blit_time / total_time,
sysmem_time, 100.0 * sysmem_time / total_time,
total_time
))
def main():
filename = sys.argv[1]
if filename.endswith(".gz"):
file = gzip.open(filename, "r")
file = io.TextIOWrapper(file)
else:
file = open(filename, "r")
lines = file.read().split('\n')
compute_match = re.compile(r"COMPUTE: START")
gmem_start_match = re.compile(r": GMEM: cleared=(\S+), gmem_reason=(\S+), num_draws=(\S+), samples=(\S+)")
gmem_match = re.compile(r": rendering (\S+)x(\S+) tiles (\S+)x(\S+)")
gmem_surf_match = re.compile(r": {format = (\S+),")
gmem_lrz_clear_match = re.compile(r"\+(\S+): END LRZ CLEAR")
gmem_binning_match = re.compile(r"\+(\S+): GMEM: END BINNING IB")
gmem_restore_clear_match = re.compile(r"\+(\S+): TILE: END CLEAR/RESTORE")
gmem_draw_match = re.compile(r"\+(\S+): TILE\[\S+\]: END DRAW IB")
gmem_resolve_match = re.compile(r"\+(\S+): TILE: END RESOLVE")
sysmem_match = re.compile(r": rendering sysmem (\S+)x(\S+)")
blit_match = re.compile(r": END BLIT")
elapsed_match = re.compile(r"ELAPSED: (\S+) ns")
eof_match = re.compile(r"END OF FRAME (\S+)")
# Times in ns:
times_blit = []
times_sysmem = []
times_gmem = []
times_compute = []
times = None
gmem_passes = [] # set of GMEM passes in frame
gmem = None # current GMEM pass
for line in lines:
match = re.search(compute_match, line)
if match is not None:
#printf("GRID/COMPUTE")
if times is not None:
print("expected times to not be set yet")
times = times_compute
continue
match = re.search(gmem_start_match, line)
if match is not None:
if gmem is not None:
print("expected gmem to not be set yet")
if times is not None:
print("expected times to not be set yet")
times = times_gmem
gmem = GMEMPass()
gmem.cleared = match.group(1)
gmem.gmem_reason = match.group(2)
gmem.num_draws = match.group(3)
gmem.samples = match.group(4)
if gmem is not None:
match = re.search(gmem_match, line)
if match is not None:
gmem.width = int(match.group(1))
gmem.height = int(match.group(2))
gmem.nbinx = int(match.group(3))
gmem.nbiny = int(match.group(4))
continue
match = re.search(gmem_surf_match, line)
if match is not None:
gmem.formats.append(match.group(1))
continue
match = re.search(gmem_lrz_clear_match, line)
if match is not None:
gmem.lrz_clear_time += int(match.group(1))
continue
match = re.search(gmem_binning_match, line)
if match is not None:
gmem.binning_time += int(match.group(1))
continue
match = re.search(gmem_restore_clear_match, line)
if match is not None:
gmem.restore_clear_time += int(match.group(1))
continue
match = re.search(gmem_draw_match, line)
if match is not None:
gmem.draw_time += int(match.group(1))
continue
match = re.search(gmem_resolve_match, line)
if match is not None:
gmem.resolve_time += int(match.group(1))
continue
match = re.search(sysmem_match, line)
if match is not None:
#print("SYSMEM")
if times is not None:
print("expected times to not be set yet")
times = times_sysmem
continue
match = re.search(blit_match, line)
if match is not None:
#print("BLIT")
if times is not None:
print("expected times to not be set yet")
times = times_blit
continue
match = re.search(eof_match, line)
if match is not None:
frame_nr = int(match.group(1))
print("FRAME[{}]: {} blits ({:,} ns), {} SYSMEM ({:,} ns), {} GMEM ({:,} ns), {} COMPUTE ({:,} ns)".format(
frame_nr,
len(times_blit), sum(times_blit),
len(times_sysmem), sum(times_sysmem),
len(times_gmem), sum(times_gmem),
len(times_compute), sum(times_compute)
))
if len(gmem_passes) > 0:
total_time = sum(times_blit) + sum(times_sysmem) + sum(times_gmem) + sum(times_compute)
dump_gmem_passes(gmem_passes, sum(times_blit), sum(times_sysmem), total_time)
times_blit = []
times_sysmem = []
times_gmem = []
times = None
gmem_passes = []
gmem = None
continue
match = re.search(elapsed_match, line)
if match is not None:
time = int(match.group(1))
#print("ELAPSED: " + str(time) + " ns")
times.append(time)
times = None
if gmem is not None:
gmem.elapsed_time = time
gmem_passes.append(gmem)
gmem = None
continue
if __name__ == "__main__":
main()
|