Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | 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 '#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.  
  199. def show_usage():
  200.         print "Usage: %s [-f input_file_name]" % sys.argv[0]
  201.         sys.exit(1)
  202.  
  203. if __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.