summaryrefslogtreecommitdiff
path: root/run.py
blob: 03961b0c3c88509d6af5caba4e7fdcee15df2103 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#!/usr/bin/env python3

import re
import sys
import os
import time
import argparse
import subprocess
from concurrent.futures import ThreadPoolExecutor
from multiprocessing import cpu_count


def process_directories(items):
    for item in items:
        if os.path.isfile(item):
            yield item
        else:
            for dirpath, _, filenames in os.walk(item):
                for fname in filenames:
                    if os.path.splitext(fname)[1] == '.shader_test':
                        yield os.path.join(dirpath, fname)


def run_test(filename):
    if ".out" in filename:
        return ""

    timebefore = time.time()

    try:
        p = subprocess.Popen(
            ['./bin/shader_runner', filename, '-auto', '-fbo'],
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE)
        (stdout, stderr) = p.communicate()
        results = (stdout + stderr).decode("utf-8")
    except KeyboardInterrupt:
        exit(1)
    except:
        return filename + " FAIL\n"

    timeafter = time.time()

    with open(filename + '.out', 'w') as file:
        file.write(results)

    counts = {}

    lines = (line for line in results.splitlines())
    re_number = re.compile(
        r'Native code for (unnamed )?(fragment|vertex|geometry) (shader|program) (?P<number>\d+)')
    for line in lines:
        shader = re_number.match(line)
        if shader and int(shader.group('number')) > 0:
            break
    else:
        raise Exception('Only shader 0 found. {}'.format(filename))

    re_search = re.compile(
        r'(?P<stage>[A-Za-z0-9]+) (vec4 )?shader\: (?P<count>\d+) instructions.')
    for line in lines:
        match = re_search.match(line)
        if match is not None:
            counts[match.group('stage')] = int(match.group('count'))

    assert counts, 'File: {} does not have any shaders'.format(filename)

    timestr = "    {:.3f} secs".format(timeafter - timebefore)
    out = ''
    for k, v in counts.items():
        if v != 0:
            out += "{0:40} {1} : {2:6}{3}\n".format(filename, k, v, timestr)
            timestr = ""
    return out


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("shader",
                        nargs='*',
                        default=['shaders'],
                        metavar="<shader_file | shader dir>",
                        help="A shader file or directory containing shader "
                             "files. Defaults to 'shaders/'")
    args = parser.parse_args()

    os.environ["shader_precompile"] = "true"
    os.environ["allow_glsl_extension_directive_midshader"] = "true"
    os.environ["PIGLIT_PLATFORM"] = "gbm"
    if "INTEL_DEBUG" in os.environ:
        print("Warning: INTEL_DEBUG environment variable set!", file=sys.stderr)
        os.environ["INTEL_DEBUG"] += ",vs,gs,fs"
    else:
        os.environ["INTEL_DEBUG"] = "vs,gs,fs"

    try:
        os.stat("bin/shader_runner")
    except OSError:
        print("./bin must be a symlink to a built piglit bin directory")
        sys.exit(1)

    runtimebefore = time.time()

    filenames = process_directories(args.shader)

    executor = ThreadPoolExecutor(cpu_count())
    for t in executor.map(run_test, filenames):
        sys.stdout.write(t)

    runtime = time.time() - runtimebefore
    print("shader-db run completed in {:.1f} secs".format(runtime))


if __name__ == "__main__":
    main()