VirtualBox

source: vbox/trunk/src/VBox/Devices/Graphics/svgadump/svga_dump.py@ 105852

Last change on this file since 105852 was 105852, checked in by vboxsync, 3 months ago

Device/VMSVGA: Use local copy of VMSVGA headers in svga_dump_command. bugref:10580

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette