0,0 → 1,218 |
#!/usr/bin/env python |
|
# Copyright (C) 2009 Chia-I Wu <olv@0xlab.org> |
# 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 <olv@0xlab.org>", "Chia-I Wu") |
return |
|
|
def printRealHeader(self): |
print '#include "main/dispatch.h"' |
print '#include "main/remap.h"' |
print '' |
return |
|
|
def printBody(self, api): |
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 gl_function_pool_remap 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 ) |