]> git.cworth.org Git - apitrace-tests/blob - mesademos.py
Ignore results.
[apitrace-tests] / mesademos.py
1 #!/usr/bin/env python
2 ##########################################################################
3 #
4 # Copyright 2011 Jose Fonseca
5 # All Rights Reserved.
6 #
7 # Permission is hereby granted, free of charge, to any person obtaining a copy
8 # of this software and associated documentation files (the "Software"), to deal
9 # in the Software without restriction, including without limitation the rights
10 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 # copies of the Software, and to permit persons to whom the Software is
12 # furnished to do so, subject to the following conditions:
13 #
14 # The above copyright notice and this permission notice shall be included in
15 # all copies or substantial portions of the Software.
16 #
17 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 # THE SOFTWARE.
24 #
25 ##########################################################################/
26
27
28 '''Apitrace test suite based on Mesa demos.'''
29
30
31
32 import os.path
33 import optparse
34 import sys
35 import subprocess
36 import time
37 import re
38 import signal
39
40
41 ansi_re = re.compile('\x1b\[[0-9]{1,2}(;[0-9]{1,2}){0,2}m')
42
43
44 def ansi_strip(s):
45     # http://www.theeggeadventure.com/wikimedia/index.php/Linux_Tips#Use_sed_to_remove_ANSI_colors
46     return ansi_re.sub('', s)
47
48
49 def popen(command, *args, **kwargs):
50     if 'cwd' in kwargs:
51         sys.stdout.write('cd %s && ' % kwargs['cwd'])
52     if 'env' in kwargs:
53         for name, value in kwargs['env'].iteritems():
54             if value != os.environ.get(name, None):
55                 sys.stdout.write('%s=%s ' % (name, value))
56     sys.stdout.write(' '.join(command) + '\n')
57     sys.stdout.flush()
58     return subprocess.Popen(command, *args, **kwargs)
59
60
61 ignored_function_names = set([
62     'glGetString',
63     'glXGetCurrentDisplay',
64     'glXGetClientString',
65     'glXGetProcAddress',
66     'glXGetProcAddressARB',
67     'glXQueryVersion',
68     'glXGetVisualFromFBConfig',
69     'glXChooseFBConfig',
70     'glXCreateNewContext',
71     'glXMakeContextCurrent',
72     'glXQueryExtension',
73     'glXIsDirect',
74 ])
75
76
77 def image_tag(html, image):
78     url = os.path.relpath(image, options.results)
79     html.write('        <td><a href="%s"><img src="%s"/></a></td>\n' % (url, url))
80
81
82 def runtest(html, demo):
83
84     app = os.path.join(options.mesa_demos, 'src', demo)
85
86     dirname, basename = os.path.split(app)
87
88     trace = os.path.abspath(os.path.join(options.results, demo.replace('/', '-') + '.trace'))
89
90     env = os.environ.copy()
91     env['LD_PRELOAD'] = os.path.abspath(os.path.join(options.build, 'glxtrace.so'))
92     env['TRACE_FILE'] = trace
93
94     args = [os.path.join('.', basename)]
95     window_name = args[0]
96
97     p = popen(args, cwd=dirname)
98     for i in range(6):
99         time.sleep(0.5)
100         if p.poll() is not None:
101             break
102         if subprocess.call(['xwininfo', '-name', window_name], stdout=subprocess.PIPE, stderr=subprocess.PIPE) == 0:
103             break
104     if p.returncode is None:
105         p.terminate()
106     elif p.returncode:
107         sys.stdout.write('SKIP (app)\n')
108         return
109
110     ref_image = os.path.join(options.results, demo.replace('/', '-') + '.ref.png')
111     p = popen(args, env=env, cwd=dirname)
112     try:
113         for i in range(10):
114             time.sleep(0.5)
115             if p.poll() is not None:
116                 break
117             if subprocess.call(['xwininfo', '-name', window_name], stdout=subprocess.PIPE, stderr=subprocess.PIPE) == 0:
118                 break
119
120         if p.returncode is None:
121             subprocess.call("xwd -name '%s' | xwdtopnm | pnmtopng > '%s'" % (args[0], ref_image), shell=True)
122     finally:
123         if p.returncode is None:
124             p.terminate()
125             p.wait()
126         elif p.returncode:
127             print p.returncode
128             sys.stdout.write('FAIL (trace)\n')
129             return
130
131     p = popen([os.path.join(options.build, 'tracedump'), trace], stdout=subprocess.PIPE)
132     call_re = re.compile('^([0-9]+) (\w+)\(')
133     swapbuffers = 0
134     flushes = 0
135     for orig_line in p.stdout:
136         orig_line = orig_line.rstrip()
137         line = ansi_strip(orig_line)
138         mo = call_re.match(line)
139         if mo:
140             call_no = int(mo.group(1))
141             function_name = mo.group(2)
142             if function_name in ignored_function_names:
143                 continue
144             if function_name == 'glXSwapBuffers':
145                 swapbuffers += 1
146             if function_name in ('glFlush', 'glFinish'):
147                 flushes += 1
148         #print orig_line
149     p.wait()
150     if p.returncode != 0:
151         sys.stdout.write('FAIL (tracedump)\n')
152         return
153
154     args = [os.path.join(options.build, 'glretrace')]
155     if swapbuffers:
156         args += ['-db']
157         frames = swapbuffers
158     else:
159         args += ['-sb']
160         frames = flushes
161     if os.path.exists(ref_image) and frames < 10:
162         snapshot_prefix = os.path.join(options.results, demo.replace('/', '-') + '.')
163         args += ['-s', snapshot_prefix]
164     else:
165         snapshot_prefix = None
166     args += [trace]
167     p = popen(args, stdout=subprocess.PIPE)
168     image_re = re.compile('^Wrote (.*\.png)$')
169     image = None
170     for line in p.stdout:
171         line = line.rstrip()
172         mo = image_re.match(line)
173         if mo:
174             image = mo.group(1)
175     p.wait()
176     if p.returncode != 0:
177         sys.stdout.write('FAIL (glretrace)\n')
178         return
179
180     if image:
181         delta_image = os.path.join(options.results, demo.replace('/', '-') + '.diff.png')
182         p = popen([
183             'compare',
184             '-alpha', 'opaque',
185             '-metric', 'AE',
186             '-fuzz', '5%',
187             '-dissimilarity-threshold', '1',
188             ref_image, image, delta_image
189         ], stderr = subprocess.PIPE)
190         _, stderr = p.communicate()
191
192         try:
193             ae = int(stderr)
194         except ValueError:
195             ae = 9999
196
197         if ae:
198             html.write('      <tr>\n')
199             image_tag(html, ref_image)
200             image_tag(html, image)
201             image_tag(html, delta_image)
202             html.write('      </tr>\n')
203             html.flush()
204
205             sys.stdout.write('FAIL (snapshot)\n')
206             return
207
208     sys.stdout.write('PASS\n')
209
210
211 tests = [
212     'trivial/clear-color',
213     'trivial/clear-fbo',
214     'trivial/clear-fbo-scissor',
215     'trivial/clear-fbo-tex',
216     'trivial/clear-random',
217     'trivial/clear-repeat',
218     'trivial/clear-scissor',
219     'trivial/clear-undefined',
220     'trivial/createwin',
221     'trivial/dlist-begin-call-end',
222     'trivial/dlist-dangling',
223     'trivial/dlist-degenerate',
224     'trivial/dlist-edgeflag',
225     'trivial/dlist-edgeflag-dangling',
226     'trivial/dlist-flat-tri',
227     'trivial/dlist-mat-tri',
228     'trivial/dlist-recursive-call',
229     'trivial/dlist-tri-flat-tri',
230     'trivial/dlist-tri-mat-tri',
231     'trivial/draw2arrays',
232     'trivial/drawarrays',
233     'trivial/drawelements',
234     'trivial/drawelements-large',
235     'trivial/drawrange',
236     'trivial/flat-clip',
237     'trivial/fs-tri',
238     'trivial/line',
239     'trivial/line-clip',
240     'trivial/line-cull',
241     'trivial/line-flat',
242     'trivial/line-smooth',
243     'trivial/line-stipple-wide',
244     'trivial/line-userclip',
245     'trivial/line-userclip-clip',
246     'trivial/line-userclip-nop',
247     'trivial/line-userclip-nop-clip',
248     'trivial/line-wide',
249     'trivial/line-xor',
250     'trivial/lineloop',
251     'trivial/lineloop-clip',
252     'trivial/lineloop-elts',
253     'trivial/linestrip',
254     'trivial/linestrip-clip',
255     'trivial/linestrip-flat-stipple',
256     'trivial/linestrip-stipple',
257     'trivial/linestrip-stipple-wide',
258     'trivial/long-fixed-func',
259     'trivial/pgon-mode',
260     'trivial/point',
261     'trivial/point-clip',
262     'trivial/point-param',
263     'trivial/point-sprite',
264     'trivial/point-wide',
265     'trivial/point-wide-smooth',
266     'trivial/poly',
267     'trivial/poly-flat',
268     'trivial/poly-flat-clip',
269     'trivial/poly-flat-unfilled-clip',
270     'trivial/poly-unfilled',
271     'trivial/quad',
272     'trivial/quad-clip',
273     'trivial/quad-clip-all-vertices',
274     'trivial/quad-clip-nearplane',
275     'trivial/quad-degenerate',
276     'trivial/quad-flat',
277     'trivial/quad-offset-factor',
278     'trivial/quad-offset-unfilled',
279     'trivial/quad-offset-units',
280     'trivial/quad-tex-2d',
281     'trivial/quad-tex-3d',
282     'trivial/quad-tex-alpha',
283     'trivial/quad-tex-pbo',
284     'trivial/quad-tex-sub',
285     'trivial/quad-unfilled',
286     'trivial/quad-unfilled-clip',
287     'trivial/quad-unfilled-stipple',
288     'trivial/quads',
289     'trivial/quadstrip',
290     'trivial/quadstrip-clip',
291     'trivial/quadstrip-cont',
292     'trivial/quadstrip-flat',
293     'trivial/readpixels',
294     'trivial/sub-tex',
295     'trivial/tex-quads',
296     'trivial/tri',
297     'trivial/tri-alpha',
298     'trivial/tri-alpha-tex',
299     'trivial/tri-array-interleaved',
300     'trivial/tri-blend',
301     'trivial/tri-blend-color',
302     'trivial/tri-blend-max',
303     'trivial/tri-blend-min',
304     'trivial/tri-blend-revsub',
305     'trivial/tri-blend-sub',
306     'trivial/tri-clear',
307     'trivial/tri-clip',
308     'trivial/tri-cull',
309     'trivial/tri-cull-both',
310     'trivial/tri-dlist',
311     'trivial/tri-edgeflag',
312     'trivial/tri-edgeflag-array',
313     'trivial/tri-fbo',
314     'trivial/tri-fbo-tex',
315     'trivial/tri-fbo-tex-mip',
316     'trivial/tri-flat',
317     'trivial/tri-flat-clip',
318     'trivial/tri-fog',
319     'trivial/tri-fp',
320     'trivial/tri-fp-const-imm',
321     'trivial/tri-lit',
322     'trivial/tri-lit-material',
323     'trivial/tri-logicop-none',
324     'trivial/tri-logicop-xor',
325     'trivial/tri-mask-tri',
326     'trivial/tri-multitex-vbo',
327     'trivial/tri-orig',
328     'trivial/tri-point-line-clipped',
329     'trivial/tri-query',
330     'trivial/tri-repeat',
331     'trivial/tri-scissor-tri',
332     'trivial/tri-square',
333     'trivial/tri-stencil',
334     'trivial/tri-stipple',
335     'trivial/tri-tex',
336     'trivial/tri-tex-1d',
337     'trivial/tri-tex-3d',
338     'trivial/tri-tri',
339     'trivial/tri-unfilled',
340     'trivial/tri-unfilled-clip',
341     'trivial/tri-unfilled-edgeflag',
342     'trivial/tri-unfilled-fog',
343     'trivial/tri-unfilled-point',
344     'trivial/tri-unfilled-smooth',
345     'trivial/tri-unfilled-tri',
346     'trivial/tri-unfilled-tri-lit',
347     'trivial/tri-unfilled-userclip',
348     'trivial/tri-unfilled-userclip-stip',
349     'trivial/tri-userclip',
350     'trivial/tri-viewport',
351     'trivial/tri-z',
352     'trivial/tri-z-9',
353     'trivial/tri-z-eq',
354     'trivial/trifan',
355     'trivial/trifan-flat',
356     'trivial/trifan-flat-clip',
357     'trivial/trifan-flat-unfilled-clip',
358     'trivial/trifan-unfilled',
359     'trivial/tristrip',
360     'trivial/tristrip-clip',
361     'trivial/tristrip-flat',
362     'trivial/vbo-drawarrays',
363     'trivial/vbo-drawelements',
364     'trivial/vbo-drawrange',
365     'trivial/vbo-noninterleaved',
366     'trivial/vbo-tri',
367     'trivial/vp-array',
368     'trivial/vp-array-hf',
369     'trivial/vp-array-int',
370     'trivial/vp-clip',
371     'trivial/vp-line-clip',
372     'trivial/vp-tri',
373     'trivial/vp-tri-cb',
374     'trivial/vp-tri-cb-pos',
375     'trivial/vp-tri-cb-tex',
376     'trivial/vp-tri-imm',
377     'trivial/vp-tri-invariant',
378     'trivial/vp-tri-swap',
379     'trivial/vp-tri-tex',
380     'trivial/vp-unfilled',
381
382     'demos/arbfplight',
383     'demos/arbfslight',
384     'demos/arbocclude',
385     'demos/arbocclude2',
386     'demos/bounce',
387     'demos/clearspd',
388     'demos/copypix',
389     'demos/cubemap',
390     'demos/dinoshade',
391     'demos/dissolve',
392     'demos/drawpix',
393     'demos/engine',
394     'demos/fbo_firecube',
395     'demos/fbotexture',
396     'demos/fire',
397     'demos/fogcoord',
398     'demos/fplight',
399     'demos/fslight',
400     'demos/gamma',
401     'demos/gearbox',
402     'demos/gears',
403     'demos/geartrain',
404     'demos/glinfo',
405     'demos/gloss',
406     'demos/gltestperf',
407     'demos/ipers',
408     'demos/isosurf',
409     'demos/lodbias',
410     'demos/morph3d',
411     'demos/multiarb',
412     'demos/paltex',
413     'demos/pointblast',
414     'demos/projtex',
415     'demos/rain',
416     'demos/ray',
417     'demos/readpix',
418     'demos/reflect',
419     'demos/renormal',
420     'demos/shadowtex',
421     'demos/singlebuffer',
422     'demos/spectex',
423     'demos/spriteblast',
424     'demos/stex3d',
425     'demos/teapot',
426     'demos/terrain',
427     'demos/tessdemo',
428     'demos/texcyl',
429     'demos/texenv',
430     'demos/textures',
431     'demos/trispd',
432     'demos/tunnel',
433     'demos/tunnel2',
434     'demos/vao_demo',
435     'demos/winpos',
436
437     #'fp/fp-tri', # XXX: parameterized
438     'fp/point-position',
439     'fp/tri-depth',
440     'fp/tri-depth2',
441     'fp/tri-depthwrite',
442     'fp/tri-depthwrite2',
443     'fp/tri-param',
444     'fp/tri-tex',
445
446     #'fpglsl/fp-tri',
447
448     'glsl/array',
449     'glsl/bezier',
450     'glsl/bitmap',
451     'glsl/brick',
452     'glsl/bump',
453     'glsl/convolutions',
454     'glsl/deriv',
455     'glsl/fragcoord',
456     'glsl/fsraytrace',
457     'glsl/geom-sprites',
458     'glsl/geom-stipple-lines',
459     'glsl/geom-wide-lines',
460     'glsl/identity',
461     'glsl/linktest',
462     'glsl/mandelbrot',
463     'glsl/multinoise',
464     'glsl/multitex',
465     'glsl/noise',
466     'glsl/noise2',
467     'glsl/pointcoord',
468     'glsl/points',
469     'glsl/samplers',
470     'glsl/shadow_sampler',
471     'glsl/shtest',
472     'glsl/skinning',
473     'glsl/texaaline',
474     'glsl/texdemo1',
475     'glsl/toyball',
476     'glsl/trirast',
477     'glsl/twoside',
478     'glsl/vert-or-frag-only',
479     'glsl/vert-tex',
480     'glsl/vsraytrace',
481
482     #'gs/gs-tri',
483
484     #'perf/copytex',
485     #'perf/drawoverhead',
486     #'perf/fbobind',
487     #'perf/fill',
488     #'perf/genmipmap',
489     #'perf/readpixels',
490     #'perf/swapbuffers',
491     #'perf/teximage',
492     #'perf/vbo',
493     #'perf/vertexrate',
494
495     'redbook/aaindex',
496     'redbook/aapoly',
497     'redbook/aargb',
498     'redbook/accanti',
499     'redbook/accpersp',
500     'redbook/alpha',
501     'redbook/alpha3D',
502     'redbook/anti',
503     'redbook/bezcurve',
504     'redbook/bezmesh',
505     'redbook/checker',
506     'redbook/clip',
507     'redbook/colormat',
508     'redbook/combiner',
509     'redbook/convolution',
510     'redbook/cube',
511     'redbook/cubemap',
512     'redbook/depthcue',
513     'redbook/dof',
514     'redbook/double',
515     'redbook/drawf',
516     'redbook/feedback',
517     'redbook/fog',
518     'redbook/fogcoord',
519     'redbook/fogindex',
520     'redbook/font',
521     'redbook/hello',
522     'redbook/histogram',
523     'redbook/image',
524     'redbook/light',
525     'redbook/lines',
526     'redbook/list',
527     'redbook/material',
528     'redbook/minmax',
529     'redbook/mipmap',
530     'redbook/model',
531     'redbook/movelight',
532     'redbook/multisamp',
533     'redbook/multitex',
534     'redbook/mvarray',
535     'redbook/nurbs',
536     'redbook/pickdepth',
537     'redbook/picksquare',
538     'redbook/plane',
539     'redbook/planet',
540     'redbook/pointp',
541     'redbook/polyoff',
542     'redbook/polys',
543     'redbook/quadric',
544     'redbook/robot',
545     'redbook/sccolorlight',
546     'redbook/scene',
547     'redbook/scenebamb',
548     'redbook/sceneflat',
549     'redbook/select',
550     'redbook/shadowmap',
551     'redbook/smooth',
552     'redbook/stencil',
553     'redbook/stroke',
554     'redbook/surface',
555     'redbook/surfpoints',
556     'redbook/teaambient',
557     'redbook/teapots',
558     'redbook/tess',
559     'redbook/tesswind',
560     'redbook/texbind',
561     'redbook/texgen',
562     'redbook/texprox',
563     'redbook/texsub',
564     'redbook/texture3d',
565     'redbook/texturesurf',
566     'redbook/torus',
567     'redbook/trim',
568     'redbook/unproject',
569     'redbook/varray',
570     'redbook/wrap',
571
572     'samples/accum',
573     'samples/bitmap1',
574     'samples/bitmap2',
575     'samples/blendeq',
576     'samples/blendxor',
577     'samples/copy',
578     'samples/cursor',
579     'samples/depth',
580     'samples/eval',
581     'samples/fog',
582     'samples/font',
583     'samples/line',
584     'samples/logo',
585     'samples/nurb',
586     'samples/oglinfo',
587     'samples/olympic',
588     'samples/overlay',
589     'samples/point',
590     'samples/prim',
591     'samples/quad',
592     'samples/rgbtoppm',
593     'samples/select',
594     'samples/shape',
595     'samples/sphere',
596     'samples/star',
597     'samples/stencil',
598     'samples/stretch',
599     'samples/texture',
600     'samples/tri',
601     'samples/wave',
602
603     #'slang/cltest',
604     #'slang/sotest',
605     #'slang/vstest',
606
607     'tests/afsmultiarb',
608     'tests/antialias',
609     'tests/arbfpspec',
610     'tests/arbfptest1',
611     'tests/arbfptexture',
612     'tests/arbfptrig',
613     'tests/arbgpuprog',
614     'tests/arbnpot',
615     'tests/arbnpot-mipmap',
616     'tests/arbvptest1',
617     'tests/arbvptest3',
618     'tests/arbvptorus',
619     'tests/arbvpwarpmesh',
620     'tests/arraytexture',
621     'tests/auxbuffer',
622     'tests/blendxor',
623     'tests/blitfb',
624     'tests/bufferobj',
625     'tests/bug_3050',
626     'tests/bug_3101',
627     'tests/bug_3195',
628     'tests/bug_texstore_i8',
629     'tests/bumpmap',
630     'tests/calibrate_rast',
631     'tests/condrender',
632     #'tests/copypixrate', # XXX: benchmark
633     'tests/cva',
634     'tests/cva_huge',
635     'tests/cylwrap',
636     'tests/drawbuffers',
637     'tests/drawbuffers2',
638     'tests/drawstencil',
639     'tests/exactrast',
640     'tests/ext422square',
641     'tests/fbotest1',
642     'tests/fbotest2',
643     'tests/fbotest3',
644     #'tests/fillrate', # XXX: benchmark
645     'tests/floattex',
646     'tests/fogcoord',
647     'tests/fptest1',
648     'tests/fptexture',
649     'tests/getteximage',
650     'tests/glutfx',
651     'tests/interleave',
652     'tests/invert',
653     'tests/jkrahntest',
654     'tests/lineclip',
655     'tests/manytex',
656     'tests/mapbufrange',
657     'tests/minmag',
658     'tests/mipgen',
659     'tests/mipmap_comp',
660     'tests/mipmap_comp_tests',
661     'tests/mipmap_limits',
662     'tests/mipmap_tunnel',
663     'tests/mipmap_view',
664     'tests/multipal',
665     'tests/multitexarray',
666     'tests/multiwindow',
667     'tests/no_s3tc',
668     'tests/occlude',
669     'tests/packedpixels',
670     'tests/pbo',
671     'tests/persp_hint',
672     'tests/prim',
673     'tests/prog_parameter',
674     'tests/quads',
675     'tests/random',
676     #'tests/readrate', # XXX: benchmark
677     'tests/rubberband',
678     'tests/scissor',
679     'tests/scissor-viewport',
680     'tests/seccolor',
681     'tests/shader-interp',
682     'tests/shader_api',
683     'tests/shadow-sample',
684     'tests/sharedtex',
685     'tests/stencilreaddraw',
686     'tests/stencilwrap',
687     'tests/step',
688     'tests/streaming_rect',
689     'tests/subtex',
690     #'tests/subtexrate', # XXX: benchmark
691     'tests/tex1d',
692     'tests/texcmp',
693     'tests/texcompress2',
694     'tests/texcompsub',
695     'tests/texdown',
696     'tests/texfilt',
697     'tests/texgenmix',
698     'tests/texleak',
699     'tests/texline',
700     'tests/texobj',
701     'tests/texobjshare',
702     'tests/texrect',
703     'tests/unfilledclip',
704     'tests/vparray',
705     'tests/vpeval',
706     'tests/vptest1',
707     'tests/vptest2',
708     'tests/vptest3',
709     'tests/vptorus',
710     'tests/vpwarpmesh',
711     'tests/yuvrect',
712     'tests/yuvsquare',
713     'tests/zbitmap',
714     'tests/zcomp',
715     'tests/zdrawpix',
716     'tests/zreaddraw',
717
718     #'vp/vp-tris',
719     #'vpglsl/vp-tris',
720
721     'xdemos/corender',
722     'xdemos/glsync',
723     #'xdemos/glthreads', # XXX: multithreaded
724     'xdemos/glxcontexts',
725     'xdemos/glxdemo',
726     'xdemos/glxgears',
727     'xdemos/glxgears_fbconfig',
728     'xdemos/glxgears_pixmap',
729     'xdemos/glxheads',
730     'xdemos/glxinfo',
731     'xdemos/glxpbdemo',
732     'xdemos/glxpixmap',
733     'xdemos/glxsnoop',
734     'xdemos/glxswapcontrol',
735     'xdemos/manywin',
736     'xdemos/msctest',
737     'xdemos/multictx',
738     'xdemos/offset',
739     'xdemos/omlsync',
740     'xdemos/opencloseopen',
741     'xdemos/overlay',
742     'xdemos/pbdemo',
743     'xdemos/pbinfo',
744     'xdemos/shape',
745     'xdemos/sharedtex',
746     #'xdemos/sharedtex_mt', # XXX: multithreaded
747     'xdemos/texture_from_pixmap',
748     'xdemos/wincopy',
749     'xdemos/xfont',
750     'xdemos/xrotfontdemo',
751     'xdemos/yuvrect_client',
752 ]
753
754
755 _tests = [
756     'trivial/tri',
757     'trivial/tri-tex',
758 ]
759
760
761 def main():
762     global options
763
764     # Parse command line options
765     optparser = optparse.OptionParser(
766         usage='\n\t%prog [options] [demo] ...',
767         version='%%prog')
768     optparser.add_option(
769         '--build', metavar='PATH',
770         type='string', dest='build', default='.',
771         help='path to apitrace build [default=%default]')
772     optparser.add_option(
773         '--results', metavar='PATH',
774         type='string', dest='results', default='results',
775         help='results directory [default=%default]')
776     optparser.add_option(
777         '--mesa-demos', metavar='PATH',
778         type='string', dest='mesa_demos', default=os.environ.get('MESA_DEMOS'),
779         help='path to Mesa demos [default=%default]')
780
781     (options, args) = optparser.parse_args(sys.argv[1:])
782
783     if not options.mesa_demos:
784         optparser.error('path to Mesa demos not specified')
785     if not os.path.exists(options.results):
786         os.makedirs(options.results)
787
788     if args:
789         testlist = []
790         for arg in args:
791             if arg.endswith('/'):
792                 for test in tests:
793                     if test.startswith(arg):
794                         testlist.append(test)
795             else:
796                 testlist.append(arg)
797     else:
798         testlist = tests
799
800     html = open(os.path.join(options.results, 'index.html'), 'wt')
801     html.write('<html>\n')
802     html.write('  <body>\n')
803     html.write('    <table border="1">\n')
804     html.write('      <tr><th>Ref</th><th>Src</th><th>&Delta;</th></tr>\n')
805     for test in testlist:
806        runtest(html, test)
807     html.write('    </table>\n')
808     html.write('  </body>\n')
809     html.write('</html>\n')
810
811
812 if __name__ == '__main__':
813     main()