Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/src/tests/restricted_traces/retrace_restricted_traces.py
1693 views
1
#! /usr/bin/env python3
2
#
3
# Copyright 2020 The ANGLE Project Authors. All rights reserved.
4
# Use of this source code is governed by a BSD-style license that can be
5
# found in the LICENSE file.
6
#
7
'''
8
Script that re-captures the traces in the restricted trace folder. We can
9
use this to update traces without needing to re-run the app on a device.
10
'''
11
12
import argparse
13
import fnmatch
14
import json
15
import logging
16
import os
17
import re
18
import subprocess
19
import sys
20
21
from gen_restricted_traces import get_context as get_context
22
23
DEFAULT_TEST_SUITE = 'angle_perftests'
24
DEFAULT_TEST_JSON = 'restricted_traces.json'
25
DEFAULT_LOG_LEVEL = 'info'
26
27
# We preserve select metadata in the trace header that can't be re-captured properly.
28
# Currently this is just the set of default framebuffer surface config bits.
29
METADATA_KEYWORDS = ['kDefaultFramebuffer']
30
31
32
def src_trace_path(trace):
33
script_dir = os.path.dirname(sys.argv[0])
34
return os.path.join(script_dir, trace)
35
36
37
def context_header(trace, trace_path):
38
context_id = get_context(trace_path)
39
header = '%s_capture_context%s.h' % (trace, context_id)
40
return os.path.join(trace_path, header)
41
42
43
def get_num_frames(trace):
44
trace_path = src_trace_path(trace)
45
46
lo = 99999999
47
hi = 0
48
49
for file in os.listdir(trace_path):
50
match = re.match(r'.+_capture_context\d_frame(\d+)\.cpp', file)
51
if match:
52
frame = int(match.group(1))
53
if frame < lo:
54
lo = frame
55
if frame > hi:
56
hi = frame
57
58
return hi - lo + 1
59
60
61
def get_trace_metadata(trace):
62
trace_path = src_trace_path(trace)
63
header_file = context_header(trace, trace_path)
64
metadata = []
65
with open(header_file, 'rt') as f:
66
for line in f.readlines():
67
for keyword in METADATA_KEYWORDS:
68
if keyword in line:
69
metadata += [line]
70
return metadata
71
72
73
def replace_metadata(header_file, metadata):
74
lines = []
75
replaced = False
76
with open(header_file, 'rt') as f:
77
for line in f.readlines():
78
found_keyword = False
79
for keyword in METADATA_KEYWORDS:
80
if keyword in line:
81
found_keyword = True
82
break
83
84
if found_keyword:
85
if not replaced:
86
replaced = True
87
lines += metadata
88
else:
89
lines += [line]
90
91
with open(header_file, 'wt') as f:
92
f.writelines(lines)
93
94
95
def path_contains_header(path):
96
for file in os.listdir(path):
97
if fnmatch.fnmatch(file, '*.h'):
98
return True
99
return False
100
101
102
def main():
103
parser = argparse.ArgumentParser()
104
parser.add_argument('gn_path', help='GN build path')
105
parser.add_argument('out_path', help='Output directory')
106
parser.add_argument('-f', '--filter', help='Trace filter. Defaults to all.', default='*')
107
parser.add_argument('-l', '--log', help='Logging level.', default=DEFAULT_LOG_LEVEL)
108
parser.add_argument(
109
'--no-swiftshader',
110
help='Trace against native Vulkan.',
111
action='store_true',
112
default=False)
113
parser.add_argument(
114
'-n',
115
'--no-overwrite',
116
help='Skip traces which already exist in the out directory.',
117
action='store_true')
118
parser.add_argument(
119
'--validation', help='Enable state serialization validation calls.', action='store_true')
120
parser.add_argument(
121
'--limit',
122
'--frame-limit',
123
type=int,
124
help='Limits the number of captured frames to produce a shorter trace than the original.')
125
args, extra_flags = parser.parse_known_args()
126
127
logging.basicConfig(level=args.log.upper())
128
129
script_dir = os.path.dirname(sys.argv[0])
130
131
# Load trace names
132
with open(os.path.join(script_dir, DEFAULT_TEST_JSON)) as f:
133
traces = json.loads(f.read())
134
135
traces = [trace.split(' ')[0] for trace in traces['traces']]
136
137
binary = os.path.join(args.gn_path, DEFAULT_TEST_SUITE)
138
if os.name == 'nt':
139
binary += '.exe'
140
141
failures = []
142
143
for trace in fnmatch.filter(traces, args.filter):
144
logging.debug('Tracing %s' % trace)
145
146
trace_path = os.path.abspath(os.path.join(args.out_path, trace))
147
if not os.path.isdir(trace_path):
148
os.makedirs(trace_path)
149
elif args.no_overwrite and path_contains_header(trace_path):
150
logging.info('Skipping "%s" because the out folder already exists' % trace)
151
continue
152
153
num_frames = get_num_frames(trace)
154
metadata = get_trace_metadata(trace)
155
156
logging.debug('Read metadata: %s' % str(metadata))
157
158
max_steps = min(args.limit, num_frames) if args.limit else num_frames
159
160
# We start tracing from frame 2. --retrace-mode issues a Swap() after Setup() so we can
161
# accurately re-trace the MEC.
162
additional_env = {
163
'ANGLE_CAPTURE_LABEL': trace,
164
'ANGLE_CAPTURE_OUT_DIR': trace_path,
165
'ANGLE_CAPTURE_FRAME_START': '2',
166
'ANGLE_CAPTURE_FRAME_END': str(num_frames + 1),
167
}
168
if args.validation:
169
additional_env['ANGLE_CAPTURE_VALIDATION'] = '1'
170
# Also turn on shader output init to ensure we have no undefined values.
171
# This feature is also enabled in replay when using --validation.
172
additional_env['ANGLE_FEATURE_OVERRIDES_ENABLED'] = 'forceInitShaderOutputVariables'
173
174
env = {**os.environ.copy(), **additional_env}
175
176
renderer = 'vulkan' if args.no_swiftshader else 'vulkan_swiftshader'
177
178
trace_filter = '--gtest_filter=TracePerfTest.Run/%s_%s' % (renderer, trace)
179
run_args = [
180
binary,
181
trace_filter,
182
'--retrace-mode',
183
'--max-steps-performed',
184
str(max_steps),
185
'--enable-all-trace-tests',
186
]
187
188
print('Capturing "%s" (%d frames)...' % (trace, num_frames))
189
logging.debug('Running "%s" with environment: %s' %
190
(' '.join(run_args), str(additional_env)))
191
try:
192
subprocess.check_call(run_args, env=env)
193
194
header_file = context_header(trace, trace_path)
195
196
if not os.path.exists(header_file):
197
logging.error('There was a problem tracing "%s", could not find header file: %s' %
198
(trace, header_file))
199
failures += [trace]
200
else:
201
replace_metadata(header_file, metadata)
202
except:
203
logging.exception('There was an exception running "%s":' % trace)
204
failures += [trace]
205
206
if failures:
207
print('The following traces failed to re-trace:\n')
208
print('\n'.join([' ' + trace for trace in failures]))
209
return 1
210
211
return 0
212
213
214
if __name__ == '__main__':
215
sys.exit(main())
216
217