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 (at] 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 ) 325