#!/usr/bin/env python # (C) Copyright IBM Corporation 2005 # All Rights Reserved. # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), # to deal in the Software without restriction, including without limitation # on the rights to use, copy, modify, merge, publish, distribute, sub # license, and/or sell copies of the Software, and to permit persons to whom # the Software is furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice (including the next # paragraph) shall be included in all copies or substantial portions of the # Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL # IBM AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. # # Authors: # Ian Romanick import gl_XML import license import sys, getopt, string vtxfmt = [ "ArrayElement", \ "Color3f", \ "Color3fv", \ "Color4f", \ "Color4fv", \ "EdgeFlag", \ "EdgeFlagv", \ "EvalCoord1f", \ "EvalCoord1fv", \ "EvalCoord2f", \ "EvalCoord2fv", \ "EvalPoint1", \ "EvalPoint2", \ "FogCoordfEXT", \ "FogCoordfvEXT", \ "Indexf", \ "Indexfv", \ "Materialfv", \ "MultiTexCoord1fARB", \ "MultiTexCoord1fvARB", \ "MultiTexCoord2fARB", \ "MultiTexCoord2fvARB", \ "MultiTexCoord3fARB", \ "MultiTexCoord3fvARB", \ "MultiTexCoord4fARB", \ "MultiTexCoord4fvARB", \ "Normal3f", \ "Normal3fv", \ "SecondaryColor3fEXT", \ "SecondaryColor3fvEXT", \ "TexCoord1f", \ "TexCoord1fv", \ "TexCoord2f", \ "TexCoord2fv", \ "TexCoord3f", \ "TexCoord3fv", \ "TexCoord4f", \ "TexCoord4fv", \ "Vertex2f", \ "Vertex2fv", \ "Vertex3f", \ "Vertex3fv", \ "Vertex4f", \ "Vertex4fv", \ "CallList", \ "CallLists", \ "Begin", \ "End", \ "VertexAttrib1fNV", \ "VertexAttrib1fvNV", \ "VertexAttrib2fNV", \ "VertexAttrib2fvNV", \ "VertexAttrib3fNV", \ "VertexAttrib3fvNV", \ "VertexAttrib4fNV", \ "VertexAttrib4fvNV", \ "VertexAttrib1fARB", \ "VertexAttrib1fvARB", \ "VertexAttrib2fARB", \ "VertexAttrib2fvARB", \ "VertexAttrib3fARB", \ "VertexAttrib3fvARB", \ "VertexAttrib4fARB", \ "VertexAttrib4fvARB", \ "Rectf", \ "DrawArrays", \ "DrawElements", \ "DrawRangeElements", \ "EvalMesh1", \ "EvalMesh2", \ ] def all_entrypoints_in_abi(f, abi, api): for n in f.entry_points: [category, num] = api.get_category_for_name( n ) if category not in abi: return 0 return 1 def any_entrypoints_in_abi(f, abi, api): for n in f.entry_points: [category, num] = api.get_category_for_name( n ) if category in abi: return 1 return 0 def condition_for_function(f, abi, all_not_in_ABI): """Create a C-preprocessor condition for the function. There are two modes of operation. If all_not_in_ABI is set, a condition is only created is all of the entry-point names for f are not in the selected ABI. If all_not_in_ABI is not set, a condition is created if any entryp-point name is not in the selected ABI. """ condition = [] for n in f.entry_points: [category, num] = api.get_category_for_name( n ) if category not in abi: condition.append( 'defined(need_%s)' % (gl_XML.real_category_name( category )) ) elif all_not_in_ABI: return [] return condition class PrintGlExtensionGlue(gl_XML.gl_print_base): def __init__(self): gl_XML.gl_print_base.__init__(self) self.name = "extension_helper.py (from Mesa)" self.license = license.bsd_license_template % ("(C) Copyright IBM Corporation 2005", "IBM") return def printRealHeader(self): print '#include "utils.h"' print '#include "main/dispatch.h"' print '' return def printBody(self, api): abi = [ "1.0", "1.1", "1.2", "GL_ARB_multitexture" ] category_list = {} print '#ifndef NULL' print '# define NULL 0' print '#endif' print '' for f in api.functionIterateAll(): condition = condition_for_function(f, abi, 0) if len(condition): print '#if %s' % (string.join(condition, " || ")) print 'static const char %s_names[] =' % (f.name) parameter_signature = '' for p in f.parameterIterator(): if p.is_padding: continue # FIXME: This is a *really* ugly hack. :( tn = p.type_expr.get_base_type_node() if p.is_pointer(): parameter_signature += 'p' elif tn.integer: parameter_signature += 'i' elif tn.size == 4: parameter_signature += 'f' else: parameter_signature += 'd' print ' "%s\\0" /* Parameter signature */' % (parameter_signature) for n in f.entry_points: print ' "gl%s\\0"' % (n) [category, num] = api.get_category_for_name( n ) if category not in abi: c = gl_XML.real_category_name(category) if not category_list.has_key(c): category_list[ c ] = [] category_list[ c ].append( f ) print ' "";' print '#endif' print '' keys = category_list.keys() keys.sort() for category in keys: print '#if defined(need_%s)' % (category) print 'static const struct dri_extension_function %s_functions[] = {' % (category) for f in category_list[ category ]: # A function either has an offset that is # assigned by the ABI, or it has a remap # index. if any_entrypoints_in_abi(f, abi, api): index_name = "-1" offset = f.offset else: index_name = "%s_remap_index" % (f.name) offset = -1 print ' { %s_names, %s, %d },' % (f.name, index_name, offset) print ' { NULL, 0, 0 }' print '};' print '#endif' print '' return class PrintInitDispatch(gl_XML.gl_print_base): def __init__(self): gl_XML.gl_print_base.__init__(self) self.name = "extension_helper.py (from Mesa)" self.license = license.bsd_license_template % ("(C) Copyright IBM Corporation 2005", "IBM") return def do_function_body(self, api, abi, vtxfmt_only): last_condition_string = None for f in api.functionIterateByOffset(): if (f.name in vtxfmt) and not vtxfmt_only: continue if (f.name not in vtxfmt) and vtxfmt_only: continue condition = condition_for_function(f, abi, 1) condition_string = string.join(condition, " || ") if condition_string != last_condition_string: if last_condition_string: print '#endif /* %s */' % (last_condition_string) if condition_string: print '#if %s' % (condition_string) if vtxfmt_only: print ' disp->%s = vfmt->%s;' % (f.name, f.name) else: print ' disp->%s = _mesa_%s;' % (f.name, f.name) last_condition_string = condition_string if last_condition_string: print '#endif /* %s */' % (last_condition_string) def printBody(self, api): abi = [ "1.0", "1.1", "1.2", "GL_ARB_multitexture" ] print 'void driver_init_exec_table(struct _glapi_table *disp)' print '{' self.do_function_body(api, abi, 0) print '}' print '' print 'void driver_install_vtxfmt(struct _glapi_table *disp, const GLvertexformat *vfmt)' print '{' self.do_function_body(api, abi, 1) print '}' return def show_usage(): print "Usage: %s [-f input_file_name] [-m output_mode]" % sys.argv[0] print " -m output_mode Output mode can be one of 'extensions' or 'exec_init'." sys.exit(1) if __name__ == '__main__': file_name = "gl_API.xml" try: (args, trail) = getopt.getopt(sys.argv[1:], "f:m:") except Exception,e: show_usage() mode = "extensions" for (arg,val) in args: if arg == "-f": file_name = val if arg == '-m': mode = val api = gl_XML.parse_GL_API( file_name ) if mode == "extensions": printer = PrintGlExtensionGlue() elif mode == "exec_init": printer = PrintInitDispatch() else: show_usage() printer.Print( api )