blob: 9be7f4bb4222c02dfe6aee6b9e9e75f8c8952ec0 [file] [log] [blame]
José Fonseca2cce1922012-12-11 19:51:26 +00001#!/usr/bin/env python
2##########################################################################
3#
4# Copyright 2012 VMware Inc.
5# All Rights Reserved.
6#
7# Permission is hereby granted, free of charge, to any person obtaining a copy
8# of this software and associated documentation files (the 'Software'), to deal
9# in the Software without restriction, including without limitation the rights
10# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11# copies of the Software, and to permit persons to whom the Software is
12# furnished to do so, subject to the following conditions:
13#
14# The above copyright notice and this permission notice shall be included in
15# all copies or substantial portions of the Software.
16#
17# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23# THE SOFTWARE.
24#
25##########################################################################/
26
27'''Convert traces to/from PIX.
28'''
29
30
31import optparse
32import os.path
33import subprocess
34import platform
35import sys
36
37
José Fonsecaf3cb6202015-02-08 00:05:35 +000038def callProcess(cmd):
39 if options.verbose:
40 sys.stderr.write(' '.join(cmd) + '\n')
41 ret = subprocess.call(cmd)
42 if ret:
43 exeName = os.path.basename(cmd[0])
44 sys.stderr.write('error: %s failed with exit code %u\n' % (exeName, ret))
45 sys.exit(ret)
46 return ret
47
48
49def verifyTrace(outTrace):
50 if os.path.exists(outTrace):
51 sys.stderr.write('info: %s written\n' % outTrace)
52 if options.verify:
53 callProcess([options.retrace, os.path.abspath(outTrace)])
54 else:
55 sys.stderr.write('error: %s not written\n' % outTrace)
56 sys.exit(1)
57
58
José Fonseca8b9f78b2013-04-25 15:22:53 +010059def getPixExe():
José Fonseca2cce1922012-12-11 19:51:26 +000060 try:
José Fonseca87f97d22012-12-11 20:37:39 +000061 programFiles = os.environ['ProgramFiles(x86)']
62 except KeyError:
63 programFiles = os.environ['ProgramFiles']
64 try:
José Fonseca2cce1922012-12-11 19:51:26 +000065 dxsdkDir = os.environ['DXSDK_DIR']
66 except KeyError:
67 dxsdkDir = os.path.join(programFiles, "Microsoft DirectX SDL (June 2010)")
José Fonseca8b9f78b2013-04-25 15:22:53 +010068 pixExe = os.path.join(dxsdkDir, "Utilities", "bin", 'x86', 'PIXwin.exe')
69 return pixExe
70
71
José Fonseca8b9f78b2013-04-25 15:22:53 +010072def convertToPix(inTrace, outPixrun):
José Fonsecaf3cb6202015-02-08 00:05:35 +000073 pixExe = getPixExe()
José Fonseca2cce1922012-12-11 19:51:26 +000074
75 pixExp = os.path.join(os.path.dirname(__file__), 'apitrace.PIXExp')
76
77 # http://social.msdn.microsoft.com/Forums/sv/devdocs/thread/15addc0c-036d-413a-854a-35637ccbb834
78 # http://src.chromium.org/svn/trunk/o3d/tests/test_driver.py
79 cmd = [
José Fonseca8b9f78b2013-04-25 15:22:53 +010080 getPixExe(),
José Fonseca2cce1922012-12-11 19:51:26 +000081 pixExp,
82 '-start',
83 '-runfile', os.path.abspath(outPixrun),
84 '-targetpath', os.path.abspath(options.retrace),
85 #'-targetstartfolder', ...,
86 '-targetargs', os.path.abspath(inTrace),
87 ]
88
José Fonseca8b9f78b2013-04-25 15:22:53 +010089 callProcess(cmd)
José Fonseca2cce1922012-12-11 19:51:26 +000090 if os.path.exists(outPixrun):
91 sys.stderr.write('info: %s written\n' % outPixrun)
José Fonseca8b9f78b2013-04-25 15:22:53 +010092 if options.verify:
José Fonsecaf3cb6202015-02-08 00:05:35 +000093 subprocess.call([pixExe, os.path.abspath(outPixrun)])
José Fonseca2cce1922012-12-11 19:51:26 +000094 else:
95 sys.stderr.write('error: %s not written\n' % outPixrun)
96 sys.exit(1)
97
98
José Fonseca8b9f78b2013-04-25 15:22:53 +010099def convertFromPix(inPix, outTrace):
100 pixExe = getPixExe()
101
102 if False:
José Fonseca5ad7df82013-04-26 12:05:05 +0100103 # TODO: Use -exporttocsv option to detect which API to use
José Fonseca8b9f78b2013-04-25 15:22:53 +0100104 cmd = [
105 pixExe,
106 inPix,
José Fonseca5ad7df82013-04-26 12:05:05 +0100107 '-exporttocsv', # XXX: output filename is ignored
José Fonseca8b9f78b2013-04-25 15:22:53 +0100108 ]
109 callProcess(cmd)
110
111 cmd = [
112 options.apitrace,
113 'trace',
114 '-a', options.api,
115 '-o', outTrace,
116 pixExe,
117 inPix,
118 '-playstandalone',
119 ]
120
121 callProcess(cmd)
José Fonsecaf3cb6202015-02-08 00:05:35 +0000122 verifyTrace(outTrace)
123
124
125def getDxcapExe():
126 winDir = os.environ['windir']
127 if 'ProgramFiles(x86)' in os.environ:
128 sysSubDir = 'SysWOW64'
José Fonseca8b9f78b2013-04-25 15:22:53 +0100129 else:
José Fonsecaf3cb6202015-02-08 00:05:35 +0000130 sysSubDir = 'System32'
131 dxcapExe = os.path.join(winDir, sysSubDir, 'dxcap.exe')
132 return dxcapExe
133
134
135def convertToDxcap(inTrace, outDxcaprun):
136 # https://msdn.microsoft.com/en-us/library/vstudio/dn774939.aspx
137
138 dxcapExe = getDxcapExe()
139
140 cmd = [
141 getDxcapExe(),
142 '-rawmode',
143 '-file', os.path.abspath(outDxcaprun),
144 '-c',
145 options.retrace,
146 '-b',
147 os.path.abspath(inTrace),
148 ]
149
150 callProcess(cmd)
151 if os.path.exists(outDxcaprun):
152 sys.stderr.write('info: %s written\n' % outDxcaprun)
153 if options.verify:
154 callProcess([dxcapExe, '-p', os.path.abspath(outDxcaprun)])
155 else:
156 sys.stderr.write('error: %s not written\n' % outDxcaprun)
José Fonseca8b9f78b2013-04-25 15:22:53 +0100157 sys.exit(1)
158
159
José Fonsecaf3cb6202015-02-08 00:05:35 +0000160def convertFromDxcap(inDxcap, outTrace):
161 dxcapExe = getDxcapExe()
162
163 cmd = [
164 options.apitrace,
165 'trace',
166 '-a', options.api,
167 '-o', outTrace,
168 '--',
169 dxcapExe,
170 '-rawmode',
171 '-p', inDxcap,
172 ]
173
174 callProcess(cmd)
175 verifyTrace(outTrace)
176
177
José Fonseca2cce1922012-12-11 19:51:26 +0000178def main():
179 global options
180
181 # Parse command line options
182 optparser = optparse.OptionParser(
183 usage='\n\t%prog [options] <trace> ...',
184 version='%%prog')
185 optparser.add_option(
José Fonseca8b9f78b2013-04-25 15:22:53 +0100186 '--apitrace', metavar='PROGRAM',
187 type='string', dest='apitrace', default='apitrace.exe',
José Fonsecacd442802013-06-08 14:05:19 +0100188 help='path to apitrace command [default: %default]')
José Fonseca8b9f78b2013-04-25 15:22:53 +0100189 optparser.add_option(
190 '-a', '--api', metavar='API',
José Fonsecaf3cb6202015-02-08 00:05:35 +0000191 type='string', dest='api', default='dxgi',
José Fonseca8b9f78b2013-04-25 15:22:53 +0100192 help='api [default: %default]')
193 optparser.add_option(
José Fonseca2cce1922012-12-11 19:51:26 +0000194 '-r', '--retrace', metavar='PROGRAM',
José Fonseca8b9f78b2013-04-25 15:22:53 +0100195 type='string', dest='retrace', default='d3dretrace.exe',
José Fonsecacd442802013-06-08 14:05:19 +0100196 help='path to retrace command [default: %default]')
José Fonseca2cce1922012-12-11 19:51:26 +0000197 optparser.add_option(
198 '-v', '--verbose',
199 action='store_true', dest='verbose', default=False,
200 help='verbose output')
201 optparser.add_option(
202 '-o', '--output', metavar='FILE',
203 type="string", dest="output",
204 help="output file [default: stdout]")
José Fonseca8b9f78b2013-04-25 15:22:53 +0100205 optparser.add_option(
206 '--verify',
207 action='store_true', dest='verify', default=False,
208 help='verify output by replaying it')
José Fonseca2cce1922012-12-11 19:51:26 +0000209
210 (options, args) = optparser.parse_args(sys.argv[1:])
211 if not args:
212 optparser.error("incorrect number of arguments")
213
José Fonseca8b9f78b2013-04-25 15:22:53 +0100214 for inFile in args:
215 name, inExt = os.path.splitext(os.path.basename(inFile))
José Fonseca8b9f78b2013-04-25 15:22:53 +0100216 if inExt.lower() == '.trace':
José Fonsecaf3cb6202015-02-08 00:05:35 +0000217 convert = convertToDxcap
218 outExt = '.vsglog'
219 if options.output:
220 _, outExt = os.path.splitext(options.output)
221 if outExt.lower() == '.pixrun':
222 convert = convertToPix
223 elif inExt.lower() == '.vsglog':
224 convert = convertFromDxcap
225 outExt = '.trace'
José Fonseca8b9f78b2013-04-25 15:22:53 +0100226 elif inExt.lower() == '.pixrun':
227 convert = convertFromPix
228 outExt = '.trace'
José Fonseca2cce1922012-12-11 19:51:26 +0000229 else:
José Fonseca8b9f78b2013-04-25 15:22:53 +0100230 optparser.error("unexpected file extensions `%s`" % inExt)
231 if options.output:
232 outFile = options.output
233 else:
234 outFile = name + outExt
235 convert(inFile, outFile)
José Fonseca2cce1922012-12-11 19:51:26 +0000236
237
238if __name__ == '__main__':
239 main()