remap_helper.py revision 3464ebd5
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 '#ifdef need_MESA_remap_table' 78 print '' 79 print 'static const char _mesa_function_pool[] =' 80 81 # output string pool 82 index = 0; 83 for f in api.functionIterateAll(): 84 pool_indices[f] = index 85 86 spec = get_function_spec(f) 87 88 # a function has either assigned offset, fixed offset, 89 # or no offset 90 if f.assign_offset: 91 comments = "will be remapped" 92 elif f.offset > 0: 93 comments = "offset %d" % f.offset 94 else: 95 comments = "dynamic" 96 97 print ' /* _mesa_function_pool[%d]: %s (%s) */' \ 98 % (index, f.name, comments) 99 for line in spec: 100 print ' "%s\\0"' % line 101 index += len(line) + 1 102 print ' ;' 103 print '' 104 105 print '/* these functions need to be remapped */' 106 print 'static const struct gl_function_pool_remap MESA_remap_table_functions[] = {' 107 # output all functions that need to be remapped 108 # iterate by offsets so that they are sorted by remap indices 109 for f in api.functionIterateByOffset(): 110 if not f.assign_offset: 111 continue 112 print ' { %5d, %s_remap_index },' \ 113 % (pool_indices[f], f.name) 114 print ' { -1, -1 }' 115 print '};' 116 print '' 117 118 # collect functions by versions/extensions 119 extension_functions = {} 120 abi_extensions = [] 121 for f in api.functionIterateAll(): 122 for n in f.entry_points: 123 category, num = api.get_category_for_name(n) 124 # consider only GL_VERSION_X_Y or extensions 125 c = gl_XML.real_category_name(category) 126 if c.startswith("GL_"): 127 if not extension_functions.has_key(c): 128 extension_functions[c] = [] 129 extension_functions[c].append(f) 130 # remember the ext names of the ABI 131 if (f.is_abi() and n == f.name and 132 c not in abi_extensions): 133 abi_extensions.append(c) 134 # ignore the ABI itself 135 for ext in abi_extensions: 136 extension_functions.pop(ext) 137 138 extensions = extension_functions.keys() 139 extensions.sort() 140 141 # output ABI functions that have alternative names (with ext suffix) 142 print '/* these functions are in the ABI, but have alternative names */' 143 print 'static const struct gl_function_remap MESA_alt_functions[] = {' 144 for ext in extensions: 145 funcs = [] 146 for f in extension_functions[ext]: 147 # test if the function is in the ABI and has alt names 148 if f.is_abi() and len(f.entry_points) > 1: 149 funcs.append(f) 150 if not funcs: 151 continue 152 print ' /* from %s */' % ext 153 for f in funcs: 154 print ' { %5d, _gloffset_%s },' \ 155 % (pool_indices[f], f.name) 156 print ' { -1, -1 }' 157 print '};' 158 print '' 159 160 print '#endif /* need_MESA_remap_table */' 161 print '' 162 163 # output remap helpers for DRI drivers 164 165 for ext in extensions: 166 funcs = [] 167 remapped = [] 168 for f in extension_functions[ext]: 169 if f.assign_offset: 170 # these are handled above 171 remapped.append(f) 172 else: 173 # these functions are either in the 174 # abi, or have offset -1 175 funcs.append(f) 176 177 print '#if defined(need_%s)' % (ext) 178 if remapped: 179 print '/* functions defined in MESA_remap_table_functions are excluded */' 180 181 # output extension functions that need to be mapped 182 print 'static const struct gl_function_remap %s_functions[] = {' % (ext) 183 for f in funcs: 184 if f.offset >= 0: 185 print ' { %5d, _gloffset_%s },' \ 186 % (pool_indices[f], f.name) 187 else: 188 print ' { %5d, -1 }, /* %s */' % \ 189 (pool_indices[f], f.name) 190 print ' { -1, -1 }' 191 print '};' 192 193 print '#endif' 194 print '' 195 196 return 197 198 199def show_usage(): 200 print "Usage: %s [-f input_file_name]" % sys.argv[0] 201 sys.exit(1) 202 203if __name__ == '__main__': 204 file_name = "gl_API.xml" 205 206 try: 207 (args, trail) = getopt.getopt(sys.argv[1:], "f:") 208 except Exception,e: 209 show_usage() 210 211 for (arg,val) in args: 212 if arg == "-f": 213 file_name = val 214 215 api = gl_XML.parse_GL_API( file_name ) 216 217 printer = PrintGlRemap() 218 printer.Print( api ) 219