glthread: track instance divisor changes
[mesa.git] / src / mapi / glapi / gen / gl_apitemp.py
1
2 # (C) Copyright IBM Corporation 2004, 2005
3 # All Rights Reserved.
4 #
5 # Permission is hereby granted, free of charge, to any person obtaining a
6 # copy of this software and associated documentation files (the "Software"),
7 # to deal in the Software without restriction, including without limitation
8 # on the rights to use, copy, modify, merge, publish, distribute, sub
9 # license, and/or sell copies of the Software, and to permit persons to whom
10 # the Software is furnished to do so, subject to the following conditions:
11 #
12 # The above copyright notice and this permission notice (including the next
13 # paragraph) shall be included in all copies or substantial portions of the
14 # Software.
15 #
16 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 # FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 # IBM AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 # IN THE SOFTWARE.
23 #
24 # Authors:
25 # Ian Romanick <idr@us.ibm.com>
26
27 from __future__ import print_function
28
29 import argparse
30
31 import gl_XML, glX_XML
32 import license
33
34 class PrintGlOffsets(gl_XML.gl_print_base):
35 def __init__(self, es=False):
36 gl_XML.gl_print_base.__init__(self)
37
38 self.name = "gl_apitemp.py (from Mesa)"
39 self.license = license.bsd_license_template % ( \
40 """Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
41 (C) Copyright IBM Corporation 2004""", "BRIAN PAUL, IBM")
42
43 self.es = es
44
45 self.undef_list.append( "KEYWORD1" )
46 self.undef_list.append( "KEYWORD1_ALT" )
47 self.undef_list.append( "KEYWORD2" )
48 self.undef_list.append( "NAME" )
49 self.undef_list.append( "DISPATCH" )
50 self.undef_list.append( "RETURN_DISPATCH" )
51 self.undef_list.append( "DISPATCH_TABLE_NAME" )
52 self.undef_list.append( "UNUSED_TABLE_NAME" )
53 self.undef_list.append( "TABLE_ENTRY" )
54
55
56 def printFunction(self, f, name):
57 p_string = ""
58 o_string = ""
59 t_string = ""
60 comma = ""
61
62 if f.is_static_entry_point(name):
63 keyword = "KEYWORD1"
64 else:
65 keyword = "KEYWORD1_ALT"
66
67 n = f.static_name(name)
68
69 silence = ''
70 space = ''
71 for p in f.parameterIterator(name):
72 if p.is_padding:
73 continue
74
75 if p.is_pointer():
76 cast = "(const void *) "
77 else:
78 cast = ""
79
80 t_string = t_string + comma + p.format_string()
81 p_string = p_string + comma + p.name
82 o_string = o_string + comma + cast + p.name
83 comma = ", "
84
85 silence += "%s(void) %s;" % (space, p.name);
86 space = ' '
87
88
89 if f.return_type != 'void':
90 dispatch = "RETURN_DISPATCH"
91 else:
92 dispatch = "DISPATCH"
93
94 need_proto = False
95 if not f.is_static_entry_point(name):
96 need_proto = True
97 elif self.es:
98 cat, num = api.get_category_for_name(name)
99 if (cat.startswith("es") or cat.startswith("GL_OES")):
100 need_proto = True
101 if need_proto:
102 print('%s %s KEYWORD2 NAME(%s)(%s);' % (keyword, f.return_type, n, f.get_parameter_string(name)))
103 print('')
104
105 print('%s %s KEYWORD2 NAME(%s)(%s)' % (keyword, f.return_type, n, f.get_parameter_string(name)))
106 print('{')
107 if silence:
108 print(' %s' % (silence))
109 if p_string == "":
110 print(' %s(%s, (), (F, "gl%s();\\n"));' \
111 % (dispatch, f.name, name))
112 else:
113 print(' %s(%s, (%s), (F, "gl%s(%s);\\n", %s));' \
114 % (dispatch, f.name, p_string, name, t_string, o_string))
115 print('}')
116 print('')
117 return
118
119 def printRealHeader(self):
120 print('')
121 self.printVisibility( "HIDDEN", "hidden" )
122 print("""
123 /*
124 * This file is a template which generates the OpenGL API entry point
125 * functions. It should be included by a .c file which first defines
126 * the following macros:
127 * KEYWORD1 - usually nothing, but might be __declspec(dllexport) on Win32
128 * KEYWORD2 - usually nothing, but might be __stdcall on Win32
129 * NAME(n) - builds the final function name (usually add "gl" prefix)
130 * DISPATCH(func, args, msg) - code to do dispatch of named function.
131 * msg is a printf-style debug message.
132 * RETURN_DISPATCH(func, args, msg) - code to do dispatch with a return value
133 *
134 * Here is an example which generates the usual OpenGL functions:
135 * #define KEYWORD1
136 * #define KEYWORD2
137 * #define NAME(func) gl##func
138 * #define DISPATCH(func, args, msg) \\
139 * struct _glapi_table *dispatch = CurrentClientDispatch; \\
140 * (*dispatch->func) args
141 * #define RETURN DISPATCH(func, args, msg) \\
142 * struct _glapi_table *dispatch = CurrentClientDispatch; \\
143 * return (*dispatch->func) args
144 *
145 */
146
147
148 #if defined( NAME )
149 #ifndef KEYWORD1
150 #define KEYWORD1
151 #endif
152
153 #ifndef KEYWORD1_ALT
154 #define KEYWORD1_ALT HIDDEN
155 #endif
156
157 #ifndef KEYWORD2
158 #define KEYWORD2
159 #endif
160
161 #ifndef DISPATCH
162 #error DISPATCH must be defined
163 #endif
164
165 #ifndef RETURN_DISPATCH
166 #error RETURN_DISPATCH must be defined
167 #endif
168
169 """)
170 return
171
172
173
174 def printInitDispatch(self, api):
175 print("""
176 #endif /* defined( NAME ) */
177
178 /*
179 * This is how a dispatch table can be initialized with all the functions
180 * we generated above.
181 */
182 #ifdef DISPATCH_TABLE_NAME
183
184 #ifndef TABLE_ENTRY
185 #error TABLE_ENTRY must be defined
186 #endif
187
188 #ifdef _GLAPI_SKIP_NORMAL_ENTRY_POINTS
189 #error _GLAPI_SKIP_NORMAL_ENTRY_POINTS must not be defined
190 #endif
191
192 _glapi_proc DISPATCH_TABLE_NAME[] = {""")
193 for f in api.functionIterateByOffset():
194 print(' TABLE_ENTRY(%s),' % (f.dispatch_name()))
195
196 print(' /* A whole bunch of no-op functions. These might be called')
197 print(' * when someone tries to call a dynamically-registered')
198 print(' * extension function without a current rendering context.')
199 print(' */')
200 for i in range(1, 100):
201 print(' TABLE_ENTRY(Unused),')
202
203 print('};')
204 print('#endif /* DISPATCH_TABLE_NAME */')
205 print('')
206 return
207
208
209 def printAliasedTable(self, api):
210 print("""
211 /*
212 * This is just used to silence compiler warnings.
213 * We list the functions which are not otherwise used.
214 */
215 #ifdef UNUSED_TABLE_NAME
216 _glapi_proc UNUSED_TABLE_NAME[] = {""")
217
218 normal_entries = []
219 proto_entries = []
220 for f in api.functionIterateByOffset():
221 normal_ents, proto_ents = self.classifyEntryPoints(f)
222
223 # exclude f.name
224 if f.name in normal_ents:
225 normal_ents.remove(f.name)
226 elif f.name in proto_ents:
227 proto_ents.remove(f.name)
228
229 normal_ents = [f.static_name(ent) for ent in normal_ents]
230 proto_ents = [f.static_name(ent) for ent in proto_ents]
231
232 normal_entries.extend(normal_ents)
233 proto_entries.extend(proto_ents)
234
235 print('#ifndef _GLAPI_SKIP_NORMAL_ENTRY_POINTS')
236 for ent in normal_entries:
237 print(' TABLE_ENTRY(%s),' % (ent))
238 print('#endif /* _GLAPI_SKIP_NORMAL_ENTRY_POINTS */')
239 print('#ifndef _GLAPI_SKIP_PROTO_ENTRY_POINTS')
240 for ent in proto_entries:
241 print(' TABLE_ENTRY(%s),' % (ent))
242 print('#endif /* _GLAPI_SKIP_PROTO_ENTRY_POINTS */')
243
244 print('};')
245 print('#endif /*UNUSED_TABLE_NAME*/')
246 print('')
247 return
248
249
250 def classifyEntryPoints(self, func):
251 normal_names = []
252 normal_stubs = []
253 proto_names = []
254 proto_stubs = []
255 # classify the entry points
256 for name in func.entry_points:
257 if func.has_different_protocol(name):
258 if func.is_static_entry_point(name):
259 proto_names.append(name)
260 else:
261 proto_stubs.append(name)
262 else:
263 if func.is_static_entry_point(name):
264 normal_names.append(name)
265 else:
266 normal_stubs.append(name)
267 # there can be at most one stub for a function
268 if normal_stubs:
269 normal_names.append(normal_stubs[0])
270 elif proto_stubs:
271 proto_names.append(proto_stubs[0])
272
273 return (normal_names, proto_names)
274
275 def printBody(self, api):
276 normal_entry_points = []
277 proto_entry_points = []
278 for func in api.functionIterateByOffset():
279 normal_ents, proto_ents = self.classifyEntryPoints(func)
280 normal_entry_points.append((func, normal_ents))
281 proto_entry_points.append((func, proto_ents))
282
283 print('#ifndef _GLAPI_SKIP_NORMAL_ENTRY_POINTS')
284 print('')
285 for func, ents in normal_entry_points:
286 for ent in ents:
287 self.printFunction(func, ent)
288 print('')
289 print('#endif /* _GLAPI_SKIP_NORMAL_ENTRY_POINTS */')
290 print('')
291 print('/* these entry points might require different protocols */')
292 print('#ifndef _GLAPI_SKIP_PROTO_ENTRY_POINTS')
293 print('')
294 for func, ents in proto_entry_points:
295 for ent in ents:
296 self.printFunction(func, ent)
297 print('')
298 print('#endif /* _GLAPI_SKIP_PROTO_ENTRY_POINTS */')
299 print('')
300
301 self.printInitDispatch(api)
302 self.printAliasedTable(api)
303 return
304
305
306 def _parser():
307 """Parser arguments and return a namespace."""
308 parser = argparse.ArgumentParser()
309 parser.add_argument('-f',
310 metavar='<input file name>',
311 dest='filename',
312 default="gl_API.xml",
313 help="An XML file describing the API.")
314 parser.add_argument('-c',
315 action='store_true',
316 dest='es',
317 help="Enable OpenGL ES compatibility")
318 return parser.parse_args()
319
320
321 def main():
322 """Main function."""
323 args = _parser()
324
325 api = gl_XML.parse_GL_API(args.filename, glX_XML.glx_item_factory())
326
327 printer = PrintGlOffsets(args.es)
328 printer.Print(api)
329
330
331 if __name__ == '__main__':
332 main()