]> git.cworth.org Git - apitrace-tests/blobdiff - mesademos.py
Split testing into common/different parts.
[apitrace-tests] / mesademos.py
index 4375ef8a30638c9b1908585712bacc4a28890291..21b0af444b7c86e15315e93716a1d829a8fb1c81 100755 (executable)
 import os.path
 import optparse
 import sys
-import subprocess
-import time
-import re
-import signal
 
+from test import Report, TestCase
 
-ansi_re = re.compile('\x1b\[[0-9]{1,2}(;[0-9]{1,2}){0,2}m')
-
-
-def ansi_strip(s):
-    # http://www.theeggeadventure.com/wikimedia/index.php/Linux_Tips#Use_sed_to_remove_ANSI_colors
-    return ansi_re.sub('', s)
-
-
-def popen(command, *args, **kwargs):
-    if 'cwd' in kwargs:
-        sys.stdout.write('cd %s && ' % kwargs['cwd'])
-    if 'env' in kwargs:
-        for name, value in kwargs['env'].iteritems():
-            if value != os.environ.get(name, None):
-                sys.stdout.write('%s=%s ' % (name, value))
-    sys.stdout.write(' '.join(command) + '\n')
-    sys.stdout.flush()
-    return subprocess.Popen(command, *args, **kwargs)
-
-
-ignored_function_names = set([
-    'glGetString',
-    'glXGetCurrentDisplay',
-    'glXGetClientString',
-    'glXGetProcAddress',
-    'glXGetProcAddressARB',
-    'glXQueryVersion',
-    'glXGetVisualFromFBConfig',
-    'glXChooseFBConfig',
-    'glXCreateNewContext',
-    'glXMakeContextCurrent',
-    'glXQueryExtension',
-    'glXIsDirect',
-])
-
-
-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):
 
+def runtest(report, demo):
     app = os.path.join(options.mesa_demos, 'src', demo)
-
     dirname, basename = os.path.split(app)
-    
-    trace = os.path.abspath(os.path.join(options.results, demo.replace('/', '-') + '.trace'))
-
-    env = os.environ.copy()
-    env['LD_PRELOAD'] = os.path.abspath(os.path.join(options.build, 'glxtrace.so'))
-    env['TRACE_FILE'] = trace
-    
+    name = demo.replace('/', '-')
     args = [os.path.join('.', basename)]
-    p = popen(args, env=env, cwd=dirname)
-    try:
-        window_name = args[0]
-
-        for i in range(10):
-            time.sleep(1)
-            if subprocess.call(['xwininfo', '-name', window_name], stdout=subprocess.PIPE) == 0:
-                break
-
-        ref_image = os.path.join(options.results, demo.replace('/', '-') + '.ref.png')
-        subprocess.call("xwd -name '%s' | xwdtopnm | pnmtopng > '%s'" % (args[0], ref_image), shell=True)
-
-    finally:
-        p.send_signal(signal.SIGTERM)
-
-    p = popen([os.path.join(options.build, 'tracedump'), trace], stdout=subprocess.PIPE)
-    stdout, _ = p.communicate()
-
-    call_re = re.compile('^([0-9]+) (\w+)\(')
-    double_buffer = False
-    for orig_line in stdout.split('\n'):
-        line = ansi_strip(orig_line)
-        mo = call_re.match(line)
-        if mo:
-            call_no = int(mo.group(1))
-            function_name = mo.group(2)
-            if function_name in ignored_function_names:
-                continue
-            if function_name == 'glXSwapBuffers':
-                double_buffer = True
-        #print orig_line
-
-    args = [os.path.join(options.build, 'glretrace')]
-    if double_buffer:
-        args += ['-db']
-    else:
-        args += ['-sb']
-    snapshot_prefix = os.path.join(options.results, demo.replace('/', '-') + '.')
-    args += ['-s', snapshot_prefix]
-    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'):
-        mo = image_re.match(line)
-        if mo:
-            image = mo.group(1)
-    
-    if 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\n')
-        else:
-            sys.stdout.write('PASS\n')
+
+    test = TestCase(
+        name = name,
+        args = args,
+        cwd = dirname,
+        build = options.build,
+        results = options.results,
+    )
+    test.run(report)
+
 
 
 tests = [
@@ -177,7 +59,7 @@ tests = [
     'trivial/clear-fbo-scissor',
     'trivial/clear-fbo-tex',
     'trivial/clear-random',
-    #'trivial/clear-repeat', # XXX: animated
+    'trivial/clear-repeat',
     'trivial/clear-scissor',
     'trivial/clear-undefined',
     'trivial/createwin',
@@ -251,7 +133,7 @@ tests = [
     'trivial/quads',
     'trivial/quadstrip',
     'trivial/quadstrip-clip',
-    #'trivial/quadstrip-cont', # XXX: animated
+    'trivial/quadstrip-cont',
     'trivial/quadstrip-flat',
     'trivial/readpixels',
     'trivial/sub-tex',
@@ -290,7 +172,7 @@ tests = [
     'trivial/tri-orig',
     'trivial/tri-point-line-clipped',
     'trivial/tri-query',
-    #'trivial/tri-repeat', # XXX: animated
+    'trivial/tri-repeat',
     'trivial/tri-scissor-tri',
     'trivial/tri-square',
     'trivial/tri-stencil',
@@ -342,103 +224,109 @@ tests = [
     '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/cuberender',
+    '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',
@@ -449,117 +337,121 @@ tests = [
     #'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', # XXX: animated
-    #'tests/antialias', # XXX: animated
+
+    'tests/afsmultiarb',
+    'tests/antialias',
     'tests/arbfpspec',
     'tests/arbfptest1',
     'tests/arbfptexture',
@@ -569,21 +461,21 @@ tests = [
     'tests/arbnpot-mipmap',
     'tests/arbvptest1',
     'tests/arbvptest3',
-    #'tests/arbvptorus', # XXX: animated
-    #'tests/arbvpwarpmesh', # XXX: animated
+    'tests/arbvptorus',
+    'tests/arbvpwarpmesh',
     'tests/arraytexture',
     'tests/auxbuffer',
     'tests/blendxor',
     'tests/blitfb',
-    #'tests/bufferobj', # XXX: animated
+    'tests/bufferobj',
     'tests/bug_3050',
     'tests/bug_3101',
-    #'tests/bug_3195', # XXX: animated
+    'tests/bug_3195',
     'tests/bug_texstore_i8',
     'tests/bumpmap',
-    #'tests/calibrate_rast', # XXX: animated
+    'tests/calibrate_rast',
     'tests/condrender',
-    #'tests/copypixrate', # XXX: animated
+    #'tests/copypixrate', # XXX: benchmark
     'tests/cva',
     'tests/cva_huge',
     'tests/cylwrap',
@@ -593,9 +485,9 @@ tests = [
     'tests/exactrast',
     'tests/ext422square',
     'tests/fbotest1',
-    #'tests/fbotest2', # XXX: animated
+    'tests/fbotest2',
     'tests/fbotest3',
-    #'tests/fillrate', # XXX: animated
+    #'tests/fillrate', # XXX: benchmark
     'tests/floattex',
     'tests/fogcoord',
     'tests/fptest1',
@@ -606,7 +498,7 @@ tests = [
     'tests/invert',
     'tests/jkrahntest',
     'tests/lineclip',
-    #'tests/manytex', # XXX: animated
+    'tests/manytex',
     'tests/mapbufrange',
     'tests/minmag',
     'tests/mipgen',
@@ -617,7 +509,7 @@ tests = [
     'tests/mipmap_view',
     'tests/multipal',
     'tests/multitexarray',
-    #'tests/multiwindow', # XXX: animated
+    'tests/multiwindow',
     'tests/no_s3tc',
     'tests/occlude',
     'tests/packedpixels',
@@ -625,9 +517,9 @@ tests = [
     'tests/persp_hint',
     'tests/prim',
     'tests/prog_parameter',
-    #'tests/quads', # XXX: animated
-    #'tests/random', # XXX: animated
-    #'tests/readrate', # XXX: animated
+    'tests/quads',
+    'tests/random',
+    #'tests/readrate', # XXX: benchmark
     'tests/rubberband',
     'tests/scissor',
     'tests/scissor-viewport',
@@ -635,15 +527,15 @@ tests = [
     'tests/shader-interp',
     'tests/shader_api',
     'tests/shadow-sample',
-    #'tests/sharedtex', # XXX: animated
+    'tests/sharedtex',
     'tests/stencilreaddraw',
-    #'tests/stencilwrap', # XXX: animated
+    'tests/stencilwrap',
     'tests/step',
-    #'tests/streaming_rect', # XXX: animated
+    'tests/streaming_rect',
     'tests/subtex',
-    #'tests/subtexrate', # XXX: animated
+    #'tests/subtexrate', # XXX: benchmark
     'tests/tex1d',
-    #'tests/texcmp', # XXX: animated
+    'tests/texcmp',
     'tests/texcompress2',
     'tests/texcompsub',
     'tests/texdown',
@@ -651,7 +543,7 @@ tests = [
     'tests/texgenmix',
     'tests/texleak',
     'tests/texline',
-    #'tests/texobj', # XXX: animated
+    'tests/texobj',
     'tests/texobjshare',
     'tests/texrect',
     'tests/unfilledclip',
@@ -668,39 +560,41 @@ tests = [
     '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',
 ]
 
 
@@ -723,7 +617,7 @@ def main():
         help='path to apitrace build [default=%default]')
     optparser.add_option(
         '--results', metavar='PATH',
-        type='string', dest='results', default='.',
+        type='string', dest='results', default='results',
         help='results directory [default=%default]')
     optparser.add_option(
         '--mesa-demos', metavar='PATH',
@@ -734,21 +628,22 @@ def main():
 
     if not options.mesa_demos:
         optparser.error('path to Mesa demos not specified')
-    if not os.path.exists(options.results):
-        os.makedirs(options.results)
-
-    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>&Delta;</th></tr>\n')
-    if not args:
-        args = tests
-    for test in args:
-       runtest(html, test)
-    html.write('    </table>\n')
-    html.write('  </body>\n')
-    html.write('</html>\n')
+
+    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
+
+    report = Report(options.results)
+    for test in testlist:
+       runtest(report, test)
 
 
 if __name__ == '__main__':