Merge branch 'mesa_7_6_branch' into mesa_7_7_branch
[mesa.git] / src / gallium / drivers / svga / svgadump / svga_dump.py
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 ]
206
207 def dump_cmds():
208 print r'''
209 void
210 svga_dump_commands(const void *commands, uint32_t size)
211 {
212 const uint8_t *next = commands;
213 const uint8_t *last = next + size;
214
215 assert(size % sizeof(uint32_t) == 0);
216
217 while(next < last) {
218 const uint32_t cmd_id = *(const uint32_t *)next;
219
220 if(SVGA_3D_CMD_BASE <= cmd_id && cmd_id < SVGA_3D_CMD_MAX) {
221 const SVGA3dCmdHeader *header = (const SVGA3dCmdHeader *)next;
222 const uint8_t *body = (const uint8_t *)&header[1];
223
224 next = (const uint8_t *)body + header->size;
225 if(next > last)
226 break;
227 '''
228
229 print ' switch(cmd_id) {'
230 indexes = 'ijklmn'
231 for id, header, body, footer in cmds:
232 print ' case %s:' % id
233 print ' debug_printf("\\t%s\\n");' % id
234 print ' {'
235 print ' const %s *cmd = (const %s *)body;' % (header, header)
236 if len(body):
237 print ' unsigned ' + ', '.join(indexes[:len(body)]) + ';'
238 print ' dump_%s(cmd);' % header
239 print ' body = (const uint8_t *)&cmd[1];'
240 for i in range(len(body)):
241 struct, count = body[i]
242 idx = indexes[i]
243 print ' for(%s = 0; %s < cmd->%s; ++%s) {' % (idx, idx, count, idx)
244 print ' dump_%s((const %s *)body);' % (struct, struct)
245 print ' body += sizeof(%s);' % struct
246 print ' }'
247 if footer is not None:
248 print ' while(body + sizeof(%s) <= next) {' % footer
249 print ' dump_%s((const %s *)body);' % (footer, footer)
250 print ' body += sizeof(%s);' % footer
251 print ' }'
252 if id == 'SVGA_3D_CMD_SHADER_DEFINE':
253 print ' sh_svga_dump((const uint32_t *)body, (unsigned)(next - body)/sizeof(uint32_t));'
254 print ' body = next;'
255 print ' }'
256 print ' break;'
257 print ' default:'
258 print ' debug_printf("\\t0x%08x\\n", cmd_id);'
259 print ' break;'
260 print ' }'
261
262 print r'''
263 while(body + sizeof(uint32_t) <= next) {
264 debug_printf("\t\t0x%08x\n", *(const uint32_t *)body);
265 body += sizeof(uint32_t);
266 }
267 while(body + sizeof(uint32_t) <= next)
268 debug_printf("\t\t0x%02x\n", *body++);
269 }
270 else if(cmd_id == SVGA_CMD_FENCE) {
271 debug_printf("\tSVGA_CMD_FENCE\n");
272 debug_printf("\t\t0x%08x\n", ((const uint32_t *)next)[1]);
273 next += 2*sizeof(uint32_t);
274 }
275 else {
276 debug_printf("\t0x%08x\n", cmd_id);
277 next += sizeof(uint32_t);
278 }
279 }
280 }
281 '''
282
283 def main():
284 print copyright.strip()
285 print
286 print '/**'
287 print ' * @file'
288 print ' * Dump SVGA commands.'
289 print ' *'
290 print ' * Generated automatically from svga3d_reg.h by svga_dump.py.'
291 print ' */'
292 print
293 print '#include "svga_types.h"'
294 print '#include "svga_shader_dump.h"'
295 print '#include "svga3d_reg.h"'
296 print
297 print '#include "pipe/p_debug.h"'
298 print '#include "svga_dump.h"'
299 print
300
301 config = parser.config_t(
302 include_paths = ['include'],
303 compiler = 'gcc',
304 )
305
306 headers = [
307 'include/svga_types.h',
308 'include/svga3d_reg.h',
309 ]
310
311 decls = parser.parse(headers, config, parser.COMPILATION_MODE.ALL_AT_ONCE)
312 global_ns = declarations.get_global_namespace(decls)
313
314 names = set()
315 for id, header, body, footer in cmds:
316 names.add(header)
317 for struct, count in body:
318 names.add(struct)
319 if footer is not None:
320 names.add(footer)
321
322 for class_ in global_ns.classes(lambda decl: decl.name in names):
323 dump_struct(decls, class_)
324
325 dump_cmds()
326
327
328 if __name__ == '__main__':
329 main()