Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4358 | Serge | 1 | #!/usr/bin/env python |
2 | ''' |
||
3 | Generates dumper for the SVGA 3D command stream using pygccxml. |
||
4 | |||
5 | Jose Fonseca |
||
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 | |||
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 | |||
304 | print '#include "svga_types.h"' |
||
305 | print '#include "svga_shader_dump.h"' |
||
306 | print '#include "svga3d_reg.h"' |
||
307 | |||
308 | print '#include "util/u_debug.h"' |
||
309 | print '#include "svga_dump.h"' |
||
310 | |||
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()>=>>=>=>=>> |