1#!/usr/bin/env python 2 3# Copyright (C) 2009 Chia-I Wu <olv@0xlab.org> 4# All Rights Reserved. 5# 6# This is based on extension_helper.py by Ian Romanick. 7# 8# Permission is hereby granted, free of charge, to any person obtaining a 9# copy of this software and associated documentation files (the "Software"), 10# to deal in the Software without restriction, including without limitation 11# on the rights to use, copy, modify, merge, publish, distribute, sub 12# license, and/or sell copies of the Software, and to permit persons to whom 13# the Software is furnished to do so, subject to the following conditions: 14# 15# The above copyright notice and this permission notice (including the next 16# paragraph) shall be included in all copies or substantial portions of the 17# Software. 18# 19# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 22# IBM AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 24# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 25# IN THE SOFTWARE. 26 27import gl_XML 28import license 29import sys, getopt, string 30 31def get_function_spec(func): 32 sig = "" 33 # derive parameter signature 34 for p in func.parameterIterator(): 35 if p.is_padding: 36 continue 37 # FIXME: This is a *really* ugly hack. :( 38 tn = p.type_expr.get_base_type_node() 39 if p.is_pointer(): 40 sig += 'p' 41 elif tn.integer: 42 sig += 'i' 43 elif tn.size == 4: 44 sig += 'f' 45 else: 46 sig += 'd' 47 48 spec = [sig] 49 for ent in func.entry_points: 50 spec.append("gl" + ent) 51 52 # spec is terminated by an empty string 53 spec.append('') 54 55 return spec 56 57class PrintGlRemap(gl_XML.gl_print_base): 58 def __init__(self): 59 gl_XML.gl_print_base.__init__(self) 60 61 self.name = "remap_helper.py (from Mesa)" 62 self.license = license.bsd_license_template % ("Copyright (C) 2009 Chia-I Wu <olv@0xlab.org>", "Chia-I Wu") 63 return 64 65 66 def printRealHeader(self): 67 print '#include "main/dispatch.h"' 68 print '#include "main/remap.h"' 69 print '' 70 return 71 72 73 def printBody(self, api): 74 pool_indices = {} 75 76 print '/* this is internal to remap.c */' 77 print '#ifndef need_MESA_remap_table' 78 print '#error Only remap.c should include this file!' 79 print '#endif /* need_MESA_remap_table */' 80 print '' 81 82 print '' 83 print 'static const char _mesa_function_pool[] =' 84 85 # output string pool 86 index = 0; 87 for f in api.functionIterateAll(): 88 pool_indices[f] = index 89 90 spec = get_function_spec(f) 91 92 # a function has either assigned offset, fixed offset, 93 # or no offset 94 if f.assign_offset: 95 comments = "will be remapped" 96 elif f.offset > 0: 97 comments = "offset %d" % f.offset 98 else: 99 comments = "dynamic" 100 101 print ' /* _mesa_function_pool[%d]: %s (%s) */' \ 102 % (index, f.name, comments) 103 for line in spec: 104 print ' "%s\\0"' % line 105 index += len(line) + 1 106 print ' ;' 107 print '' 108 109 print '/* these functions need to be remapped */' 110 print 'static const struct gl_function_pool_remap MESA_remap_table_functions[] = {' 111 # output all functions that need to be remapped 112 # iterate by offsets so that they are sorted by remap indices 113 for f in api.functionIterateByOffset(): 114 if not f.assign_offset: 115 continue 116 print ' { %5d, %s_remap_index },' \ 117 % (pool_indices[f], f.name) 118 print ' { -1, -1 }' 119 print '};' 120 print '' 121 122 # collect functions by versions/extensions 123 extension_functions = {} 124 abi_extensions = [] 125 for f in api.functionIterateAll(): 126 for n in f.entry_points: 127 category, num = api.get_category_for_name(n) 128 # consider only GL_VERSION_X_Y or extensions 129 c = gl_XML.real_category_name(category) 130 if c.startswith("GL_"): 131 if not extension_functions.has_key(c): 132 extension_functions[c] = [] 133 extension_functions[c].append(f) 134 # remember the ext names of the ABI 135 if (f.is_abi() and n == f.name and 136 c not in abi_extensions): 137 abi_extensions.append(c) 138 # ignore the ABI itself 139 for ext in abi_extensions: 140 extension_functions.pop(ext) 141 142 extensions = extension_functions.keys() 143 extensions.sort() 144 145 # output ABI functions that have alternative names (with ext suffix) 146 print '/* these functions are in the ABI, but have alternative names */' 147 print 'static const struct gl_function_remap MESA_alt_functions[] = {' 148 for ext in extensions: 149 funcs = [] 150 for f in extension_functions[ext]: 151 # test if the function is in the ABI and has alt names 152 if f.is_abi() and len(f.entry_points) > 1: 153 funcs.append(f) 154 if not funcs: 155 continue 156 print ' /* from %s */' % ext 157 for f in funcs: 158 print ' { %5d, _gloffset_%s },' \ 159 % (pool_indices[f], f.name) 160 print ' { -1, -1 }' 161 print '};' 162 print '' 163 return 164 165 166def show_usage(): 167 print "Usage: %s [-f input_file_name] [-c ver]" % sys.argv[0] 168 print " -c ver Version can be 'es1' or 'es2'." 169 sys.exit(1) 170 171if __name__ == '__main__': 172 file_name = "gl_API.xml" 173 174 try: 175 (args, trail) = getopt.getopt(sys.argv[1:], "f:c:") 176 except Exception,e: 177 show_usage() 178 179 es = None 180 for (arg,val) in args: 181 if arg == "-f": 182 file_name = val 183 elif arg == "-c": 184 es = val 185 186 api = gl_XML.parse_GL_API( file_name ) 187 188 if es is not None: 189 import gles_api 190 191 api_map = { 192 'es1': gles_api.es1_api, 193 'es2': gles_api.es2_api, 194 } 195 196 api.filter_functions(api_map[es]) 197 198 printer = PrintGlRemap() 199 printer.Print( api ) 200