VirtualBox

source: vbox/trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_generated.py@ 55762

Last change on this file since 55762 was 55762, checked in by vboxsync, 10 years ago

Host 3D: DLM: dump local stuff (preparing for saving Display Lists).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 14.9 KB
Line 
1# $Id: dlm_generated.py 55762 2015-05-08 18:05:43Z vboxsync $
2import sys, cPickle, re
3
4sys.path.append( "../glapi_parser" )
5import apiutil
6
7# A routine that can create call strings from instance names
8def InstanceCallString( params ):
9 output = ''
10 for index in range(0,len(params)):
11 if index > 0:
12 output += ", "
13 if params[index][0] != '':
14 output += 'instance->' + params[index][0]
15 return output
16
17def GetPointerType(basetype):
18 words = basetype.split()
19 if words[0] == 'const':
20 words = words[1:]
21 if words[-1].endswith('*'):
22 words[-1] = words[-1][:-1].strip()
23 if words[-1] == '':
24 words = words[:-1]
25 if words[0] == 'void' or words[0] == 'GLvoid':
26 words[0] = 'int'
27 return ' '.join(words)
28
29
30def GetPointerInfo(functionName):
31 # We'll keep track of all the parameters that require pointers.
32 # They'll require special handling later.
33 params = apiutil.Parameters(functionName)
34 pointers = []
35 pointername=''
36 pointerarg=''
37 pointertype=''
38 pointersize=0
39 pointercomment=''
40
41 index = 0
42 for (name, type, vecSize) in params:
43 # Watch out for the word "const" (which should be ignored)
44 # and for types that end in "*" (which are pointers and need
45 # special treatment)
46 words = type.split()
47 if words[-1].endswith('*'):
48 pointers.append(index)
49 index += 1
50
51 # If any argument was a pointer, we need a special pointer data
52 # array. The pointer data will be stored into this array, and
53 # references to the array will be generated as parameters.
54 if len(pointers) == 1:
55 index = pointers[0]
56 pointername = params[index][0]
57 pointerarg = pointername + 'Data'
58 pointertype = GetPointerType(params[index][1])
59 pointersize = params[index][2]
60 if pointersize == 0:
61 pointersize = "special"
62 elif len(pointers) > 1:
63 pointerarg = 'data';
64 pointertype = GetPointerType(params[pointers[0]][1])
65 for index in range(1,len(pointers)):
66 if GetPointerType(params[pointers[index]][1]) != pointertype:
67 pointertype = 'GLvoid *'
68
69 return (pointers,pointername,pointerarg,pointertype,pointersize,pointercomment)
70
71def wrap_struct(functionName):
72 params = apiutil.Parameters(functionName)
73 argstring = apiutil.MakeDeclarationString(params)
74 extendedArgstring = argstring
75 props = apiutil.Properties(functionName)
76 if "useclient" in props or "pixelstore" in props:
77 extendedArgstring += ", CRClientState *c"
78
79 # We'll keep track of all the parameters that require pointers.
80 # They'll require special handling later.
81 (pointers, pointername, pointerarg, pointertype, pointersize, pointercomment) = GetPointerInfo(functionName)
82
83 # Start writing the header
84 print 'struct instance%s {' % (functionName)
85 print ' DLMInstanceList *next;'
86 print ' DLMInstanceList *stateNext;'
87 print ' int cbInstance;'
88 print ' void (DLM_APIENTRY *execute)(DLMInstanceList *instance, SPUDispatchTable *dispatchTable);'
89 for (name, type, vecSize) in params:
90 # Watch out for the word "const" (which should be ignored)
91 # and for types that end in "*" (which are pointers and need
92 # special treatment)
93 words = type.split()
94 if words[0] == 'const':
95 words = words[1:]
96 if words[0] != "void":
97 print ' %s %s;' % (' '.join(words), name)
98
99 # If any argument was a pointer, we need a special pointer data
100 # array. The pointer data will be stored into this array, and
101 # references to the array will be generated as parameters.
102 if len(pointers) == 1:
103 if pointersize == None:
104 print " /* Oh no - pointer parameter %s found, but no pointer class specified and can't guess */" % pointername
105 else:
106 if pointersize == 'special':
107 print ' %s %s[1];%s' % (pointertype, pointerarg, pointercomment)
108 else:
109 print ' %s %s[%s];%s' % (pointertype, pointerarg, pointersize,pointercomment)
110 elif len(pointers) > 1:
111 print ' %s %s[1];%s' % (pointertype, pointerarg,pointercomment)
112
113 print '};'
114
115 # Pointers only happen with instances
116 if len(pointers) > 1 or (len(pointers) == 1 and pointersize == 'special'):
117 print 'int crdlm_pointers_%s(struct instance%s *instance, %s);' % (functionName, functionName, extendedArgstring)
118
119 # See if the GL function must sometimes allow passthrough even
120 # if the display list is open
121 if "checklist" in apiutil.ChromiumProps(functionName):
122 print 'int crdlm_checklist_%s(%s);' % (functionName, argstring)
123
124 return
125
126def wrap_execute(functionName):
127 params = apiutil.Parameters(functionName)
128 print 'static void execute%s(DLMInstanceList *x, SPUDispatchTable *dispatchTable)' % functionName
129 print '{'
130 if len(params) > 0:
131 print '\tstruct instance%s *instance = (struct instance%s *)x;' % (functionName, functionName)
132 print '\tif (dispatchTable->%s != NULL) {' % (functionName)
133 print '\t\tdispatchTable->%s(%s);' % (functionName, InstanceCallString(params))
134 print '\t}'
135 print '\telse {'
136 print '\t\tcrWarning("DLM warning: execute%s called with NULL dispatch entry");' % (functionName)
137 print '\t}'
138 print '}'
139
140def generate_bbox_code(functionName):
141 assert functionName[0:6] == "Vertex"
142 pattern = "(VertexAttribs|VertexAttrib|Vertex)(1|2|3|4)(N?)(f|d|i|s|b|ub|us|ui)(v?)"
143 m = re.match(pattern, functionName)
144 if m:
145 name = m.group(1)
146 size = int(m.group(2))
147 normalize = m.group(3)
148 type = m.group(4)
149 vector = m.group(5)
150
151 # only update bbox for vertex attribs if index == 0
152 if name == "VertexAttrib":
153 test = "if (index == 0) {"
154 elif name == "VertexAttribs":
155 test = "if (index == 0) {"
156 else:
157 assert name == "Vertex"
158 test = "{"
159
160 # find names of the X, Y, Z, W values
161 xName = ""
162 yName = ""
163 zName = "0.0"
164 wName = ""
165 if vector == "v":
166 xName = "v[0]"
167 if size > 1:
168 yName = "v[1]"
169 if size > 2:
170 zName = "v[2]"
171 if size > 3:
172 wName = "v[3]"
173 else:
174 xName = "x"
175 if size > 1:
176 yName = "y"
177 if size > 2:
178 zName = "z"
179 if size > 3:
180 wName = "w"
181
182 # start emitting code
183 print '\t%s' % test
184
185 if normalize == "N":
186 if type == "b":
187 denom = "128.0f"
188 elif type == "s":
189 denom = "32768.0f"
190 elif type == "i":
191 denom = "2147483647.0f"
192 elif type == "ub":
193 denom = "255.0f"
194 elif type == "us":
195 denom = "65535.0f"
196 elif type == "ui":
197 denom = "4294967295.0f"
198
199 print '\t\tGLfloat nx = (GLfloat) %s / %s;' % (xName, denom)
200 xName = "nx"
201 if yName:
202 print '\t\tGLfloat ny = (GLfloat) %s / %s;' % (yName, denom)
203 yName = "ny"
204 if zName:
205 print '\t\tGLfloat nz = (GLfloat) %s / %s;' % (zName, denom)
206 zName = "nz"
207 if 0 and wName:
208 print '\t\tGLfloat nw = (GLfloat) %s / %s;' % (wName, denom)
209 wName = "nw"
210
211 if xName:
212 print '\t\tif (%s < state->currentListInfo->bbox.xmin)' % xName
213 print '\t\t\tstate->currentListInfo->bbox.xmin = %s;' % xName
214 print '\t\tif (%s > state->currentListInfo->bbox.xmax)' % xName
215 print '\t\t\tstate->currentListInfo->bbox.xmax = %s;' % xName
216 if yName:
217 print '\t\tif (%s < state->currentListInfo->bbox.ymin)' % yName
218 print '\t\t\tstate->currentListInfo->bbox.ymin = %s;' % yName
219 print '\t\tif (%s > state->currentListInfo->bbox.ymax)' % yName
220 print '\t\t\tstate->currentListInfo->bbox.ymax = %s;' % yName
221 if zName:
222 print '\t\tif (%s < state->currentListInfo->bbox.zmin)' % zName
223 print '\t\t\tstate->currentListInfo->bbox.zmin = %s;' % zName
224 print '\t\tif (%s > state->currentListInfo->bbox.zmax)' % zName
225 print '\t\t\tstate->currentListInfo->bbox.zmax = %s;' % zName
226 # XXX what about divide by W if we have 4 components?
227 print '\t}'
228
229 else:
230 print ' /* bbox error for %s !!!!! */' % functionName
231
232# These code snippets isolate the code required to add a given instance
233# to the display list correctly. They are used during generation, to
234# generate correct code, and also to create useful utilities.
235def AddInstanceToList(pad):
236 print '%s/* Add this instance to the current display list. */' % pad
237 print '%sinstance->next = NULL;' % pad
238 print '%sinstance->stateNext = NULL;' % pad
239 print '%sif (!state->currentListInfo->first) {' % pad
240 print '%s\tstate->currentListInfo->first = (DLMInstanceList *)instance;' % pad
241 print '%s}' % pad
242 print '%selse {' % pad
243 print '%s\tstate->currentListInfo->last->next = (DLMInstanceList *)instance;' % pad
244 print '%s}' % pad
245 print '%sstate->currentListInfo->last = (DLMInstanceList *)instance;' % pad
246 print '%sstate->currentListInfo->numInstances++;' % pad
247
248def AddInstanceToStateList(pad):
249 print '%s/* Instances that change state have to be added to the state list as well. */' % pad
250 print '%sif (!state->currentListInfo->stateFirst) {' % pad
251 print '%s\tstate->currentListInfo->stateFirst = (DLMInstanceList *)instance;' % pad
252 print '%s}' % pad
253 print '%selse {' % pad
254 print '%s\tstate->currentListInfo->stateLast->stateNext = (DLMInstanceList *)instance;' % pad
255 print '%s}' % pad
256 print '%sstate->currentListInfo->stateLast = (DLMInstanceList *)instance;' % pad
257
258
259# The compile wrapper collects the parameters into a DLMInstanceList
260# element, and adds that element to the end of the display list currently
261# being compiled.
262def wrap_compile(functionName):
263 params = apiutil.Parameters(functionName)
264 return_type = apiutil.ReturnType(functionName)
265 # Make sure the return type is void. It's nonsensical to compile
266 # an element with any other return type.
267 if return_type != 'void':
268 print '/* Nonsense: DL function %s has a %s return type?!? */' % (functionName, return_type)
269 # return
270 # Define a structure to hold all the parameters. Note that the
271 # top parameters must exactly match the DLMInstanceList structure
272 # in include/cr_dlm.h, or everything will break horribly.
273 # Start off by getting all the pointer info we could ever use
274 # from the parameters
275 (pointers, pointername, pointerarg, pointertype, pointersize, pointercomment) = GetPointerInfo(functionName)
276
277 # Finally, the compile wrapper. This one will diverge strongly
278 # depending on whether or not there are pointer parameters.
279 callstring = apiutil.MakeCallString(params)
280 argstring = apiutil.MakeDeclarationString(params)
281 props = apiutil.Properties(functionName)
282 if "useclient" in props or "pixelstore" in props:
283 callstring += ", c"
284 argstring += ", CRClientState *c"
285 print 'void DLM_APIENTRY crDLMCompile%s( %s )' % (functionName, argstring)
286 print '{'
287 print ' CRDLMContextState *state = CURRENT_STATE();'
288 print ' struct instance%s *instance;' % (functionName)
289
290 # The calling SPU is supposed to verify that the element is supposed to be
291 # compiled before it is actually compiled; typically, this is done based
292 # on whether a glNewList has been executed more recently than a glEndList.
293 # But some functions are dual-natured, sometimes being compiled, and sometimes
294 # being executed immediately. We can check for this here.
295 if "checklist" in apiutil.ChromiumProps(functionName):
296 print '\tif (crDLMCheckList%s(%s)) {' % (functionName, apiutil.MakeCallString(params))
297 print '\t\tcrdlm_error(__LINE__, __FILE__, GL_INVALID_OPERATION,'
298 print '\t\t "this instance of function %s should not be compiled");' % functionName;
299 print '\t\treturn;'
300 print '\t}'
301
302 if len(pointers) > 1 or pointersize == 'special':
303 # Pass NULL, to just allocate space
304 print '\tinstance = crCalloc(sizeof(struct instance%s) + crdlm_pointers_%s(NULL, %s));' % (functionName, functionName, callstring)
305 else:
306 print '\tinstance = crCalloc(sizeof(struct instance%s));' % (functionName)
307 print '\tif (!instance) {'
308 print '\t\tcrdlm_error(__LINE__, __FILE__, GL_OUT_OF_MEMORY,'
309 print '\t\t\t"out of memory adding %s to display list");' % (functionName)
310 print '\t\treturn;'
311 print '\t}'
312
313 # Put in the fields that must always exist
314 print '\tinstance->execute = execute%s;' % functionName
315
316 # Apply all the simple (i.e. non-pointer) parameters
317 for index in range(len(params)):
318 if index not in pointers:
319 name = params[index][0]
320 print '\tinstance->%s = %s;' % (name, name)
321
322 # We need to know instance size in bytes in order to save its state later.
323 print '\tinstance->cbInstance = sizeof(struct instance%s);' % functionName
324
325 # If there's a pointer parameter, apply it.
326 if len(pointers) == 1:
327 print '\tif (%s == NULL) {' % (params[pointers[0]][0])
328 print '\t\tinstance->%s = NULL;' % (params[pointers[0]][0])
329 print '\t}'
330 print '\telse {'
331 print '\t\tinstance->%s = instance->%s;' % (params[pointers[0]][0], pointerarg)
332 print '\t}'
333 if pointersize == 'special':
334 print '\tinstance->cbInstance += crdlm_pointers_%s(instance, %s);' % (functionName, callstring)
335 else:
336 print '\tcrMemcpy((void *)instance->%s, (void *) %s, %s*sizeof(%s));' % (params[pointers[0]][0], params[pointers[0]][0], pointersize, pointertype)
337 elif len(pointers) == 2:
338 # this seems to work
339 print '\tinstance->cbInstance += crdlm_pointers_%s(instance, %s);' % (functionName, callstring)
340 elif len(pointers) > 2:
341 print "#error don't know how to handle pointer parameters for %s" % (functionName)
342
343 # Add the element to the current display list
344 AddInstanceToList('\t')
345 # If the element is a state-changing element, add it to the current state list
346 if apiutil.SetsTrackedState(functionName):
347 AddInstanceToStateList('\t')
348
349 # XXX might need a better test here
350 if functionName[0:6] == "Vertex":
351 generate_bbox_code(functionName)
352
353 print '}'
354
355whichfile=sys.argv[1]
356if whichfile == 'headers':
357 print """#ifndef _DLM_GENERATED_H
358#define _DLM_GENERATED_H
359
360/* DO NOT EDIT. This file is auto-generated by dlm_generated.py. */
361"""
362else:
363 print """#include <stdio.h>
364#include "cr_spu.h"
365#include "cr_dlm.h"
366#include "cr_mem.h"
367#include "cr_error.h"
368#include "state/cr_statefuncs.h"
369#include "dlm.h"
370#include "dlm_pointers.h"
371#include "dlm_generated.h"
372
373/* DO NOT EDIT. This file is auto-generated by dlm_generated.py. */
374"""
375
376# Add in the "add_to_dl" utility function, which will be used by
377# external (i.e. non-generated) functions. The utility ensures that
378# any external functions that are written for compiling elements
379# don't have to be rewritten if the conventions for adding to display
380# lists are changed.
381print """
382void crdlm_add_to_list(
383 DLMInstanceList *instance,
384 void (*executeFunc)(DLMInstanceList *x, SPUDispatchTable *dispatchTable)"""
385
386if (whichfile == 'headers'):
387 print ");"
388else:
389 print """) {
390 CRDLMContextState *state = CURRENT_STATE();
391 instance->execute = executeFunc;"""
392
393 # Add in the common code for adding the instance to the display list
394 AddInstanceToList(" ")
395
396 print '}'
397 print ''
398
399# Now generate the functions that won't use the crdlm_add_to_list utility.
400# These all directly add their own instances to the current display list
401# themselves, without using the crdlm_add_to_list() function.
402keys = apiutil.GetDispatchedFunctions(sys.argv[3]+"/APIspec.txt")
403for func_name in keys:
404 if apiutil.CanCompile(func_name):
405 print "\n/*** %s ***/" % func_name
406 # Auto-generate an appropriate DL function. First, functions
407 # that go into the display list but that rely on state will
408 # have to have their argument strings expanded, to take pointers
409 # to that appropriate state.
410 if whichfile == "headers":
411 wrap_struct(func_name)
412 elif not apiutil.FindSpecial("dlm", func_name):
413 wrap_execute(func_name)
414 wrap_compile(func_name)
415 # All others just pass through
416
417if whichfile == 'headers':
418 print "#endif /* _DLM_GENERATED_H */"
Note: See TracBrowser for help on using the repository browser.

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