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