Home | History | Annotate | Download | only in gen
      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