X-Git-Url: https://git.cworth.org/git?p=apitrace-tests;a=blobdiff_plain;f=app_driver.py;h=e5536b83729ffc4bbc8e84478295def6146e48ca;hp=a44badea1566d4248e80ed28374359dd22710fe7;hb=d9858b16096ac4ec7c99f1430a6ee934e33db2e0;hpb=b8296ac85e510854e7ad57b02ddba25114b92775 diff --git a/app_driver.py b/app_driver.py index a44bade..e5536b8 100755 --- a/app_driver.py +++ b/app_driver.py @@ -42,102 +42,99 @@ except ImportError: from StringIO import StringIO +import tracematch from base_driver import * -class TraceChecker: +class RefTraceParser(tracematch.RefTraceParser): - def __init__(self, srcStream, refFileName, verbose=False): - self.srcStream = srcStream - self.refFileName = refFileName - if refFileName: - self.refStream = open(refFileName, 'rt') - else: - self.refStream = None - self.verbose = verbose - self.doubleBuffer = False - self.callNo = 0 - self.refLine = '' + def __init__(self, fileName): + tracematch.RefTraceParser.__init__(self, open(fileName, 'rt')) + self.fileName = fileName self.images = [] self.states = [] + self.pragmaNo = 0 - call_re = re.compile(r'^([0-9]+) (\w+)\(') - - def check(self): - - swapbuffers = 0 - flushes = 0 - - srcLines = [] - self.consumeRefLine() - for line in self.srcStream: - line = line.rstrip() - if self.verbose: - sys.stdout.write(line + '\n') - mo = self.call_re.match(line) - if mo: - self.callNo = int(mo.group(1)) - function_name = mo.group(2) - if function_name.find('SwapBuffers') != -1 or \ - line.find('kCGLPFADoubleBuffer') != -1: - swapbuffers += 1 - if function_name in ('glFlush', 'glFinish'): - flushes += 1 - srcLine = line[mo.start(2):] - else: - srcLine = line - if self.refLine: - if srcLine == self.refLine: - self.consumeRefLine() - srcLines = [] - else: - srcLines.append(srcLine) - - if self.refLine: - if srcLines: - fail('missing call `%s` (found `%s`)' % (self.refLine, srcLines[0])) + def handlePragma(self, line): + if self.calls: + lastCall = self.calls[-1] + if lastCall.callNo is None: + paramName = 'pragma%u' % self.pragmaNo + lastCall.callNo = tracematch.WildcardMatcher(paramName) else: - fail('missing call %s' % self.refLine) - - if swapbuffers: - self.doubleBuffer = True + paramName = lastCall.callNo.name else: - self.doubleBuffer = False - - def consumeRefLine(self): - if not self.refStream: - self.refLine = '' - return + paramName = 0 + self.pragmaNo += 1 - while True: - line = self.refStream.readline() - if not line: - break - line = line.rstrip() - if line.startswith('#'): - self.handlePragma(line) - else: - break - self.refLine = line - - def handlePragma(self, line): pragma, rest = line.split(None, 1) if pragma == '#image': imageFileName = self.getAbsPath(rest) - self.images.append((self.callNo, imageFileName)) + self.images.append((paramName, imageFileName)) elif pragma == '#state': stateFileName = self.getAbsPath(rest) - self.states.append((self.callNo, stateFileName)) + self.states.append((paramName, stateFileName)) else: assert False def getAbsPath(self, path): '''Get the absolute from a path relative to the reference filename''' - return os.path.abspath(os.path.join(os.path.dirname(self.refFileName), path)) + return os.path.abspath(os.path.join(os.path.dirname(self.fileName), path)) + + +class SrcTraceParser(tracematch.SrcTraceParser): + + def __init__(self, stream): + tracematch.SrcTraceParser.__init__(self, stream) + self.swapbuffers = 0 + + def handleCall(self, callNo, functionName, args, ret): + tracematch.SrcTraceParser.handleCall(self, callNo, functionName, args, ret) + + if functionName.find('SwapBuffers') != -1 or \ + repr(args).find('kCGLPFADoubleBuffer') != -1: + self.swapbuffers += 1 + + +class TraceChecker: + + def __init__(self, srcStream, refFileName): + self.srcStream = srcStream + self.refFileName = refFileName + self.doubleBuffer = False + self.callNo = 0 + self.images = [] + self.states = [] + def check(self): + srcParser = SrcTraceParser(self.srcStream) + srcTrace = srcParser.parse() + self.doubleBuffer = srcParser.swapbuffers > 0 + if self.refFileName: + refParser = RefTraceParser(self.refFileName) + refTrace = refParser.parse() -class TestCase: + try: + mo = refTrace.match(srcTrace) + except tracematch.TraceMismatch, ex: + self.fail(str(ex)) + + for paramName, imageFileName in refParser.images: + if isinstance(paramName, int): + callNo = paramName + else: + callNo = mo.params[paramName] + self.images.append((callNo, imageFileName)) + for paramName, stateFileName in refParser.states: + if isinstance(paramName, int): + callNo = paramName + else: + callNo = mo.params[paramName] + self.states.append((callNo, stateFileName)) + + +class AppDriver(Driver): cmd = None cwd = None @@ -155,6 +152,7 @@ class TestCase: threshold_precision = 12.0 def __init__(self): + Driver.__init__(self) self.stateCache = {} def runApp(self): @@ -166,14 +164,34 @@ class TestCase: p = popen(self.cmd, cwd=self.cwd) p.wait() - if p.returncode: + if p.returncode != 0: skip('application returned code %i' % p.returncode) - api_map = { + api_trace_map = { 'gl': 'gl', 'egl_gl': 'egl', 'egl_gles1': 'egl', 'egl_gles2': 'egl', + 'd3d7': 'd3d7', + 'd3d8': 'd3d8', + 'd3d9': 'd3d9', + 'd3d10': 'd3d10', + 'd3d10_1': 'd3d10_1', + 'd3d11': 'd3d11', + 'd3d11_1': 'd3d11', + } + + api_retrace_map = { + 'gl': 'glretrace', + 'egl_gl': 'eglretrace', + 'egl_gles1': 'eglretrace', + 'egl_gles2': 'eglretrace', + #'d3d8': 'd3dretrace', + 'd3d9': 'd3dretrace', + 'd3d10': 'd3dretrace', + 'd3d10_1': 'd3dretrace', + 'd3d11': 'd3dretrace', + 'd3d11_1': 'd3dretrace', } def traceApp(self): @@ -201,7 +219,7 @@ class TestCase: cmd = [ options.apitrace, 'trace', - '--api', self.api_map[self.api], + '--api', self.api_trace_map[self.api], '--output', self.trace_file, '--' ] + cmd @@ -210,6 +228,8 @@ class TestCase: p = popen(cmd, env=env, cwd=self.cwd) p.wait() + if p.returncode != 0: + fail('`apitrace trace` returned code %i' % p.returncode) if not os.path.exists(self.trace_file): fail('no trace file generated\n') @@ -218,7 +238,7 @@ class TestCase: cmd = [options.apitrace, 'dump', '--color=never', self.trace_file] p = popen(cmd, stdout=subprocess.PIPE) - checker = TraceChecker(p.stdout, self.ref_dump, self.verbose) + checker = TraceChecker(p.stdout, self.ref_dump) checker.check() p.wait() if p.returncode != 0: @@ -226,6 +246,9 @@ class TestCase: self.doubleBuffer = checker.doubleBuffer + if self.api not in self.api_retrace_map: + return + for callNo, refImageFileName in checker.images: self.checkImage(callNo, refImageFileName) for callNo, refStateFileName in checker.states: @@ -292,6 +315,9 @@ class TestCase: open(filename, 'wt').write(s) def retrace(self): + if self.api not in self.api_retrace_map: + return + p = self._retrace() p.wait() if p.returncode != 0: @@ -351,19 +377,9 @@ class TestCase: except KeyError: return - # On NVIDIA drivers glGetIntegerv(GL_INDEX_WRITEMASK) returns -1 + # On NVIDIA drivers glGetIntegerv(GL_INDEX_WRITEMASK) returns 255 self.replaceState(parameters, 'GL_INDEX_WRITEMASK', 255, -1) - # On Gallium - if 'Gallium' in parameters['GL_RENDERER'].split(): - # Gallium drivers have wrong defaults for draw/read buffer state - self.replaceState(parameters, 'GL_DRAW_BUFFER', 'GL_BACK_LEFT', 'GL_BACK') - self.replaceState(parameters, 'GL_DRAW_BUFFER0', 'GL_BACK_LEFT', 'GL_BACK') - self.replaceState(parameters, 'GL_READ_BUFFER', 'GL_BACK_LEFT', 'GL_BACK') - self.replaceState(parameters, 'GL_DRAW_BUFFER', 'GL_FRONT_LEFT', 'GL_FRONT') - self.replaceState(parameters, 'GL_DRAW_BUFFER0', 'GL_FRONT_LEFT', 'GL_FRONT') - self.replaceState(parameters, 'GL_READ_BUFFER', 'GL_FRONT_LEFT', 'GL_FRONT') - def adjustRefState(self, state): # Do some adjustments on reference state to eliminate failures from # bugs/issues outside of apitrace @@ -394,8 +410,9 @@ class TestCase: pass def _retrace(self, args = None, stdout=subprocess.PIPE): - retrace = self.api_map[self.api] + 'retrace' - cmd = [get_build_program(retrace)] + retrace = self.api_retrace_map[self.api] + #cmd = [get_build_program(retrace)] + cmd = [options.apitrace, 'retrace'] if self.doubleBuffer: cmd += ['-db'] else: @@ -405,19 +422,8 @@ class TestCase: cmd += [self.trace_file] return popen(cmd, stdout=stdout) - def run(self): - self.runApp() - self.traceApp() - self.checkTrace() - self.retrace() - - pass_() - - -class AppMain(Main): - def createOptParser(self): - optparser = Main.createOptParser(self) + optparser = Driver.createOptParser(self) optparser.add_option( '-a', '--api', metavar='API', @@ -434,7 +440,7 @@ class AppMain(Main): return optparser - def main(self): + def run(self): global options (options, args) = self.parseOptions() @@ -442,17 +448,20 @@ class AppMain(Main): if not os.path.exists(options.results): os.makedirs(options.results) - test = TestCase() - test.verbose = options.verbose + self.verbose = options.verbose - test.cmd = args - test.cwd = options.cwd - test.api = options.api - test.ref_dump = options.ref_dump - test.results = options.results + self.cmd = args + self.cwd = options.cwd + self.api = options.api + self.ref_dump = options.ref_dump + self.results = options.results - test.run() + self.runApp() + self.traceApp() + self.checkTrace() + self.retrace() + pass_() if __name__ == '__main__': - AppMain().main() + AppDriver().run()