1 | '''
|
---|
2 | Generates dumper for the SVGA 3D command stream using pygccxml.
|
---|
3 |
|
---|
4 | Jose Fonseca <[email protected]>
|
---|
5 | '''
|
---|
6 |
|
---|
7 | copyright = '''
|
---|
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 | '''
|
---|
35 | The script was reworked for Python 3 by VirtualBox.
|
---|
36 | '''
|
---|
37 |
|
---|
38 | import os
|
---|
39 | import sys
|
---|
40 |
|
---|
41 | from pygccxml import parser
|
---|
42 | from pygccxml import declarations
|
---|
43 | from pygccxml import utils
|
---|
44 |
|
---|
45 | from pygccxml.declarations import algorithm
|
---|
46 | from pygccxml.declarations import decl_visitor
|
---|
47 | from pygccxml.declarations import type_traits
|
---|
48 | from pygccxml.declarations import type_visitor
|
---|
49 |
|
---|
50 |
|
---|
51 | enums = True
|
---|
52 |
|
---|
53 |
|
---|
54 | class 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 |
|
---|
90 | def dump_decl(instance, decl):
|
---|
91 | dumper = decl_dumper_t(instance, decl)
|
---|
92 | algorithm.apply_visitor(dumper, decl)
|
---|
93 |
|
---|
94 |
|
---|
95 | class 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 |
|
---|
166 | def 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 |
|
---|
172 | def 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 |
|
---|
181 | cmds = [
|
---|
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 |
|
---|
224 | def dump_cmds():
|
---|
225 | print(r'''
|
---|
226 | void
|
---|
227 | svga_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'''
|
---|
276 | void
|
---|
277 | svga_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 |
|
---|
310 | def 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 |
|
---|
372 | if __name__ == '__main__':
|
---|
373 | main()
|
---|
374 |
|
---|