VirtualBox

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

Last change on this file since 65641 was 65381, checked in by vboxsync, 8 years ago

bugref:8282: Additions/linux: submit DRM driver to the Linux kernel: move all graphics device-related header files to a separate sub-directory and add that to the include path where they are needed. The intention is too be able to remove the VBox/ include folder in the DRM driver package.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 13.6 KB
Line 
1# $Id: dlm_generated.py 65381 2017-01-20 09:23:53Z 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 ' VBoxDLOpCode iVBoxOpCode;'
89 print ' void (DLM_APIENTRY *execute)(DLMInstanceList *instance, SPUDispatchTable *dispatchTable);'
90 for (name, type, vecSize) in params:
91 # Watch out for the word "const" (which should be ignored)
92 # and for types that end in "*" (which are pointers and need
93 # special treatment)
94 words = type.split()
95 if words[0] == 'const':
96 words = words[1:]
97 if words[0] != "void":
98 print ' %s %s;' % (' '.join(words), name)
99
100 # If any argument was a pointer, we need a special pointer data
101 # array. The pointer data will be stored into this array, and
102 # references to the array will be generated as parameters.
103 if len(pointers) == 1:
104 if pointersize == None:
105 print " /* Oh no - pointer parameter %s found, but no pointer class specified and can't guess */" % pointername
106 else:
107 if pointersize == 'special':
108 print ' %s %s[1];%s' % (pointertype, pointerarg, pointercomment)
109 else:
110 print ' %s %s[%s];%s' % (pointertype, pointerarg, pointersize,pointercomment)
111 elif len(pointers) > 1:
112 print ' %s %s[1];%s' % (pointertype, pointerarg,pointercomment)
113
114 print '};'
115
116 # Pointers only happen with instances
117 if len(pointers) > 1 or (len(pointers) == 1 and pointersize == 'special'):
118 print 'int crdlm_pointers_%s(struct instance%s *instance, %s);' % (functionName, functionName, extendedArgstring)
119
120 # See if the GL function must sometimes allow passthrough even
121 # if the display list is open
122 if "checklist" in apiutil.ChromiumProps(functionName):
123 print 'int crdlm_checklist_%s(%s);' % (functionName, argstring)
124
125 return
126
127def wrap_execute(functionName):
128
129 params = apiutil.Parameters(functionName)
130 (pointers, _, pointerarg, _, _, _) = GetPointerInfo(functionName)
131
132 print 'static void execute%s(DLMInstanceList *x, SPUDispatchTable *dispatchTable)' % functionName
133 print '{'
134 if len(params) > 0:
135 print ' struct instance%s *instance = (struct instance%s *)x;' % (functionName, functionName)
136
137 if len(pointers) == 1:
138 print ' instance->%s = instance->%s;' % (params[pointers[0]][0], pointerarg)
139
140 print ' if (dispatchTable->%s != NULL)' % (functionName)
141 print ' dispatchTable->%s(%s);' % (functionName, InstanceCallString(params))
142 print ' else'
143 print ' crWarning("DLM warning: execute%s called with NULL dispatch entry");' % (functionName)
144 print '}'
145
146# These code snippets isolate the code required to add a given instance
147# to the display list correctly. They are used during generation, to
148# generate correct code, and also to create useful utilities.
149def AddInstanceToList(pad):
150 print '%s/* Add this instance to the current display list. */' % pad
151 print '%sinstance->next = NULL;' % pad
152 print '%sinstance->stateNext = NULL;' % pad
153 print '%sif (!state->currentListInfo->first) {' % pad
154 print '%s state->currentListInfo->first = (DLMInstanceList *)instance;' % pad
155 print '%s}' % pad
156 print '%selse {' % pad
157 print '%s state->currentListInfo->last->next = (DLMInstanceList *)instance;' % pad
158 print '%s}' % pad
159 print '%sstate->currentListInfo->last = (DLMInstanceList *)instance;' % pad
160 print '%sstate->currentListInfo->numInstances++;' % pad
161
162def AddInstanceToStateList(pad):
163 print '%s/* Instances that change state have to be added to the state list as well. */' % pad
164 print '%sif (!state->currentListInfo->stateFirst) {' % pad
165 print '%s state->currentListInfo->stateFirst = (DLMInstanceList *)instance;' % pad
166 print '%s}' % pad
167 print '%selse {' % pad
168 print '%s state->currentListInfo->stateLast->stateNext = (DLMInstanceList *)instance;' % pad
169 print '%s}' % pad
170 print '%sstate->currentListInfo->stateLast = (DLMInstanceList *)instance;' % pad
171
172
173# The compile wrapper collects the parameters into a DLMInstanceList
174# element, and adds that element to the end of the display list currently
175# being compiled.
176def wrap_compile(functionName):
177 params = apiutil.Parameters(functionName)
178 return_type = apiutil.ReturnType(functionName)
179 # Make sure the return type is void. It's nonsensical to compile
180 # an element with any other return type.
181 if return_type != 'void':
182 print '/* Nonsense: DL function %s has a %s return type?!? */' % (functionName, return_type)
183
184 # Define a structure to hold all the parameters. Note that the
185 # top parameters must exactly match the DLMInstanceList structure
186 # in include/cr_dlm.h, or everything will break horribly.
187 # Start off by getting all the pointer info we could ever use
188 # from the parameters
189 (pointers, pointername, pointerarg, pointertype, pointersize, pointercomment) = GetPointerInfo(functionName)
190
191 # Finally, the compile wrapper. This one will diverge strongly
192 # depending on whether or not there are pointer parameters.
193 callstring = apiutil.MakeCallString(params)
194 argstring = apiutil.MakeDeclarationString(params)
195 props = apiutil.Properties(functionName)
196 if "useclient" in props or "pixelstore" in props:
197 callstring += ", c"
198 argstring += ", CRClientState *c"
199 print 'void DLM_APIENTRY crDLMCompile%s(%s)' % (functionName, argstring)
200 print '{'
201 print ' CRDLMContextState *state = CURRENT_STATE();'
202 print ' struct instance%s *instance;' % (functionName)
203
204 # The calling SPU is supposed to verify that the element is supposed to be
205 # compiled before it is actually compiled; typically, this is done based
206 # on whether a glNewList has been executed more recently than a glEndList.
207 # But some functions are dual-natured, sometimes being compiled, and sometimes
208 # being executed immediately. We can check for this here.
209 if "checklist" in apiutil.ChromiumProps(functionName):
210 print ' if (crDLMCheckList%s(%s))' % (functionName, apiutil.MakeCallString(params))
211 print ' {'
212 print ' crdlm_error(__LINE__, __FILE__, GL_INVALID_OPERATION,'
213 print ' "this instance of function %s should not be compiled");' % functionName;
214 print ' return;'
215 print ' }'
216
217 if len(pointers) > 1 or pointersize == 'special':
218 # Pass NULL, to just allocate space
219 print ' instance = crCalloc(sizeof(struct instance%s) + crdlm_pointers_%s(NULL, %s));' % (functionName, functionName, callstring)
220 else:
221 print ' instance = crCalloc(sizeof(struct instance%s));' % (functionName)
222 print ' if (!instance)'
223 print ' {'
224 print ' crdlm_error(__LINE__, __FILE__, GL_OUT_OF_MEMORY,'
225 print ' "out of memory adding %s to display list");' % (functionName)
226 print ' return;'
227 print ' }'
228
229 # Put in the fields that must always exist
230 print ' instance->execute = execute%s;' % functionName
231
232 # Apply all the simple (i.e. non-pointer) parameters
233 for index in range(len(params)):
234 if index not in pointers:
235 name = params[index][0]
236 print ' instance->%s = %s;' % (name, name)
237
238 # We need to know instance size in bytes in order to save its state later.
239 print ' instance->cbInstance = sizeof(struct instance%s);' % functionName
240
241 # Set OPCODE.
242 print ' instance->iVBoxOpCode = VBOX_DL_OPCODE_%s;' % functionName
243
244 # If there's a pointer parameter, apply it.
245 if len(pointers) == 1:
246
247 print ' if (%s == NULL)' % (params[pointers[0]][0])
248 print ' instance->%s = NULL;' % (params[pointers[0]][0])
249 print ' else'
250 print ' instance->%s = instance->%s;' % (params[pointers[0]][0], pointerarg)
251
252 if pointersize == 'special':
253 print ' instance->cbInstance += crdlm_pointers_%s(instance, %s);' % (functionName, callstring)
254 else:
255 print ' crMemcpy((void *)instance->%s, (void *) %s, %s*sizeof(%s));' % (params[pointers[0]][0], params[pointers[0]][0], pointersize, pointertype)
256 elif len(pointers) == 2:
257 # this seems to work
258 print ' instance->cbInstance += crdlm_pointers_%s(instance, %s);' % (functionName, callstring)
259 elif len(pointers) > 2:
260 print "#error don't know how to handle pointer parameters for %s" % (functionName)
261
262 # Add the element to the current display list
263 AddInstanceToList(' ')
264 # If the element is a state-changing element, add it to the current state list
265 if apiutil.SetsTrackedState(functionName):
266 AddInstanceToStateList(' ')
267 print '}'
268
269whichfile=sys.argv[1]
270if whichfile == 'headers':
271 print """#ifndef _DLM_GENERATED_H
272#define _DLM_GENERATED_H
273
274#include <VBoxUhgsmi.h>
275
276/* DO NOT EDIT. This file is auto-generated by dlm_generated.py. */
277"""
278else:
279 print """#include <stdio.h>
280#include "cr_spu.h"
281#include "cr_dlm.h"
282#include "cr_mem.h"
283#include "cr_error.h"
284#include "state/cr_statefuncs.h"
285#include "dlm.h"
286#include "dlm_pointers.h"
287#include "dlm_generated.h"
288
289/* DO NOT EDIT. This file is auto-generated by dlm_generated.py. */
290"""
291
292# Add in the "add_to_dl" utility function, which will be used by
293# external (i.e. non-generated) functions. The utility ensures that
294# any external functions that are written for compiling elements
295# don't have to be rewritten if the conventions for adding to display
296# lists are changed.
297print """
298void crdlm_add_to_list(
299 DLMInstanceList *instance,
300 void (*executeFunc)(DLMInstanceList *x, SPUDispatchTable *dispatchTable)"""
301
302if (whichfile == 'headers'):
303 print ");"
304else:
305 print """) {
306 CRDLMContextState *state = CURRENT_STATE();
307 instance->execute = executeFunc;"""
308
309 # Add in the common code for adding the instance to the display list
310 AddInstanceToList(" ")
311
312 print '}'
313 print ''
314
315# Now generate the functions that won't use the crdlm_add_to_list utility.
316# These all directly add their own instances to the current display list
317# themselves, without using the crdlm_add_to_list() function.
318keys = apiutil.GetDispatchedFunctions(sys.argv[3]+"/APIspec.txt")
319for func_name in keys:
320 if apiutil.CanCompile(func_name):
321 print "\n/*** %s ***/" % func_name
322 # Auto-generate an appropriate DL function. First, functions
323 # that go into the display list but that rely on state will
324 # have to have their argument strings expanded, to take pointers
325 # to that appropriate state.
326 if whichfile == "headers":
327 wrap_struct(func_name)
328 elif not apiutil.FindSpecial("dlm", func_name):
329 wrap_execute(func_name)
330 wrap_compile(func_name)
331
332
333# Generate mapping between OPCODE and routines to be executed.
334
335if whichfile == "headers":
336 # Execute routine prototype needed to add static array of routines.
337 print ''
338 print 'struct DLMInstanceList;'
339 print 'typedef void (*VBoxDLMExecuteFn)(struct DLMInstanceList *instance, SPUDispatchTable *dispatchTable);'
340 print ''
341 print 'extern VBoxDLMExecuteFn g_VBoxDLMExecuteFns[VBOX_DL_OPCODE_MAX];'
342 print ''
343else:
344 print ''
345 print 'VBoxDLMExecuteFn g_VBoxDLMExecuteFns[] = {'
346
347 for func_name in keys:
348 if apiutil.CanCompile(func_name) and not apiutil.FindSpecial("dlm", func_name):
349 print ' execute%s,' % func_name
350
351 print '};'
352 print ''
353
354if whichfile == 'headers':
355 print "#endif /* _DLM_GENERATED_H */"
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