1 #!/usr/bin/env python 2 ''' 3 Generates dumper for the SVGA 3D command stream using pygccxml. 4 5 Jose Fonseca <jfonseca (at] 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