Fix some problems with the generation of the size tables. Enable
[mesa.git] / src / mesa / glapi / extension_helper.py
1 #!/usr/bin/env python
2
3 # (C) Copyright IBM Corporation 2005
4 # All Rights Reserved.
5 #
6 # Permission is hereby granted, free of charge, to any person obtaining a
7 # copy of this software and associated documentation files (the "Software"),
8 # to deal in the Software without restriction, including without limitation
9 # on the rights to use, copy, modify, merge, publish, distribute, sub
10 # license, and/or sell copies of the Software, and to permit persons to whom
11 # the Software is furnished to do so, subject to the following conditions:
12 #
13 # The above copyright notice and this permission notice (including the next
14 # paragraph) shall be included in all copies or substantial portions of the
15 # 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 NON-INFRINGEMENT. IN NO EVENT SHALL
20 # IBM AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23 # IN THE SOFTWARE.
24 #
25 # Authors:
26 # Ian Romanick <idr@us.ibm.com>
27
28 import gl_XML
29 import license
30 import sys, getopt, string
31
32 vtxfmt = [
33 "ArrayElement", \
34 "Color3f", \
35 "Color3fv", \
36 "Color4f", \
37 "Color4fv", \
38 "EdgeFlag", \
39 "EdgeFlagv", \
40 "EvalCoord1f", \
41 "EvalCoord1fv", \
42 "EvalCoord2f", \
43 "EvalCoord2fv", \
44 "EvalPoint1", \
45 "EvalPoint2", \
46 "FogCoordfEXT", \
47 "FogCoordfvEXT", \
48 "Indexf", \
49 "Indexfv", \
50 "Materialfv", \
51 "MultiTexCoord1fARB", \
52 "MultiTexCoord1fvARB", \
53 "MultiTexCoord2fARB", \
54 "MultiTexCoord2fvARB", \
55 "MultiTexCoord3fARB", \
56 "MultiTexCoord3fvARB", \
57 "MultiTexCoord4fARB", \
58 "MultiTexCoord4fvARB", \
59 "Normal3f", \
60 "Normal3fv", \
61 "SecondaryColor3fEXT", \
62 "SecondaryColor3fvEXT", \
63 "TexCoord1f", \
64 "TexCoord1fv", \
65 "TexCoord2f", \
66 "TexCoord2fv", \
67 "TexCoord3f", \
68 "TexCoord3fv", \
69 "TexCoord4f", \
70 "TexCoord4fv", \
71 "Vertex2f", \
72 "Vertex2fv", \
73 "Vertex3f", \
74 "Vertex3fv", \
75 "Vertex4f", \
76 "Vertex4fv", \
77 "CallList", \
78 "CallLists", \
79 "Begin", \
80 "End", \
81 "VertexAttrib1fNV", \
82 "VertexAttrib1fvNV", \
83 "VertexAttrib2fNV", \
84 "VertexAttrib2fvNV", \
85 "VertexAttrib3fNV", \
86 "VertexAttrib3fvNV", \
87 "VertexAttrib4fNV", \
88 "VertexAttrib4fvNV", \
89 "VertexAttrib1fARB", \
90 "VertexAttrib1fvARB", \
91 "VertexAttrib2fARB", \
92 "VertexAttrib2fvARB", \
93 "VertexAttrib3fARB", \
94 "VertexAttrib3fvARB", \
95 "VertexAttrib4fARB", \
96 "VertexAttrib4fvARB", \
97 "Rectf", \
98 "DrawArrays", \
99 "DrawElements", \
100 "DrawRangeElements", \
101 "EvalMesh1", \
102 "EvalMesh2", \
103 ]
104
105 def all_entrypoints_in_abi(f, abi, api):
106 for n in f.entry_points:
107 [category, num] = api.get_category_for_name( n )
108 if category not in abi:
109 return 0
110
111 return 1
112
113
114 def any_entrypoints_in_abi(f, abi, api):
115 for n in f.entry_points:
116 [category, num] = api.get_category_for_name( n )
117 if category in abi:
118 return 1
119
120 return 0
121
122
123 def condition_for_function(f, abi, all_not_in_ABI):
124 """Create a C-preprocessor condition for the function.
125
126 There are two modes of operation. If all_not_in_ABI is set, a
127 condition is only created is all of the entry-point names for f are
128 not in the selected ABI. If all_not_in_ABI is not set, a condition
129 is created if any entryp-point name is not in the selected ABI.
130 """
131
132 condition = []
133 for n in f.entry_points:
134 [category, num] = api.get_category_for_name( n )
135 if category not in abi:
136 condition.append( 'defined(need_%s)' % (gl_XML.real_category_name( category )) )
137 elif all_not_in_ABI:
138 return []
139
140 return condition
141
142
143 class PrintGlExtensionGlue(gl_XML.gl_print_base):
144 def __init__(self):
145 gl_XML.gl_print_base.__init__(self)
146
147 self.name = "extension_helper.py (from Mesa)"
148 self.license = license.bsd_license_template % ("(C) Copyright IBM Corporation 2005", "IBM")
149 return
150
151
152 def printRealHeader(self):
153 print '#include "utils.h"'
154 print '#include "dispatch.h"'
155 print ''
156 return
157
158
159 def printBody(self, api):
160 abi = [ "1.0", "1.1", "1.2", "GL_ARB_multitexture" ]
161
162 category_list = {}
163
164 print '#ifndef NULL'
165 print '# define NULL 0'
166 print '#endif'
167 print ''
168
169 for f in api.functionIterateAll():
170 condition = condition_for_function(f, abi, 0)
171 if len(condition):
172 print '#if %s' % (string.join(condition, " || "))
173 print 'static const char %s_names[] = ' % (f.name)
174
175 parameter_signature = ''
176 for p in f.parameterIterator():
177 # FIXME: This is a *really* ugly hack. :(
178
179 tn = p.type_expr.get_base_type_node()
180 if p.is_pointer():
181 parameter_signature += 'p'
182 elif tn.integer:
183 parameter_signature += 'i'
184 elif tn.size == 4:
185 parameter_signature += 'f'
186 else:
187 parameter_signature += 'd'
188
189 print ' "%s\\0" /* Parameter signature */' % (parameter_signature)
190
191 for n in f.entry_points:
192 print ' "gl%s\\0"' % (n)
193
194 [category, num] = api.get_category_for_name( n )
195 if category not in abi:
196 c = gl_XML.real_category_name(category)
197 if not category_list.has_key(c):
198 category_list[ c ] = []
199
200 category_list[ c ].append( f )
201
202 print ' "";'
203 print '#endif'
204 print ''
205
206 keys = category_list.keys()
207 keys.sort()
208
209 for category in keys:
210 print '#if defined(need_%s)' % (category)
211 print 'static const struct dri_extension_function %s_functions[] = {' % (category)
212
213 for f in category_list[ category ]:
214 # A function either has an offset that is
215 # assigned by the ABI, or it has a remap
216 # index.
217 if any_entrypoints_in_abi(f, abi, api):
218 index_name = "-1"
219 offset = f.offset
220 else:
221 index_name = "%s_remap_index" % (f.name)
222 offset = -1
223
224 print ' { %s_names, %s, %d },' % (f.name, index_name, offset)
225
226
227 print ' { NULL, 0, 0 }'
228 print '};'
229 print '#endif'
230 print ''
231
232 return
233
234
235 class PrintInitDispatch(gl_XML.gl_print_base):
236 def __init__(self):
237 gl_XML.gl_print_base.__init__(self)
238
239 self.name = "extension_helper.py (from Mesa)"
240 self.license = license.bsd_license_template % ("(C) Copyright IBM Corporation 2005", "IBM")
241 return
242
243
244 def do_function_body(self, api, abi, vtxfmt_only):
245 last_condition_string = None
246 for f in api.functionIterateByOffset():
247 if (f.name in vtxfmt) and not vtxfmt_only:
248 continue
249
250 if (f.name not in vtxfmt) and vtxfmt_only:
251 continue
252
253 condition = condition_for_function(f, abi, 1)
254 condition_string = string.join(condition, " || ")
255
256 if condition_string != last_condition_string:
257 if last_condition_string:
258 print '#endif /* %s */' % (last_condition_string)
259
260 if condition_string:
261 print '#if %s' % (condition_string)
262
263 if vtxfmt_only:
264 print ' disp->%s = vfmt->%s;' % (f.name, f.name)
265 else:
266 print ' disp->%s = _mesa_%s;' % (f.name, f.name)
267
268 last_condition_string = condition_string
269
270 if last_condition_string:
271 print '#endif /* %s */' % (last_condition_string)
272
273
274
275 def printBody(self, api):
276 abi = [ "1.0", "1.1", "1.2", "GL_ARB_multitexture" ]
277
278 print 'void driver_init_exec_table(struct _glapi_table *disp)'
279 print '{'
280 self.do_function_body(api, abi, 0)
281 print '}'
282 print ''
283 print 'void driver_install_vtxfmt(struct _glapi_table *disp, const GLvertexformat *vfmt)'
284 print '{'
285 self.do_function_body(api, abi, 1)
286 print '}'
287
288 return
289
290
291 def show_usage():
292 print "Usage: %s [-f input_file_name] [-m output_mode]" % sys.argv[0]
293 print " -m output_mode Output mode can be one of 'extensions' or 'exec_init'."
294 sys.exit(1)
295
296 if __name__ == '__main__':
297 file_name = "gl_API.xml"
298
299 try:
300 (args, trail) = getopt.getopt(sys.argv[1:], "f:m:")
301 except Exception,e:
302 show_usage()
303
304 mode = "extensions"
305 for (arg,val) in args:
306 if arg == "-f":
307 file_name = val
308 if arg == '-m':
309 mode = val
310
311
312 api = gl_XML.parse_GL_API( file_name )
313
314 if mode == "extensions":
315 printer = PrintGlExtensionGlue()
316 elif mode == "exec_init":
317 printer = PrintInitDispatch()
318 else:
319 show_usage()
320
321 printer.Print( api )