]> git.cworth.org Git - apitrace-tests/blobdiff - app_driver.py
apps: Check d3dretrace snapshots.
[apitrace-tests] / app_driver.py
index 2e05a57b00fd3dabecd26abca7f299d7dbc0d792..0e6cc37c65c5f68ab82b82b4e16cc70f358ebe6e 100755 (executable)
@@ -42,100 +42,24 @@ except ImportError:
     from StringIO import StringIO
 
 
+import tracematch
 from base_driver import *
 
 
-import checker
-
-
-class RefTraceParser(checker.RefTraceParser):
-
-    def __init__(self, fileName):
-        checker.RefTraceParser.__init__(self, open(fileName, 'rt'))
-        self.fileName = fileName
-        self.images = []
-        self.states = []
-        self.pragmaNo = 0
-
-    def handlePragma(self, line):
-        if self.calls:
-            lastCall = self.calls[-1]
-            if lastCall.callNo is None:
-                paramName = 'pragma%u' % self.pragmaNo
-                lastCall.callNo = checker.WildcardMatcher(paramName)
-            else:
-                paramName = lastCall.callNo.name
-        else:
-            paramName = 0
-            self.pragmaNo += 1
-
-        pragma, rest = line.split(None, 1)
-        if pragma == '#image':
-            imageFileName = self.getAbsPath(rest)
-            self.images.append((paramName, imageFileName))
-        elif pragma == '#state':
-            stateFileName = self.getAbsPath(rest)
-            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.fileName), path))
-
-
-class SrcTraceParser(checker.SrcTraceParser):
+class SrcTraceParser(tracematch.SrcTraceParser):
 
     def __init__(self, stream):
-        checker.SrcTraceParser.__init__(self, stream)
+        tracematch.SrcTraceParser.__init__(self, stream)
         self.swapbuffers = 0
 
     def handleCall(self, callNo, functionName, args, ret):
-        checker.SrcTraceParser.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()
-
-            try:
-                mo = refTrace.match(srcTrace)
-            except checker.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
@@ -164,11 +88,16 @@ class AppDriver(Driver):
         if not self.cmd:
             return
 
+        sys.stderr.write('Run application...\n')
+
         p = popen(self.cmd, cwd=self.cwd)
         p.wait()
         if p.returncode != 0:
             skip('application returned code %i' % p.returncode)
 
+        sys.stdout.flush()
+        sys.stderr.write('\n')
+
     api_trace_map = {
         'gl': 'gl',
         'egl_gl': 'egl',
@@ -188,7 +117,7 @@ class AppDriver(Driver):
         'egl_gl': 'eglretrace',
         'egl_gles1': 'eglretrace',
         'egl_gles2': 'eglretrace',
-        #'d3d8': 'd3dretrace',
+        'd3d8': 'd3dretrace',
         'd3d9': 'd3dretrace',
         'd3d10': 'd3dretrace',
         'd3d10_1': 'd3dretrace',
@@ -200,6 +129,8 @@ class AppDriver(Driver):
         if not self.cmd:
             return
 
+        sys.stderr.write('Capturing trace...\n')
+
         if self.trace_file is None:
             if self.ref_dump is not None:
                 name = self.ref_dump
@@ -221,8 +152,9 @@ class AppDriver(Driver):
         
         cmd = [
             options.apitrace, 'trace', 
-            '--api', self.api_trace_map[self.api],
-            '--output', self.trace_file,
+            '-v',
+            '-a', self.api_trace_map[self.api],
+            '-o', self.trace_file,
             '--'
         ] + cmd
         if self.max_frames is not None:
@@ -235,31 +167,74 @@ class AppDriver(Driver):
 
         if not os.path.exists(self.trace_file):
             fail('no trace file generated\n')
+
+        sys.stdout.flush()
+        sys.stderr.write('\n')
     
     def checkTrace(self):
-        cmd = [options.apitrace, 'dump', '--color=never', self.trace_file]
-        p = popen(cmd, stdout=subprocess.PIPE)
+        sys.stderr.write('Comparing trace %s against %s...\n' % (self.trace_file, self.ref_dump))
+
+        cmd = [options.apitrace, 'dump', '--verbose', '--color=never', self.trace_file]
+        p = popen(cmd, stdout=subprocess.PIPE, universal_newlines=True)
+
+        srcParser = SrcTraceParser(p.stdout)
+        srcTrace = srcParser.parse()
+        self.doubleBuffer = srcParser.swapbuffers > 0
+
+        images = []
+        states = []
 
-        checker = TraceChecker(p.stdout, self.ref_dump)
-        checker.check()
+        if self.ref_dump:
+            refParser = tracematch.RefTraceParser(self.ref_dump)
+            refTrace = refParser.parse()
+
+            try:
+                mo = refTrace.match(srcTrace)
+            except tracematch.TraceMismatch, ex:
+                fail(str(ex))
+
+            dirName, baseName = os.path.split(os.path.abspath(self.ref_dump))
+            prefix, _ = os.path.splitext(baseName)
+            prefix += '.'
+            fileNames = os.listdir(dirName)
+            for fileName in fileNames:
+                if fileName.startswith(prefix) and fileName != self.ref_dump:
+                    rest = fileName[len(prefix):]
+                    paramName, ext = os.path.splitext(rest)
+                    if ext in ('.json', '.png'):
+                        if paramName.isdigit():
+                            callNo = int(paramName)
+                        else:
+                            try:
+                                callNo = mo.params[paramName]
+                            except KeyError:
+                                fail('could not find parameter %s for %s' % (paramName, fileName))
+                        filePath = os.path.join(dirName, fileName)
+                        if ext == '.png':
+                            images.append((callNo, filePath))
+                        if ext == '.json':
+                            states.append((callNo, filePath))
         p.wait()
         if p.returncode != 0:
             fail('`apitrace dump` returned code %i' % p.returncode)
 
-        self.doubleBuffer = checker.doubleBuffer
+        sys.stdout.flush()
+        sys.stderr.write('\n')
 
         if self.api not in self.api_retrace_map:
             return
 
-        for callNo, refImageFileName in checker.images:
+        for callNo, refImageFileName in images:
             self.checkImage(callNo, refImageFileName)
-        for callNo, refStateFileName in checker.states:
+        for callNo, refStateFileName in states:
             self.checkState(callNo, refStateFileName)
 
     def checkImage(self, callNo, refImageFileName):
+        sys.stderr.write('Comparing snapshot from call %u against %s...\n' % (callNo, refImageFileName))
         try:
             from PIL import Image
         except ImportError:
+            sys.stderr.write('warning: PIL not found, skipping image comparison\n');
             return
 
         srcImage = self.getImage(callNo)
@@ -277,7 +252,12 @@ class AppDriver(Driver):
             comparer.write_diff(diffImageFileName)
             fail('snapshot from call %u does not match %s' % (callNo, refImageFileName))
 
+        sys.stdout.flush()
+        sys.stderr.write('\n')
+
     def checkState(self, callNo, refStateFileName):
+        sys.stderr.write('Comparing state dump from call %u against %s...\n' % (callNo, refStateFileName))
+
         srcState = self.getState(callNo)
         refState = self.getRefState(refStateFileName)
 
@@ -295,6 +275,9 @@ class AppDriver(Driver):
             differ.visit(refState, srcState)
             fail('state from call %u does not match %s' % (callNo, refStateFileName))
 
+        sys.stdout.flush()
+        sys.stderr.write('\n')
+
     def getRefState(self, refStateFileName):
         stream = open(refStateFileName, 'rt')
         from jsondiff import load
@@ -320,23 +303,27 @@ class AppDriver(Driver):
         if self.api not in self.api_retrace_map:
             return
 
+        sys.stderr.write('Retracing %s...\n' % (self.trace_file,))
+
         p = self._retrace()
         p.wait()
         if p.returncode != 0:
             fail('retrace failed with code %i' % (p.returncode))
 
+        sys.stdout.flush()
+        sys.stderr.write('\n')
+
     def getImage(self, callNo):
         from PIL import Image
         state = self.getState(callNo)
         if self.doubleBuffer:
-            attachments = ['GL_BACK', 'GL_BACK_LEFT', 'GL_BACK_RIGHT', 'GL_COLOR_ATTACHMENT0']
+            attachments = ['GL_BACK', 'GL_BACK_LEFT', 'GL_BACK_RIGHT', 'GL_COLOR_ATTACHMENT0', 'RENDER_TARGET_0']
         else:
-            attachments = ['GL_FRONT', 'GL_FRONT_LEFT', 'GL_FRONT_RIGHT', 'GL_COLOR_ATTACHMENT0']
+            attachments = ['GL_FRONT', 'GL_FRONT_LEFT', 'GL_FRONT_RIGHT', 'GL_COLOR_ATTACHMENT0', 'RENDER_TARGET_0']
         imageObj = self.getFramebufferAttachment(state, attachments)
         data = imageObj['__data__']
         stream = StringIO(base64.b64decode(data))
         im = Image.open(stream)
-        im.save('test.png')
         return im
 
     def getFramebufferAttachment(self, state, attachments):