glsl-1.10: test mesa bug with forward declaration
[piglit.git] / tests / util / gen_dispatch.py
blob9d6530b9a12ac0263176121a119f570040fbb8f4
1 # coding=utf-8
2 # Copyright 2014 Intel Corporation
4 # Permission is hereby granted, free of charge, to any person obtaining a
5 # copy of this software and associated documentation files (the "Software"),
6 # to deal in the Software without restriction, including without limitation
7 # the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 # and/or sell copies of the Software, and to permit persons to whom the
9 # Software is furnished to do so, subject to the following conditions:
11 # The above copyright notice and this permission notice (including the next
12 # paragraph) shall be included in all copies or substantial portions of the
13 # Software.
15 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 # IN THE SOFTWARE.
24 """
25 Generate C source code from Khronos XML.
26 """
28 import argparse
29 import os.path
30 import re
31 import sys
32 import functools
33 from collections import namedtuple
35 import mako.runtime
36 import mako.template
38 PIGLIT_TOP_DIR = os.path.join(os.path.dirname(__file__), '..', '..')
39 sys.path.append(PIGLIT_TOP_DIR)
41 import registry.gl # pylint: disable=import-error
44 debug = False
47 def log_debug(msg):
48 if debug:
49 prog_name = os.path.basename(sys.argv[0])
50 print('debug: {0}: {1}'.format(prog_name, msg), file=sys.stderr)
53 def main():
54 global debug
56 argparser = argparse.ArgumentParser()
57 argparser.add_argument('-o', '--out-dir', required=True)
58 argparser.add_argument('-d', '--debug', action='store_true', default=False)
59 args = argparser.parse_args()
61 debug = args.debug
62 registry.gl.debug = debug
64 gl_registry = registry.gl.parse()
65 DispatchCode.emit(args.out_dir, gl_registry)
66 EnumCode.emit(args.out_dir, gl_registry)
69 class DispatchCode(object):
71 H_TEMPLATE = 'piglit-dispatch-gen.h.mako'
72 C_TEMPLATE = 'piglit-dispatch-gen.c.mako'
74 Api = namedtuple('DispatchApi',
75 ('name', 'base_version_int', 'c_piglit_token'))
77 APIS = {
78 'gl': Api('gl', 10, 'PIGLIT_DISPATCH_GL'),
79 'gles1': Api('gles1', 11, 'PIGLIT_DISPATCH_ES1'),
80 'gles2': Api('gles2', 20, 'PIGLIT_DISPATCH_ES2'),
82 APIS['glcore'] = APIS['gl']
84 assert set(APIS.keys()) | set(['glsc2']) | set(['disabled']) == set(registry.gl.VALID_APIS)
86 @classmethod
87 def emit(cls, out_dir, gl_registry):
88 assert isinstance(gl_registry, registry.gl.Registry)
89 context_vars = dict(dispatch=cls, gl_registry=gl_registry)
90 render_template(cls.H_TEMPLATE, out_dir, **context_vars)
91 render_template(cls.C_TEMPLATE, out_dir, **context_vars)
94 def render_template(filename, out_dir, **context_vars):
95 assert filename.endswith('.mako')
96 template_filepath = os.path.join(os.path.dirname(__file__), filename)
97 out_filepath = os.path.join(out_dir, os.path.splitext(filename)[0])
99 warning = 'DO NOT EDIT! Script {0!r} generated this file from {1!r}'
100 warning = warning.format(os.path.basename(__file__), filename)
102 fake_alignment = re.compile(r'\.*\n\.+', flags=re.MULTILINE)
103 fake_tab = re.compile(r'>-------')
105 def fake_whitespace(proto_text):
106 if debug:
107 print('fake whitespace: before: {0!r}'.format(proto_text))
109 text = proto_text
110 text = fake_alignment.sub('', text)
111 text = fake_tab.sub('\t', text)
112 if debug:
113 print('fake whitespace: after: {0!r}'.format(text))
114 return text
116 with open(out_filepath, 'w') as out_file:
117 template = mako.template.Template(
118 filename=template_filepath,
119 strict_undefined=True)
120 ctx = mako.runtime.Context(
121 buffer=out_file,
122 warning=warning,
123 fake_whitespace=fake_whitespace,
124 **context_vars)
125 template.render_context(ctx)
128 class EnumCode(object):
130 C_TEMPLATE = 'piglit-util-gl-enum-gen.c.mako'
132 @classmethod
133 def emit(cls, out_dir, gl_registry):
134 assert isinstance(gl_registry, registry.gl.Registry)
135 enums = cls.get_enums_in_default_namespace(gl_registry)
136 unique_enums = cls.get_unique_enums(enums)
137 enums_by_name = cls.get_enums_by_name(enums)
138 memory_barrier = cls.get_enums_in_memory_barrier_group(gl_registry)
139 render_template(
140 cls.C_TEMPLATE,
141 out_dir,
142 gl_registry=gl_registry,
143 sorted_unique_enums_in_default_namespace=unique_enums,
144 sorted_enums_by_name=enums_by_name,
145 sorted_by_name_memory_barrier_enums=memory_barrier)
147 @classmethod
148 def get_enums_in_default_namespace(cls, gl_registry):
149 enums = []
150 for enum_group in gl_registry.enum_groups:
151 if enum_group.type == 'default_namespace':
152 for enum in enum_group.enums:
153 enums.append(enum)
154 return enums
156 @classmethod
157 def get_enums_in_memory_barrier_group(cls, gl_registry):
158 enums = []
159 for enum_group in gl_registry.enum_groups:
160 if enum_group.name == 'MemoryBarrierMask':
161 if enum_group.type == 'bitmask':
162 for enum in enum_group.enums:
163 enums.append(enum)
164 return cls.get_enums_by_name(enums)
166 @classmethod
167 def get_unique_enums(cls, enums):
168 def append_enum_if_new_value(enum_list, enum):
169 if enum_list[-1].num_value < enum.num_value:
170 enum_list.append(enum)
171 return enum_list
173 enums = sorted(enums)
174 enums = functools.reduce(append_enum_if_new_value, enums[1:], [enums[0]])
175 return enums
177 @classmethod
178 def get_enums_by_name(cls, enums):
179 enums = sorted(enums, key=lambda enum: enum.name)
180 return enums
183 if __name__ == '__main__':
184 main()