Subversion Repositories Kolibri OS

Rev

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

  1. #!/usr/bin/env python
  2. '''
  3. Generates dumper for the SVGA 3D command stream using pygccxml.
  4.  
  5. Jose Fonseca <jfonseca@vmware.com>
  6. '''
  7.  
  8. copyright = '''
  9. /**********************************************************
  10. * Copyright 2009 VMware, Inc.  All rights reserved.
  11. *
  12. * Permission is hereby granted, free of charge, to any person
  13. * obtaining a copy of this software and associated documentation
  14. * files (the "Software"), to deal in the Software without
  15. * restriction, including without limitation the rights to use, copy,
  16. * modify, merge, publish, distribute, sublicense, and/or sell copies
  17. * of the Software, and to permit persons to whom the Software is
  18. * furnished to do so, subject to the following conditions:
  19. *
  20. * The above copyright notice and this permission notice shall be
  21. * included in all copies or substantial portions of the Software.
  22. *
  23. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  24. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  25. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  26. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  27. * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  28. * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  29. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  30. * SOFTWARE.
  31. *
  32. **********************************************************/
  33. '''
  34.  
  35. import os
  36. import sys
  37.  
  38. from pygccxml import parser
  39. from pygccxml import declarations
  40.  
  41. from pygccxml.declarations import algorithm
  42. from pygccxml.declarations import decl_visitor
  43. from pygccxml.declarations import type_traits
  44. from pygccxml.declarations import type_visitor
  45.  
  46.  
  47. enums = True
  48.  
  49.  
  50. class decl_dumper_t(decl_visitor.decl_visitor_t):
  51.  
  52.     def __init__(self, instance = '', decl = None):
  53.         decl_visitor.decl_visitor_t.__init__(self)
  54.         self._instance = instance
  55.         self.decl = decl
  56.  
  57.     def clone(self):
  58.         return decl_dumper_t(self._instance, self.decl)
  59.  
  60.     def visit_class(self):
  61.         class_ = self.decl
  62.         assert self.decl.class_type in ('struct', 'union')
  63.  
  64.         for variable in class_.variables():
  65.             if variable.name != '':
  66.                 #print 'variable = %r' % variable.name
  67.                 dump_type(self._instance + '.' + variable.name, variable.type)
  68.  
  69.     def visit_enumeration(self):
  70.         if enums:
  71.             print '   switch(%s) {' % ("(*cmd)" + self._instance,)
  72.             for name, value in self.decl.values:
  73.                 print '   case %s:' % (name,)
  74.                 print '      _debug_printf("\\t\\t%s = %s\\n");' % (self._instance, name)
  75.                 print '      break;'
  76.             print '   default:'
  77.             print '      _debug_printf("\\t\\t%s = %%i\\n", %s);' % (self._instance, "(*cmd)" + self._instance)
  78.             print '      break;'
  79.             print '   }'
  80.         else:
  81.             print '   _debug_printf("\\t\\t%s = %%i\\n", %s);' % (self._instance, "(*cmd)" + self._instance)
  82.  
  83.  
  84. def dump_decl(instance, decl):
  85.     dumper = decl_dumper_t(instance, decl)
  86.     algorithm.apply_visitor(dumper, decl)
  87.  
  88.  
  89. class type_dumper_t(type_visitor.type_visitor_t):
  90.  
  91.     def __init__(self, instance, type_):
  92.         type_visitor.type_visitor_t.__init__(self)
  93.         self.instance = instance
  94.         self.type = type_
  95.  
  96.     def clone(self):
  97.         return type_dumper_t(self.instance, self.type)
  98.  
  99.     def visit_char(self):
  100.         self.print_instance('%i')
  101.        
  102.     def visit_unsigned_char(self):
  103.         self.print_instance('%u')
  104.  
  105.     def visit_signed_char(self):
  106.         self.print_instance('%i')
  107.    
  108.     def visit_wchar(self):
  109.         self.print_instance('%i')
  110.        
  111.     def visit_short_int(self):
  112.         self.print_instance('%i')
  113.        
  114.     def visit_short_unsigned_int(self):
  115.         self.print_instance('%u')
  116.        
  117.     def visit_bool(self):
  118.         self.print_instance('%i')
  119.        
  120.     def visit_int(self):
  121.         self.print_instance('%i')
  122.        
  123.     def visit_unsigned_int(self):
  124.         self.print_instance('%u')
  125.        
  126.     def visit_long_int(self):
  127.         self.print_instance('%li')
  128.        
  129.     def visit_long_unsigned_int(self):
  130.         self.print_instance('%lu')
  131.        
  132.     def visit_long_long_int(self):
  133.         self.print_instance('%lli')
  134.        
  135.     def visit_long_long_unsigned_int(self):
  136.         self.print_instance('%llu')
  137.        
  138.     def visit_float(self):
  139.         self.print_instance('%f')
  140.        
  141.     def visit_double(self):
  142.         self.print_instance('%f')
  143.        
  144.     def visit_array(self):
  145.         for i in range(type_traits.array_size(self.type)):
  146.             dump_type(self.instance + '[%i]' % i, type_traits.base_type(self.type))
  147.  
  148.     def visit_pointer(self):
  149.         self.print_instance('%p')
  150.  
  151.     def visit_declarated(self):
  152.         #print 'decl = %r' % self.type.decl_string
  153.         decl = type_traits.remove_declarated(self.type)
  154.         dump_decl(self.instance, decl)
  155.  
  156.     def print_instance(self, format):
  157.         print '   _debug_printf("\\t\\t%s = %s\\n", %s);' % (self.instance, format, "(*cmd)" + self.instance)
  158.  
  159.  
  160. def dump_type(instance, type_):
  161.     type_ = type_traits.remove_alias(type_)
  162.     visitor = type_dumper_t(instance, type_)
  163.     algorithm.apply_visitor(visitor, type_)
  164.  
  165.  
  166. def dump_struct(decls, class_):
  167.     print 'static void'
  168.     print 'dump_%s(const %s *cmd)' % (class_.name, class_.name)
  169.     print '{'
  170.     dump_decl('', class_)
  171.     print '}'
  172.     print ''
  173.  
  174.  
  175. cmds = [
  176.     ('SVGA_3D_CMD_SURFACE_DEFINE', 'SVGA3dCmdDefineSurface', (), 'SVGA3dSize'),
  177.     ('SVGA_3D_CMD_SURFACE_DESTROY', 'SVGA3dCmdDestroySurface', (), None),
  178.     ('SVGA_3D_CMD_SURFACE_COPY', 'SVGA3dCmdSurfaceCopy', (), 'SVGA3dCopyBox'),
  179.     ('SVGA_3D_CMD_SURFACE_STRETCHBLT', 'SVGA3dCmdSurfaceStretchBlt', (), None),
  180.     ('SVGA_3D_CMD_SURFACE_DMA', 'SVGA3dCmdSurfaceDMA', (), 'SVGA3dCopyBox'),
  181.     ('SVGA_3D_CMD_CONTEXT_DEFINE', 'SVGA3dCmdDefineContext', (), None),
  182.     ('SVGA_3D_CMD_CONTEXT_DESTROY', 'SVGA3dCmdDestroyContext', (), None),
  183.     ('SVGA_3D_CMD_SETTRANSFORM', 'SVGA3dCmdSetTransform', (), None),
  184.     ('SVGA_3D_CMD_SETZRANGE', 'SVGA3dCmdSetZRange', (), None),
  185.     ('SVGA_3D_CMD_SETRENDERSTATE', 'SVGA3dCmdSetRenderState', (), 'SVGA3dRenderState'),
  186.     ('SVGA_3D_CMD_SETRENDERTARGET', 'SVGA3dCmdSetRenderTarget', (), None),
  187.     ('SVGA_3D_CMD_SETTEXTURESTATE', 'SVGA3dCmdSetTextureState', (), 'SVGA3dTextureState'),
  188.     ('SVGA_3D_CMD_SETMATERIAL', 'SVGA3dCmdSetMaterial', (), None),
  189.     ('SVGA_3D_CMD_SETLIGHTDATA', 'SVGA3dCmdSetLightData', (), None),
  190.     ('SVGA_3D_CMD_SETLIGHTENABLED', 'SVGA3dCmdSetLightEnabled', (), None),
  191.     ('SVGA_3D_CMD_SETVIEWPORT', 'SVGA3dCmdSetViewport', (), None),
  192.     ('SVGA_3D_CMD_SETCLIPPLANE', 'SVGA3dCmdSetClipPlane', (), None),
  193.     ('SVGA_3D_CMD_CLEAR', 'SVGA3dCmdClear', (), 'SVGA3dRect'),
  194.     ('SVGA_3D_CMD_PRESENT', 'SVGA3dCmdPresent', (), 'SVGA3dCopyRect'),
  195.     ('SVGA_3D_CMD_SHADER_DEFINE', 'SVGA3dCmdDefineShader', (), None),
  196.     ('SVGA_3D_CMD_SHADER_DESTROY', 'SVGA3dCmdDestroyShader', (), None),
  197.     ('SVGA_3D_CMD_SET_SHADER', 'SVGA3dCmdSetShader', (), None),
  198.     ('SVGA_3D_CMD_SET_SHADER_CONST', 'SVGA3dCmdSetShaderConst', (), None),
  199.     ('SVGA_3D_CMD_DRAW_PRIMITIVES', 'SVGA3dCmdDrawPrimitives', (('SVGA3dVertexDecl', 'numVertexDecls'), ('SVGA3dPrimitiveRange', 'numRanges')), 'SVGA3dVertexDivisor'),
  200.     ('SVGA_3D_CMD_SETSCISSORRECT', 'SVGA3dCmdSetScissorRect', (), None),
  201.     ('SVGA_3D_CMD_BEGIN_QUERY', 'SVGA3dCmdBeginQuery', (), None),
  202.     ('SVGA_3D_CMD_END_QUERY', 'SVGA3dCmdEndQuery', (), None),
  203.     ('SVGA_3D_CMD_WAIT_FOR_QUERY', 'SVGA3dCmdWaitForQuery', (), None),
  204.     #('SVGA_3D_CMD_PRESENT_READBACK', None, (), None),
  205.     ('SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN', 'SVGA3dCmdBlitSurfaceToScreen', (), 'SVGASignedRect'),
  206. ]
  207.  
  208. def dump_cmds():
  209.     print r'''
  210. void            
  211. svga_dump_command(uint32_t cmd_id, const void *data, uint32_t size)
  212. {
  213.   const uint8_t *body = (const uint8_t *)data;
  214.   const uint8_t *next = body + size;
  215. '''
  216.     print '   switch(cmd_id) {'
  217.     indexes = 'ijklmn'
  218.     for id, header, body, footer in cmds:
  219.         print '   case %s:' % id
  220.         print '      _debug_printf("\\t%s\\n");' % id
  221.         print '      {'
  222.         print '         const %s *cmd = (const %s *)body;' % (header, header)
  223.         if len(body):
  224.             print '         unsigned ' + ', '.join(indexes[:len(body)]) + ';'
  225.         print '         dump_%s(cmd);' % header
  226.         print '         body = (const uint8_t *)&cmd[1];'
  227.         for i in range(len(body)):
  228.             struct, count = body[i]
  229.             idx = indexes[i]
  230.             print '         for(%s = 0; %s < cmd->%s; ++%s) {' % (idx, idx, count, idx)
  231.             print '            dump_%s((const %s *)body);' % (struct, struct)
  232.             print '            body += sizeof(%s);' % struct
  233.             print '         }'
  234.         if footer is not None:
  235.             print '         while(body + sizeof(%s) <= next) {' % footer
  236.             print '            dump_%s((const %s *)body);' % (footer, footer)
  237.             print '            body += sizeof(%s);' % footer
  238.             print '         }'
  239.         if id == 'SVGA_3D_CMD_SHADER_DEFINE':
  240.             print '         svga_shader_dump((const uint32_t *)body,'
  241.             print '                          (unsigned)(next - body)/sizeof(uint32_t),'
  242.             print '                          FALSE);'
  243.             print '         body = next;'
  244.         print '      }'
  245.         print '      break;'
  246.     print '   default:'
  247.     print '      _debug_printf("\\t0x%08x\\n", cmd_id);'
  248.     print '      break;'
  249.     print '   }'
  250.     print r'''
  251.   while(body + sizeof(uint32_t) <= next) {
  252.      _debug_printf("\t\t0x%08x\n", *(const uint32_t *)body);
  253.      body += sizeof(uint32_t);
  254.   }
  255.   while(body + sizeof(uint32_t) <= next)
  256.      _debug_printf("\t\t0x%02x\n", *body++);
  257. }
  258. '''
  259.     print r'''
  260. void            
  261. svga_dump_commands(const void *commands, uint32_t size)
  262. {
  263.   const uint8_t *next = commands;
  264.   const uint8_t *last = next + size;
  265.  
  266.   assert(size % sizeof(uint32_t) == 0);
  267.  
  268.   while(next < last) {
  269.      const uint32_t cmd_id = *(const uint32_t *)next;
  270.  
  271.      if(SVGA_3D_CMD_BASE <= cmd_id && cmd_id < SVGA_3D_CMD_MAX) {
  272.         const SVGA3dCmdHeader *header = (const SVGA3dCmdHeader *)next;
  273.         const uint8_t *body = (const uint8_t *)&header[1];
  274.  
  275.         next = body + header->size;
  276.         if(next > last)
  277.            break;
  278.  
  279.         svga_dump_command(cmd_id, body, header->size);
  280.      }
  281.      else if(cmd_id == SVGA_CMD_FENCE) {
  282.         _debug_printf("\tSVGA_CMD_FENCE\n");
  283.         _debug_printf("\t\t0x%08x\n", ((const uint32_t *)next)[1]);
  284.         next += 2*sizeof(uint32_t);
  285.      }
  286.      else {
  287.         _debug_printf("\t0x%08x\n", cmd_id);
  288.         next += sizeof(uint32_t);
  289.      }
  290.   }
  291. }
  292. '''
  293.  
  294. def main():
  295.     print copyright.strip()
  296.     print
  297.     print '/**'
  298.     print ' * @file'
  299.     print ' * Dump SVGA commands.'
  300.     print ' *'
  301.     print ' * Generated automatically from svga3d_reg.h by svga_dump.py.'
  302.     print ' */'
  303.     print
  304.     print '#include "svga_types.h"'
  305.     print '#include "svga_shader_dump.h"'
  306.     print '#include "svga3d_reg.h"'
  307.     print
  308.     print '#include "util/u_debug.h"'
  309.     print '#include "svga_dump.h"'
  310.     print
  311.  
  312.     config = parser.config_t(
  313.         include_paths = ['../../../include', '../include'],
  314.         compiler = 'gcc',
  315.     )
  316.  
  317.     headers = [
  318.         'svga_types.h',
  319.         'svga3d_reg.h',
  320.     ]
  321.  
  322.     decls = parser.parse(headers, config, parser.COMPILATION_MODE.ALL_AT_ONCE)
  323.     global_ns = declarations.get_global_namespace(decls)
  324.  
  325.     names = set()
  326.     for id, header, body, footer in cmds:
  327.         names.add(header)
  328.         for struct, count in body:
  329.             names.add(struct)
  330.         if footer is not None:
  331.             names.add(footer)
  332.  
  333.     for class_ in global_ns.classes(lambda decl: decl.name in names):
  334.         dump_struct(decls, class_)
  335.  
  336.     dump_cmds()
  337.  
  338.  
  339. if __name__ == '__main__':
  340.     main()
  341.