])
-def runtest(demo):
+def image_tag(html, image):
+ url = os.path.relpath(image, options.results)
+ html.write(' <td><a href="%s"><img src="%s"/></a></td>\n' % (url, url))
+
+
+def runtest(html, demo):
app = os.path.join(options.mesa_demos, 'src', demo)
dirname, basename = os.path.split(app)
-
- trace = os.path.abspath(demo.replace('/', '-') + '.trace')
+
+ trace = os.path.abspath(os.path.join(options.results, demo.replace('/', '-') + '.trace'))
env = os.environ.copy()
- env['LD_PRELOAD'] = os.path.abspath('glxtrace.so')
+ env['LD_PRELOAD'] = os.path.abspath(os.path.join(options.build, 'glxtrace.so'))
env['TRACE_FILE'] = trace
-
- args = [os.path.join('.', basename)]
- p = popen(args, env=env, cwd=dirname, stdout=subprocess.PIPE)
- time.sleep(1)
-
- # http://stackoverflow.com/questions/151407/how-to-get-an-x11-window-from-a-process-id
- ref_image = demo.replace('/', '-') + '.ref.png'
- subprocess.call('xwd -name \'%s\' | xwdtopnm | pnmtopng > %s' % (args[0], ref_image), shell=True, stdout=subprocess.PIPE)
-
- os.kill(p.pid, signal.SIGTERM)
-
- p = popen(['./tracedump', trace], stdout=subprocess.PIPE)
- stdout, _ = p.communicate()
+ args = [os.path.join('.', basename)]
+ window_name = args[0]
+
+ p = popen(args, cwd=dirname)
+ for i in range(6):
+ time.sleep(0.5)
+ if p.poll() is not None:
+ break
+ if subprocess.call(['xwininfo', '-name', window_name], stdout=subprocess.PIPE, stderr=subprocess.PIPE) == 0:
+ break
+ if p.returncode is None:
+ p.terminate()
+ elif p.returncode:
+ sys.stdout.write('SKIP (app)\n')
+ return
+
+ ref_image = os.path.join(options.results, demo.replace('/', '-') + '.ref.png')
+ p = popen(args, env=env, cwd=dirname)
+ try:
+ for i in range(10):
+ time.sleep(0.5)
+ if p.poll() is not None:
+ break
+ if subprocess.call(['xwininfo', '-name', window_name], stdout=subprocess.PIPE, stderr=subprocess.PIPE) == 0:
+ break
+
+ if p.returncode is None:
+ subprocess.call("xwd -name '%s' | xwdtopnm | pnmtopng > '%s'" % (args[0], ref_image), shell=True)
+ finally:
+ if p.returncode is None:
+ p.terminate()
+ p.wait()
+ elif p.returncode:
+ print p.returncode
+ sys.stdout.write('FAIL (trace)\n')
+ return
+
+ p = popen([os.path.join(options.build, 'tracedump'), trace], stdout=subprocess.PIPE)
call_re = re.compile('^([0-9]+) (\w+)\(')
- double_buffer = False
- for orig_line in stdout.split('\n'):
+ swapbuffers = 0
+ flushes = 0
+ for orig_line in p.stdout:
+ orig_line = orig_line.rstrip()
line = ansi_strip(orig_line)
mo = call_re.match(line)
if mo:
if function_name in ignored_function_names:
continue
if function_name == 'glXSwapBuffers':
- double_buffer = True
+ swapbuffers += 1
+ if function_name in ('glFlush', 'glFinish'):
+ flushes += 1
#print orig_line
+ p.wait()
+ if p.returncode != 0:
+ sys.stdout.write('FAIL (tracedump)\n')
+ return
- args = ['./glretrace']
- if double_buffer:
+ args = [os.path.join(options.build, 'glretrace')]
+ if swapbuffers:
args += ['-db']
- args += ['-s', '/tmp/' + demo.replace('/', '-') + '.']
+ frames = swapbuffers
+ else:
+ args += ['-sb']
+ frames = flushes
+ if os.path.exists(ref_image) and frames < 10:
+ snapshot_prefix = os.path.join(options.results, demo.replace('/', '-') + '.')
+ args += ['-s', snapshot_prefix]
+ else:
+ snapshot_prefix = None
args += [trace]
p = popen(args, stdout=subprocess.PIPE)
- stdout, _ = p.communicate()
image_re = re.compile('^Wrote (.*\.png)$')
image = None
- for line in stdout.split('\n'):
+ for line in p.stdout:
+ line = line.rstrip()
mo = image_re.match(line)
if mo:
image = mo.group(1)
-
+ p.wait()
+ if p.returncode != 0:
+ sys.stdout.write('FAIL (glretrace)\n')
+ return
+
if image:
- delta_image = demo.replace('/', '-') + '.diff.png'
- p = popen(["compare", '-alpha', 'opaque', '-metric', 'AE', '-fuzz', '5%', ref_image, image, delta_image])
+ delta_image = os.path.join(options.results, demo.replace('/', '-') + '.diff.png')
+ p = popen([
+ 'compare',
+ '-alpha', 'opaque',
+ '-metric', 'AE',
+ '-fuzz', '5%',
+ '-dissimilarity-threshold', '1',
+ ref_image, image, delta_image
+ ], stderr = subprocess.PIPE)
_, stderr = p.communicate()
+ try:
+ ae = int(stderr)
+ except ValueError:
+ ae = 9999
+
+ if ae:
+ html.write(' <tr>\n')
+ image_tag(html, ref_image)
+ image_tag(html, image)
+ image_tag(html, delta_image)
+ html.write(' </tr>\n')
+ html.flush()
+
+ sys.stdout.write('FAIL (snapshot)\n')
+ return
+
+ sys.stdout.write('PASS\n')
+
tests = [
'trivial/clear-color',
'trivial/vp-tri-tex',
'trivial/vp-unfilled',
- #'demos/arbfplight',
- #'demos/arbfslight',
- #'demos/arbocclude',
- #'demos/arbocclude2',
- #'demos/bounce',
- #'demos/clearspd',
- #'demos/copypix',
- #'demos/cubemap',
- #'demos/dinoshade',
- #'demos/dissolve',
- #'demos/drawpix',
- #'demos/engine',
- #'demos/fbo_firecube',
- #'demos/fbotexture',
- #'demos/fire',
- #'demos/fogcoord',
- #'demos/fplight',
- #'demos/fslight',
- #'demos/gamma',
- #'demos/gearbox',
- #'demos/gears',
- #'demos/geartrain',
- #'demos/glinfo',
- #'demos/gloss',
- #'demos/gltestperf',
- #'demos/ipers',
- #'demos/isosurf',
- #'demos/lodbias',
- #'demos/morph3d',
- #'demos/multiarb',
- #'demos/paltex',
- #'demos/pointblast',
- #'demos/projtex',
- #'demos/rain',
- #'demos/ray',
- #'demos/readpix',
- #'demos/reflect',
- #'demos/renormal',
- #'demos/shadowtex',
- #'demos/singlebuffer',
- #'demos/spectex',
- #'demos/spriteblast',
- #'demos/stex3d',
- #'demos/teapot',
- #'demos/terrain',
- #'demos/tessdemo',
- #'demos/texcyl',
- #'demos/texenv',
- #'demos/textures',
- #'demos/trispd',
- #'demos/tunnel',
- #'demos/tunnel2',
- #'demos/vao_demo',
- #'demos/winpos',
- #'fp/fp-tri',
- #'fp/point-position',
- #'fp/tri-depth',
- #'fp/tri-depth2',
- #'fp/tri-depthwrite',
- #'fp/tri-depthwrite2',
- #'fp/tri-param',
- #'fp/tri-tex',
+ 'demos/arbfplight',
+ 'demos/arbfslight',
+ 'demos/arbocclude',
+ 'demos/arbocclude2',
+ 'demos/bounce',
+ 'demos/clearspd',
+ 'demos/copypix',
+ 'demos/cubemap',
+ 'demos/dinoshade',
+ 'demos/dissolve',
+ 'demos/drawpix',
+ 'demos/engine',
+ 'demos/fbo_firecube',
+ 'demos/fbotexture',
+ 'demos/fire',
+ 'demos/fogcoord',
+ 'demos/fplight',
+ 'demos/fslight',
+ 'demos/gamma',
+ 'demos/gearbox',
+ 'demos/gears',
+ 'demos/geartrain',
+ 'demos/glinfo',
+ 'demos/gloss',
+ 'demos/gltestperf',
+ 'demos/ipers',
+ 'demos/isosurf',
+ 'demos/lodbias',
+ 'demos/morph3d',
+ 'demos/multiarb',
+ 'demos/paltex',
+ 'demos/pointblast',
+ 'demos/projtex',
+ 'demos/rain',
+ 'demos/ray',
+ 'demos/readpix',
+ 'demos/reflect',
+ 'demos/renormal',
+ 'demos/shadowtex',
+ 'demos/singlebuffer',
+ 'demos/spectex',
+ 'demos/spriteblast',
+ 'demos/stex3d',
+ 'demos/teapot',
+ 'demos/terrain',
+ 'demos/tessdemo',
+ 'demos/texcyl',
+ 'demos/texenv',
+ 'demos/textures',
+ 'demos/trispd',
+ 'demos/tunnel',
+ 'demos/tunnel2',
+ 'demos/vao_demo',
+ 'demos/winpos',
+
+ #'fp/fp-tri', # XXX: parameterized
+ 'fp/point-position',
+ 'fp/tri-depth',
+ 'fp/tri-depth2',
+ 'fp/tri-depthwrite',
+ 'fp/tri-depthwrite2',
+ 'fp/tri-param',
+ 'fp/tri-tex',
+
#'fpglsl/fp-tri',
- #'glsl/array',
- #'glsl/bezier',
- #'glsl/bitmap',
- #'glsl/brick',
- #'glsl/bump',
- #'glsl/convolutions',
- #'glsl/deriv',
- #'glsl/fragcoord',
- #'glsl/fsraytrace',
- #'glsl/geom-sprites',
- #'glsl/geom-stipple-lines',
- #'glsl/geom-wide-lines',
- #'glsl/identity',
- #'glsl/linktest',
- #'glsl/mandelbrot',
- #'glsl/multinoise',
- #'glsl/multitex',
- #'glsl/noise',
- #'glsl/noise2',
- #'glsl/pointcoord',
- #'glsl/points',
- #'glsl/samplers',
- #'glsl/shadow_sampler',
- #'glsl/shtest',
- #'glsl/skinning',
- #'glsl/texaaline',
- #'glsl/texdemo1',
- #'glsl/toyball',
- #'glsl/trirast',
- #'glsl/twoside',
- #'glsl/vert-or-frag-only',
- #'glsl/vert-tex',
- #'glsl/vsraytrace',
+
+ 'glsl/array',
+ 'glsl/bezier',
+ 'glsl/bitmap',
+ 'glsl/brick',
+ 'glsl/bump',
+ 'glsl/convolutions',
+ 'glsl/deriv',
+ 'glsl/fragcoord',
+ 'glsl/fsraytrace',
+ 'glsl/geom-sprites',
+ 'glsl/geom-stipple-lines',
+ 'glsl/geom-wide-lines',
+ 'glsl/identity',
+ 'glsl/linktest',
+ 'glsl/mandelbrot',
+ 'glsl/multinoise',
+ 'glsl/multitex',
+ 'glsl/noise',
+ 'glsl/noise2',
+ 'glsl/pointcoord',
+ 'glsl/points',
+ 'glsl/samplers',
+ 'glsl/shadow_sampler',
+ 'glsl/shtest',
+ 'glsl/skinning',
+ 'glsl/texaaline',
+ 'glsl/texdemo1',
+ 'glsl/toyball',
+ 'glsl/trirast',
+ 'glsl/twoside',
+ 'glsl/vert-or-frag-only',
+ 'glsl/vert-tex',
+ 'glsl/vsraytrace',
+
#'gs/gs-tri',
+
#'perf/copytex',
#'perf/drawoverhead',
#'perf/fbobind',
#'perf/teximage',
#'perf/vbo',
#'perf/vertexrate',
- #'redbook/aaindex',
- #'redbook/aapoly',
- #'redbook/aargb',
- #'redbook/accanti',
- #'redbook/accpersp',
- #'redbook/alpha',
- #'redbook/alpha3D',
- #'redbook/anti',
- #'redbook/bezcurve',
- #'redbook/bezmesh',
- #'redbook/checker',
- #'redbook/clip',
- #'redbook/colormat',
- #'redbook/combiner',
- #'redbook/convolution',
- #'redbook/cube',
- #'redbook/cubemap',
- #'redbook/depthcue',
- #'redbook/dof',
- #'redbook/double',
- #'redbook/drawf',
- #'redbook/feedback',
- #'redbook/fog',
- #'redbook/fogcoord',
- #'redbook/fogindex',
- #'redbook/font',
- #'redbook/hello',
- #'redbook/histogram',
- #'redbook/image',
- #'redbook/light',
- #'redbook/lines',
- #'redbook/list',
- #'redbook/material',
- #'redbook/minmax',
- #'redbook/mipmap',
- #'redbook/model',
- #'redbook/movelight',
- #'redbook/multisamp',
- #'redbook/multitex',
- #'redbook/mvarray',
- #'redbook/nurbs',
- #'redbook/pickdepth',
- #'redbook/picksquare',
- #'redbook/plane',
- #'redbook/planet',
- #'redbook/pointp',
- #'redbook/polyoff',
- #'redbook/polys',
- #'redbook/quadric',
- #'redbook/robot',
- #'redbook/sccolorlight',
- #'redbook/scene',
- #'redbook/scenebamb',
- #'redbook/sceneflat',
- #'redbook/select',
- #'redbook/shadowmap',
- #'redbook/smooth',
- #'redbook/stencil',
- #'redbook/stroke',
- #'redbook/surface',
- #'redbook/surfpoints',
- #'redbook/teaambient',
- #'redbook/teapots',
- #'redbook/tess',
- #'redbook/tesswind',
- #'redbook/texbind',
- #'redbook/texgen',
- #'redbook/texprox',
- #'redbook/texsub',
- #'redbook/texture3d',
- #'redbook/texturesurf',
- #'redbook/torus',
- #'redbook/trim',
- #'redbook/unproject',
- #'redbook/varray',
- #'redbook/wrap',
- #'samples/accum',
- #'samples/bitmap1',
- #'samples/bitmap2',
- #'samples/blendeq',
- #'samples/blendxor',
- #'samples/copy',
- #'samples/cursor',
- #'samples/depth',
- #'samples/eval',
- #'samples/fog',
- #'samples/font',
- #'samples/line',
- #'samples/logo',
- #'samples/nurb',
- #'samples/oglinfo',
- #'samples/olympic',
- #'samples/overlay',
- #'samples/point',
- #'samples/prim',
- #'samples/quad',
- #'samples/rgbtoppm',
- #'samples/select',
- #'samples/shape',
- #'samples/sphere',
- #'samples/star',
- #'samples/stencil',
- #'samples/stretch',
- #'samples/texture',
- #'samples/tri',
- #'samples/wave',
+
+ 'redbook/aaindex',
+ 'redbook/aapoly',
+ 'redbook/aargb',
+ 'redbook/accanti',
+ 'redbook/accpersp',
+ 'redbook/alpha',
+ 'redbook/alpha3D',
+ 'redbook/anti',
+ 'redbook/bezcurve',
+ 'redbook/bezmesh',
+ 'redbook/checker',
+ 'redbook/clip',
+ 'redbook/colormat',
+ 'redbook/combiner',
+ 'redbook/convolution',
+ 'redbook/cube',
+ 'redbook/cubemap',
+ 'redbook/depthcue',
+ 'redbook/dof',
+ 'redbook/double',
+ 'redbook/drawf',
+ 'redbook/feedback',
+ 'redbook/fog',
+ 'redbook/fogcoord',
+ 'redbook/fogindex',
+ 'redbook/font',
+ 'redbook/hello',
+ 'redbook/histogram',
+ 'redbook/image',
+ 'redbook/light',
+ 'redbook/lines',
+ 'redbook/list',
+ 'redbook/material',
+ 'redbook/minmax',
+ 'redbook/mipmap',
+ 'redbook/model',
+ 'redbook/movelight',
+ 'redbook/multisamp',
+ 'redbook/multitex',
+ 'redbook/mvarray',
+ 'redbook/nurbs',
+ 'redbook/pickdepth',
+ 'redbook/picksquare',
+ 'redbook/plane',
+ 'redbook/planet',
+ 'redbook/pointp',
+ 'redbook/polyoff',
+ 'redbook/polys',
+ 'redbook/quadric',
+ 'redbook/robot',
+ 'redbook/sccolorlight',
+ 'redbook/scene',
+ 'redbook/scenebamb',
+ 'redbook/sceneflat',
+ 'redbook/select',
+ 'redbook/shadowmap',
+ 'redbook/smooth',
+ 'redbook/stencil',
+ 'redbook/stroke',
+ 'redbook/surface',
+ 'redbook/surfpoints',
+ 'redbook/teaambient',
+ 'redbook/teapots',
+ 'redbook/tess',
+ 'redbook/tesswind',
+ 'redbook/texbind',
+ 'redbook/texgen',
+ 'redbook/texprox',
+ 'redbook/texsub',
+ 'redbook/texture3d',
+ 'redbook/texturesurf',
+ 'redbook/torus',
+ 'redbook/trim',
+ 'redbook/unproject',
+ 'redbook/varray',
+ 'redbook/wrap',
+
+ 'samples/accum',
+ 'samples/bitmap1',
+ 'samples/bitmap2',
+ 'samples/blendeq',
+ 'samples/blendxor',
+ 'samples/copy',
+ 'samples/cursor',
+ 'samples/depth',
+ 'samples/eval',
+ 'samples/fog',
+ 'samples/font',
+ 'samples/line',
+ 'samples/logo',
+ 'samples/nurb',
+ 'samples/oglinfo',
+ 'samples/olympic',
+ 'samples/overlay',
+ 'samples/point',
+ 'samples/prim',
+ 'samples/quad',
+ 'samples/rgbtoppm',
+ 'samples/select',
+ 'samples/shape',
+ 'samples/sphere',
+ 'samples/star',
+ 'samples/stencil',
+ 'samples/stretch',
+ 'samples/texture',
+ 'samples/tri',
+ 'samples/wave',
+
#'slang/cltest',
#'slang/sotest',
#'slang/vstest',
+
'tests/afsmultiarb',
'tests/antialias',
'tests/arbfpspec',
'tests/bumpmap',
'tests/calibrate_rast',
'tests/condrender',
- 'tests/copypixrate',
+ #'tests/copypixrate', # XXX: benchmark
'tests/cva',
'tests/cva_huge',
'tests/cylwrap',
'tests/fbotest1',
'tests/fbotest2',
'tests/fbotest3',
- 'tests/fillrate',
+ #'tests/fillrate', # XXX: benchmark
'tests/floattex',
'tests/fogcoord',
'tests/fptest1',
'tests/prog_parameter',
'tests/quads',
'tests/random',
- 'tests/readrate',
+ #'tests/readrate', # XXX: benchmark
'tests/rubberband',
'tests/scissor',
'tests/scissor-viewport',
'tests/step',
'tests/streaming_rect',
'tests/subtex',
- 'tests/subtexrate',
+ #'tests/subtexrate', # XXX: benchmark
'tests/tex1d',
'tests/texcmp',
'tests/texcompress2',
'tests/zcomp',
'tests/zdrawpix',
'tests/zreaddraw',
+
#'vp/vp-tris',
#'vpglsl/vp-tris',
- #'xdemos/corender',
- #'xdemos/glsync',
- #'xdemos/glthreads',
- #'xdemos/glxcontexts',
- #'xdemos/glxdemo',
- #'xdemos/glxgears',
- #'xdemos/glxgears_fbconfig',
- #'xdemos/glxgears_pixmap',
- #'xdemos/glxheads',
- #'xdemos/glxinfo',
- #'xdemos/glxpbdemo',
- #'xdemos/glxpixmap',
- #'xdemos/glxsnoop',
- #'xdemos/glxswapcontrol',
- #'xdemos/manywin',
- #'xdemos/msctest',
- #'xdemos/multictx',
- #'xdemos/offset',
- #'xdemos/omlsync',
- #'xdemos/opencloseopen',
- #'xdemos/overlay',
- #'xdemos/pbdemo',
- #'xdemos/pbinfo',
- #'xdemos/shape',
- #'xdemos/sharedtex',
- #'xdemos/sharedtex_mt',
- #'xdemos/texture_from_pixmap',
- #'xdemos/wincopy',
- #'xdemos/xfont',
- #'xdemos/xrotfontdemo',
- #'xdemos/yuvrect_client',
+
+ 'xdemos/corender',
+ 'xdemos/glsync',
+ #'xdemos/glthreads', # XXX: multithreaded
+ 'xdemos/glxcontexts',
+ 'xdemos/glxdemo',
+ 'xdemos/glxgears',
+ 'xdemos/glxgears_fbconfig',
+ 'xdemos/glxgears_pixmap',
+ 'xdemos/glxheads',
+ 'xdemos/glxinfo',
+ 'xdemos/glxpbdemo',
+ 'xdemos/glxpixmap',
+ 'xdemos/glxsnoop',
+ 'xdemos/glxswapcontrol',
+ 'xdemos/manywin',
+ 'xdemos/msctest',
+ 'xdemos/multictx',
+ 'xdemos/offset',
+ 'xdemos/omlsync',
+ 'xdemos/opencloseopen',
+ 'xdemos/overlay',
+ 'xdemos/pbdemo',
+ 'xdemos/pbinfo',
+ 'xdemos/shape',
+ 'xdemos/sharedtex',
+ #'xdemos/sharedtex_mt', # XXX: multithreaded
+ 'xdemos/texture_from_pixmap',
+ 'xdemos/wincopy',
+ 'xdemos/xfont',
+ 'xdemos/xrotfontdemo',
+ 'xdemos/yuvrect_client',
]
-tests = [
+_tests = [
'trivial/tri',
'trivial/tri-tex',
]
optparser.add_option(
'--build', metavar='PATH',
type='string', dest='build', default='.',
- help='path to apitrace build')
-
+ help='path to apitrace build [default=%default]')
+ optparser.add_option(
+ '--results', metavar='PATH',
+ type='string', dest='results', default='results',
+ help='results directory [default=%default]')
optparser.add_option(
'--mesa-demos', metavar='PATH',
type='string', dest='mesa_demos', default=os.environ.get('MESA_DEMOS'),
- help='path to mesa demos')
+ help='path to Mesa demos [default=%default]')
(options, args) = optparser.parse_args(sys.argv[1:])
- if args:
- tests = args
- for test in tests:
- runtest(test)
+ if not options.mesa_demos:
+ optparser.error('path to Mesa demos not specified')
+ if not os.path.exists(options.results):
+ os.makedirs(options.results)
+
+ if args:
+ testlist = []
+ for arg in args:
+ if arg.endswith('/'):
+ for test in tests:
+ if test.startswith(arg):
+ testlist.append(test)
+ else:
+ testlist.append(arg)
+ else:
+ testlist = tests
+
+ html = open(os.path.join(options.results, 'index.html'), 'wt')
+ html.write('<html>\n')
+ html.write(' <body>\n')
+ html.write(' <table border="1">\n')
+ html.write(' <tr><th>Ref</th><th>Src</th><th>Δ</th></tr>\n')
+ for test in testlist:
+ runtest(html, test)
+ html.write(' </table>\n')
+ html.write(' </body>\n')
+ html.write('</html>\n')
if __name__ == '__main__':