#!/usr/bin/env python # Copyright (C) 2009 Chia-I Wu # All Rights Reserved. # # This is based on extension_helper.py by Ian Romanick. # # 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. import gl_XML import license import sys, getopt, string def get_function_spec(func): sig = "" # derive parameter signature for p in func.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(): sig += 'p' elif tn.integer: sig += 'i' elif tn.size == 4: sig += 'f' else: sig += 'd' spec = [sig] for ent in func.entry_points: spec.append("gl" + ent) # spec is terminated by an empty string spec.append('') return spec class PrintGlRemap(gl_XML.gl_print_base): def __init__(self): gl_XML.gl_print_base.__init__(self) self.name = "remap_helper.py (from Mesa)" self.license = license.bsd_license_template % ("Copyright (C) 2009 Chia-I Wu ", "Chia-I Wu") return def printRealHeader(self): print '#include "glapi/dispatch.h"' print '' return def printBody(self, api): print 'struct gl_function_remap {' print ' GLint func_index;' print ' GLint dispatch_offset; /* for sanity check */' print '};' print '' pool_indices = {} print '/* this is internal to remap.c */' print '#ifdef need_MESA_remap_table' print '' print 'static const char _mesa_function_pool[] =' # output string pool index = 0; for f in api.functionIterateAll(): pool_indices[f] = index spec = get_function_spec(f) # a function has either assigned offset, fixed offset, # or no offset if f.assign_offset: comments = "will be remapped" elif f.offset > 0: comments = "offset %d" % f.offset else: comments = "dynamic" print ' /* _mesa_function_pool[%d]: %s (%s) */' \ % (index, f.name, comments) for line in spec: print ' "%s\\0"' % line index += len(line) + 1 print ' ;' print '' print '/* these functions need to be remapped */' print 'static const struct {' print ' GLint pool_index;' print ' GLint remap_index;' print '} MESA_remap_table_functions[] = {' # output all functions that need to be remapped # iterate by offsets so that they are sorted by remap indices for f in api.functionIterateByOffset(): if not f.assign_offset: continue print ' { %5d, %s_remap_index },' \ % (pool_indices[f], f.name) print ' { -1, -1 }' print '};' print '' # collect functions by versions/extensions extension_functions = {} abi_extensions = [] for f in api.functionIterateAll(): for n in f.entry_points: category, num = api.get_category_for_name(n) # consider only GL_VERSION_X_Y or extensions c = gl_XML.real_category_name(category) if c.startswith("GL_"): if not extension_functions.has_key(c): extension_functions[c] = [] extension_functions[c].append(f) # remember the ext names of the ABI if (f.is_abi() and n == f.name and c not in abi_extensions): abi_extensions.append(c) # ignore the ABI itself for ext in abi_extensions: extension_functions.pop(ext) extensions = extension_functions.keys() extensions.sort() # output ABI functions that have alternative names (with ext suffix) print '/* these functions are in the ABI, but have alternative names */' print 'static const struct gl_function_remap MESA_alt_functions[] = {' for ext in extensions: funcs = [] for f in extension_functions[ext]: # test if the function is in the ABI and has alt names if f.is_abi() and len(f.entry_points) > 1: funcs.append(f) if not funcs: continue print ' /* from %s */' % ext for f in funcs: print ' { %5d, _gloffset_%s },' \ % (pool_indices[f], f.name) print ' { -1, -1 }' print '};' print '' print '#endif /* need_MESA_remap_table */' print '' # output remap helpers for DRI drivers for ext in extensions: funcs = [] remapped = [] for f in extension_functions[ext]: if f.assign_offset: # these are handled above remapped.append(f) else: # these functions are either in the # abi, or have offset -1 funcs.append(f) print '#if defined(need_%s)' % (ext) if remapped: print '/* functions defined in MESA_remap_table_functions are excluded */' # output extension functions that need to be mapped print 'static const struct gl_function_remap %s_functions[] = {' % (ext) for f in funcs: if f.offset >= 0: print ' { %5d, _gloffset_%s },' \ % (pool_indices[f], f.name) else: print ' { %5d, -1 }, /* %s */' % \ (pool_indices[f], f.name) print ' { -1, -1 }' print '};' print '#endif' print '' return def show_usage(): print "Usage: %s [-f input_file_name]" % sys.argv[0] sys.exit(1) if __name__ == '__main__': file_name = "gl_API.xml" try: (args, trail) = getopt.getopt(sys.argv[1:], "f:") except Exception,e: show_usage() for (arg,val) in args: if arg == "-f": file_name = val api = gl_XML.parse_GL_API( file_name ) printer = PrintGlRemap() printer.Print( api )