diff options
Diffstat (limited to 'scripts/convert.py')
-rwxr-xr-x | scripts/convert.py | 161 |
1 files changed, 135 insertions, 26 deletions
diff --git a/scripts/convert.py b/scripts/convert.py index 3dacd72c..5f338d80 100755 --- a/scripts/convert.py +++ b/scripts/convert.py @@ -35,6 +35,27 @@ import platform import sys +def callProcess(cmd): + if options.verbose: + sys.stderr.write(' '.join(cmd) + '\n') + ret = subprocess.call(cmd) + if ret: + exeName = os.path.basename(cmd[0]) + sys.stderr.write('error: %s failed with exit code %u\n' % (exeName, ret)) + sys.exit(ret) + return ret + + +def verifyTrace(outTrace): + if os.path.exists(outTrace): + sys.stderr.write('info: %s written\n' % outTrace) + if options.verify: + callProcess([options.retrace, os.path.abspath(outTrace)]) + else: + sys.stderr.write('error: %s not written\n' % outTrace) + sys.exit(1) + + def getPixExe(): try: programFiles = os.environ['ProgramFiles(x86)'] @@ -48,19 +69,8 @@ def getPixExe(): return pixExe -def callProcess(cmd): - if options.verbose: - sys.stderr.write(' '.join(cmd) + '\n') - ret = subprocess.call(cmd) - if ret: - exeName = os.path.basename(cmd[0]) - sys.stderr.write('error: %s failed with exit code %u\n' % (exeName, ret)) - sys.exit(ret) - return ret - - def convertToPix(inTrace, outPixrun): - pix = getPixExe() + pixExe = getPixExe() pixExp = os.path.join(os.path.dirname(__file__), 'apitrace.PIXExp') @@ -80,44 +90,130 @@ def convertToPix(inTrace, outPixrun): if os.path.exists(outPixrun): sys.stderr.write('info: %s written\n' % outPixrun) if options.verify: - subprocess.call([pix, os.path.abspath(outPixrun)]) + subprocess.call([pixExe, os.path.abspath(outPixrun)]) else: sys.stderr.write('error: %s not written\n' % outPixrun) sys.exit(1) +def detectApiFromCsv(inCsv): + import csv + csvReader = csv.reader(open(inCsv, 'rt'), ) + for row in csvReader: + print row + event = row[2] + print event + if event.startswith("Direct3DCreate9"): + return "d3d9" + if event.startswith("CreateDXGIFactory"): + return "dxgi" + if event.startswith("D3D10CreateDevice"): + return "d3d10" + if event.startswith("D3D11CreateDevice"): + return "d3d11" + assert False + + def convertFromPix(inPix, outTrace): pixExe = getPixExe() - if False: - # TODO: Use -exporttocsv option to detect which API to use + api = options.api + + if True: + # Use -exporttocsv option to detect which API to use cmd = [ pixExe, inPix, - '-exporttocsv', # XXX: output filename is ignored + '-exporttocsv', ] + + # XXX: output filename is ignored + inPixDir, inPixFileName = os.path.split(inPix) + inPixName, inPixExt = os.path.splitext(inPixFileName) + outCsv = os.path.join(inPixDir, inPixName + '.csv') + + if os.path.exists(outCsv): + os.remove(outCsv) + callProcess(cmd) + if os.path.isfile(outCsv): + api = detectApiFromCsv(outCsv) + cmd = [ options.apitrace, 'trace', - '-a', options.api, + '-a', api, '-o', outTrace, pixExe, inPix, - '-playstandalone', ] + + # XXX: Autodetect somehow + if not options.single_frame: + # Full capture + cmd += ['-playstandalone'] + else: + # Single-frame capture + cmd += ['-autorenderto', 'nul:'] callProcess(cmd) - if os.path.exists(outTrace): - sys.stderr.write('info: %s written\n' % outTrace) + verifyTrace(outTrace) + + +def getDxcapExe(): + winDir = os.environ['windir'] + if 'ProgramFiles(x86)' in os.environ: + sysSubDir = 'SysWOW64' + else: + sysSubDir = 'System32' + dxcapExe = os.path.join(winDir, sysSubDir, 'dxcap.exe') + return dxcapExe + + +def convertToDxcap(inTrace, outDxcaprun): + # https://msdn.microsoft.com/en-us/library/vstudio/dn774939.aspx + + dxcapExe = getDxcapExe() + + cmd = [ + getDxcapExe(), + '-rawmode', + '-file', os.path.abspath(outDxcaprun), + '-c', + options.retrace, + '-b', + os.path.abspath(inTrace), + ] + + callProcess(cmd) + if os.path.exists(outDxcaprun): + sys.stderr.write('info: %s written\n' % outDxcaprun) if options.verify: - subprocess.call([options.retrace, os.path.abspath(outTrace)]) + callProcess([dxcapExe, '-p', os.path.abspath(outDxcaprun)]) else: - sys.stderr.write('error: %s not written\n' % outTrace) + sys.stderr.write('error: %s not written\n' % outDxcaprun) sys.exit(1) +def convertFromDxcap(inDxcap, outTrace): + dxcapExe = getDxcapExe() + + cmd = [ + options.apitrace, + 'trace', + '-a', options.api, + '-o', outTrace, + '--', + dxcapExe, + '-rawmode', + '-p', inDxcap, + ] + + callProcess(cmd) + verifyTrace(outTrace) + + def main(): global options @@ -131,7 +227,7 @@ def main(): help='path to apitrace command [default: %default]') optparser.add_option( '-a', '--api', metavar='API', - type='string', dest='api', default='d3d9', + type='string', dest='api', default='dxgi', help='api [default: %default]') optparser.add_option( '-r', '--retrace', metavar='PROGRAM', @@ -146,6 +242,10 @@ def main(): type="string", dest="output", help="output file [default: stdout]") optparser.add_option( + '--single-frame', + action='store_true', dest='single_frame', default=False, + help='single-frame PIXRun capture') + optparser.add_option( '--verify', action='store_true', dest='verify', default=False, help='verify output by replaying it') @@ -156,10 +256,16 @@ def main(): for inFile in args: name, inExt = os.path.splitext(os.path.basename(inFile)) - inExt = inExt if inExt.lower() == '.trace': - convert = convertToPix - outExt = '.PIXRun' + convert = convertToDxcap + outExt = '.vsglog' + if options.output: + _, outExt = os.path.splitext(options.output) + if outExt.lower() == '.pixrun': + convert = convertToPix + elif inExt.lower() == '.vsglog': + convert = convertFromDxcap + outExt = '.trace' elif inExt.lower() == '.pixrun': convert = convertFromPix outExt = '.trace' @@ -169,6 +275,9 @@ def main(): outFile = options.output else: outFile = name + outExt + + if os.path.exists(outFile): + os.remove(outFile) convert(inFile, outFile) |