Home | History | Annotate | Download | only in gen
      1 #!/usr/bin/python2
      2 
      3 # (C) Copyright IBM Corporation 2004
      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
     31 
     32 class PrintGlTable(gl_XML.gl_print_base):
     33 	def __init__(self, es=False):
     34 		gl_XML.gl_print_base.__init__(self)
     35 
     36 		self.es = es
     37 		self.header_tag = '_GLAPI_TABLE_H_'
     38 		self.name = "gl_table.py (from Mesa)"
     39 		self.license = license.bsd_license_template % ( \
     40 """Copyright (C) 1999-2003  Brian Paul   All Rights Reserved.
     41 (C) Copyright IBM Corporation 2004""", "BRIAN PAUL, IBM")
     42 		self.ifdef_emitted = False;
     43 		return
     44 
     45 
     46 	def printBody(self, api):
     47 		for f in api.functionIterateByOffset():
     48 			if not f.is_abi() and not self.ifdef_emitted:
     49 				print '#if !defined HAVE_SHARED_GLAPI'
     50 				self.ifdef_emitted = True
     51 			arg_string = f.get_parameter_string()
     52 			print '   %s (GLAPIENTRYP %s)(%s); /* %d */' % (f.return_type, f.name, arg_string, f.offset)
     53 
     54 		print '#endif /* !defined HAVE_SHARED_GLAPI */'
     55 
     56 
     57 	def printRealHeader(self):
     58 		print '#ifndef GLAPIENTRYP'
     59 		print '# ifndef GLAPIENTRY'
     60 		print '#  define GLAPIENTRY'
     61 		print '# endif'
     62 		print ''
     63 		print '# define GLAPIENTRYP GLAPIENTRY *'
     64 		print '#endif'
     65 		print ''
     66 		print ''
     67 		print 'struct _glapi_table'
     68 		print '{'
     69 		return
     70 
     71 
     72 	def printRealFooter(self):
     73 		print '};'
     74 		return
     75 
     76 
     77 class PrintRemapTable(gl_XML.gl_print_base):
     78 	def __init__(self, es=False):
     79 		gl_XML.gl_print_base.__init__(self)
     80 
     81 		self.es = es
     82 		self.header_tag = '_DISPATCH_H_'
     83 		self.name = "gl_table.py (from Mesa)"
     84 		self.license = license.bsd_license_template % ("(C) Copyright IBM Corporation 2005", "IBM")
     85 		return
     86 
     87 
     88 	def printRealHeader(self):
     89 		print """
     90 /**
     91  * \\file main/dispatch.h
     92  * Macros for handling GL dispatch tables.
     93  *
     94  * For each known GL function, there are 3 macros in this file.  The first
     95  * macro is named CALL_FuncName and is used to call that GL function using
     96  * the specified dispatch table.  The other 2 macros, called GET_FuncName
     97  * can SET_FuncName, are used to get and set the dispatch pointer for the
     98  * named function in the specified dispatch table.
     99  */
    100 
    101 /* GLXEXT is defined when building the GLX extension in the xserver.
    102  */
    103 #if !defined(GLXEXT)
    104 #include "main/mfeatures.h"
    105 #endif
    106 """
    107 		return
    108 
    109 	def printBody(self, api):
    110 		print '#define CALL_by_offset(disp, cast, offset, parameters) \\'
    111 		print '    (*(cast (GET_by_offset(disp, offset)))) parameters'
    112 		print '#define GET_by_offset(disp, offset) \\'
    113 		print '    (offset >= 0) ? (((_glapi_proc *)(disp))[offset]) : NULL'
    114 		print '#define SET_by_offset(disp, offset, fn) \\'
    115 		print '    do { \\'
    116 		print '        if ( (offset) < 0 ) { \\'
    117 		print '            /* fprintf( stderr, "[%s:%u] SET_by_offset(%p, %d, %s)!\\n", */ \\'
    118 		print '            /*         __func__, __LINE__, disp, offset, # fn); */ \\'
    119 		print '            /* abort(); */ \\'
    120 		print '        } \\'
    121 		print '        else { \\'
    122 		print '            ( (_glapi_proc *) (disp) )[offset] = (_glapi_proc) fn; \\'
    123 		print '        } \\'
    124 		print '    } while(0)'
    125 		print ''
    126 
    127 		functions = []
    128 		abi_functions = []
    129 		alias_functions = []
    130 		count = 0
    131 		for f in api.functionIterateByOffset():
    132 			if not f.is_abi():
    133 				functions.append( [f, count] )
    134 				count += 1
    135 			else:
    136 				abi_functions.append( [f, -1] )
    137 
    138 			if self.es:
    139 				# remember functions with aliases
    140 				if len(f.entry_points) > 1:
    141 					alias_functions.append(f)
    142 
    143 		print '/* total number of offsets below */'
    144 		print '#define _gloffset_COUNT %d' % (len(abi_functions + functions))
    145 		print ''
    146 
    147 		for f, index in abi_functions:
    148 			print '#define _gloffset_%s %d' % (f.name, f.offset)
    149 
    150 		print ''
    151 		print '#if !FEATURE_remap_table'
    152 		print ''
    153 
    154 		for f, index in functions:
    155 			print '#define _gloffset_%s %d' % (f.name, f.offset)
    156 
    157 		print ''
    158 		print '#else /* !FEATURE_remap_table */'
    159 		print ''
    160 
    161 		if self.es:
    162 			remap_table = "esLocalRemapTable"
    163 
    164 			print '#define %s_size %u' % (remap_table, count)
    165 			print 'static int %s[ %s_size ];' % (remap_table, remap_table)
    166 			print ''
    167 		else:
    168 			remap_table = "driDispatchRemapTable"
    169 
    170 			print '#define %s_size %u' % (remap_table, count)
    171 			print 'extern int %s[ %s_size ];' % (remap_table, remap_table)
    172 			print ''
    173 
    174 		for f, index in functions:
    175 			print '#define %s_remap_index %u' % (f.name, index)
    176 
    177 		print ''
    178 
    179 		for f, index in functions:
    180 			print '#define _gloffset_%s %s[%s_remap_index]' % (f.name, remap_table, f.name)
    181 
    182 		print ''
    183 		print '#endif /* !FEATURE_remap_table */'
    184 		print ''
    185 
    186 		for f, index in abi_functions + functions:
    187 			arg_string = gl_XML.create_parameter_string( f.parameters, 0 )
    188 
    189 			print 'typedef %s (GLAPIENTRYP _glptr_%s)(%s);' % (f.return_type, f.name, arg_string)
    190 			print '#define CALL_%s(disp, parameters) \\' % (f.name)
    191 			print '    (* GET_%s(disp)) parameters' % (f.name)
    192 			print 'static inline _glptr_%s GET_%s(struct _glapi_table *disp) {' % (f.name, f.name)
    193 			print '   return (_glptr_%s) (GET_by_offset(disp, _gloffset_%s));' % (f.name, f.name)
    194 			print '}'
    195 			print
    196 			print 'static inline void SET_%s(struct _glapi_table *disp, %s (GLAPIENTRYP fn)(%s)) {' % (f.name, f.return_type, arg_string)
    197 			print '   SET_by_offset(disp, _gloffset_%s, fn);' % (f.name)
    198 			print '}'
    199 			print
    200 
    201 		if alias_functions:
    202 			print ''
    203 			print '/* define aliases for compatibility */'
    204 			for f in alias_functions:
    205 				for name in f.entry_points:
    206 					if name != f.name:
    207 						print '#define CALL_%s(disp, parameters) CALL_%s(disp, parameters)' % (name, f.name)
    208 						print '#define GET_%s(disp) GET_%s(disp)' % (name, f.name)
    209 						print '#define SET_%s(disp, fn) SET_%s(disp, fn)' % (name, f.name)
    210 			print ''
    211 
    212 			print '#if FEATURE_remap_table'
    213 			for f in alias_functions:
    214 				for name in f.entry_points:
    215 					if name != f.name:
    216 						print '#define %s_remap_index %s_remap_index' % (name, f.name)
    217 			print '#endif /* FEATURE_remap_table */'
    218 			print ''
    219 
    220 		return
    221 
    222 
    223 def show_usage():
    224 	print "Usage: %s [-f input_file_name] [-m mode] [-c ver]" % sys.argv[0]
    225 	print "    -m mode   Mode can be 'table' or 'remap_table'."
    226 	print "    -c ver    Version can be 'es1' or 'es2'."
    227 	sys.exit(1)
    228 
    229 if __name__ == '__main__':
    230 	file_name = "gl_API.xml"
    231     
    232 	try:
    233 		(args, trail) = getopt.getopt(sys.argv[1:], "f:m:c:")
    234 	except Exception,e:
    235 		show_usage()
    236 
    237 	mode = "table"
    238 	es = None
    239 	for (arg,val) in args:
    240 		if arg == "-f":
    241 			file_name = val
    242 		elif arg == "-m":
    243 			mode = val
    244 		elif arg == "-c":
    245 			es = val
    246 
    247 	if mode == "table":
    248 		printer = PrintGlTable(es)
    249 	elif mode == "remap_table":
    250 		printer = PrintRemapTable(es)
    251 	else:
    252 		show_usage()
    253 
    254 	api = gl_XML.parse_GL_API( file_name )
    255 
    256 	if es is not None:
    257 		import gles_api
    258 
    259 		api_map = {
    260 			'es1': gles_api.es1_api,
    261 			'es2': gles_api.es2_api,
    262 		}
    263 
    264 		api.filter_functions(api_map[es])
    265 
    266 	printer.Print( api )
    267