Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / mapi / glapi / gen / 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 "main/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                                         if p.is_padding:
178                                                 continue
179
180                                         # FIXME: This is a *really* ugly hack. :(
181
182                                         tn = p.type_expr.get_base_type_node()
183                                         if p.is_pointer():
184                                                 parameter_signature += 'p'
185                                         elif tn.integer:
186                                                 parameter_signature += 'i'
187                                         elif tn.size == 4:
188                                                 parameter_signature += 'f'
189                                         else:
190                                                 parameter_signature += 'd'
191
192                                 print '    "%s\\0" /* Parameter signature */' % (parameter_signature)
193
194                                 for n in f.entry_points:
195                                         print '    "gl%s\\0"' % (n)
196
197                                         [category, num] = api.get_category_for_name( n )
198                                         if category not in abi:
199                                                 c = gl_XML.real_category_name(category)
200                                                 if not category_list.has_key(c):
201                                                         category_list[ c ] = []
202
203                                                 category_list[ c ].append( f )
204
205                                 print '    "";'
206                                 print '#endif'
207                                 print ''
208
209                 keys = category_list.keys()
210                 keys.sort()
211
212                 for category in keys:
213                         print '#if defined(need_%s)' % (category)
214                         print 'static const struct dri_extension_function %s_functions[] = {' % (category)
215                         
216                         for f in category_list[ category ]:
217                                 # A function either has an offset that is
218                                 # assigned by the ABI, or it has a remap
219                                 # index.
220                                 if any_entrypoints_in_abi(f, abi, api):
221                                         index_name = "-1"
222                                         offset = f.offset
223                                 else:
224                                         index_name = "%s_remap_index" % (f.name)
225                                         offset = -1
226
227                                 print '    { %s_names, %s, %d },' % (f.name, index_name, offset)
228
229
230                         print '    { NULL, 0, 0 }'
231                         print '};'
232                         print '#endif'
233                         print ''
234                 
235                 return
236
237
238 class PrintInitDispatch(gl_XML.gl_print_base):
239         def __init__(self):
240                 gl_XML.gl_print_base.__init__(self)
241
242                 self.name = "extension_helper.py (from Mesa)"
243                 self.license = license.bsd_license_template % ("(C) Copyright IBM Corporation 2005", "IBM")
244                 return
245
246
247         def do_function_body(self, api, abi, vtxfmt_only):
248                 last_condition_string = None
249                 for f in api.functionIterateByOffset():
250                         if (f.name in vtxfmt) and not vtxfmt_only:
251                                 continue
252
253                         if (f.name not in vtxfmt) and vtxfmt_only:
254                                 continue
255
256                         condition = condition_for_function(f, abi, 1)
257                         condition_string = string.join(condition, " || ")
258
259                         if condition_string != last_condition_string:
260                                 if last_condition_string:
261                                         print '#endif /* %s */' % (last_condition_string)
262
263                                 if condition_string:
264                                         print '#if %s' % (condition_string)
265                                 
266                         if vtxfmt_only:
267                                 print '   disp->%s = vfmt->%s;' % (f.name, f.name)
268                         else:
269                                 print '   disp->%s = _mesa_%s;' % (f.name, f.name)
270
271                         last_condition_string = condition_string
272
273                 if last_condition_string:
274                         print '#endif /* %s */' % (last_condition_string)
275                 
276
277
278         def printBody(self, api):
279                 abi = [ "1.0", "1.1", "1.2", "GL_ARB_multitexture" ]
280                 
281                 print 'void driver_init_exec_table(struct _glapi_table *disp)'
282                 print '{'
283                 self.do_function_body(api, abi, 0)
284                 print '}'
285                 print ''
286                 print 'void driver_install_vtxfmt(struct _glapi_table *disp, const GLvertexformat *vfmt)'
287                 print '{'
288                 self.do_function_body(api, abi, 1)
289                 print '}'
290
291                 return
292
293
294 def show_usage():
295         print "Usage: %s [-f input_file_name] [-m output_mode]" % sys.argv[0]
296         print "    -m output_mode   Output mode can be one of 'extensions' or 'exec_init'."
297         sys.exit(1)
298
299 if __name__ == '__main__':
300         file_name = "gl_API.xml"
301     
302         try:
303                 (args, trail) = getopt.getopt(sys.argv[1:], "f:m:")
304         except Exception,e:
305                 show_usage()
306
307         mode = "extensions"
308         for (arg,val) in args:
309                 if arg == "-f":
310                         file_name = val
311                 if arg == '-m':
312                         mode = val
313
314
315         api = gl_XML.parse_GL_API( file_name )
316
317         if mode == "extensions":
318                 printer = PrintGlExtensionGlue()
319         elif mode == "exec_init":
320                 printer = PrintInitDispatch()
321         else:
322                 show_usage()
323
324         printer.Print( api )