Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  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.  
  27. import gl_XML
  28. import license
  29. import sys, getopt, string
  30.  
  31. def 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.  
  57. class 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.  
  166. def 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.  
  171. if __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.         api.filter_functions_by_api(es)
  190.  
  191.     printer = PrintGlRemap()
  192.     printer.Print( api )
  193.