blob: 6ae5fa2644fa450954d609425047a33b5aa96e27 [file] [log] [blame]
Tobin Ehlis12076fc2014-10-22 09:06:33 -06001#!/usr/bin/env python3
2#
3# XGL
4#
5# Copyright (C) 2014 LunarG, Inc.
6#
7# Permission is hereby granted, free of charge, to any person obtaining a
8# copy of this software and associated documentation files (the "Software"),
9# to deal in the Software without restriction, including without limitation
10# the rights to use, copy, modify, merge, publish, distribute, sublicense,
11# and/or sell copies of the Software, and to permit persons to whom the
12# Software is furnished to do so, subject to the following conditions:
13#
14# The above copyright notice and this permission notice shall be included
15# in all copies or substantial portions of the Software.
16#
17# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23# DEALINGS IN THE SOFTWARE.
24#
25# Authors:
26# Chia-I Wu <olv@lunarg.com>
27
28import sys
29
30import xgl
31
32class Subcommand(object):
33 def __init__(self, argv):
34 self.argv = argv
35 self.protos = ()
36 self.headers = ()
37
38 def run(self):
39 self.protos = xgl.core + xgl.ext_wsi_x11
40 self.headers = xgl.core_headers + xgl.ext_wsi_x11_headers
41 print(self.generate())
42
43 def generate(self):
44 copyright = self.generate_copyright()
45 header = self.generate_header()
46 body = self.generate_body()
47 footer = self.generate_footer()
48
49 contents = []
50 if copyright:
51 contents.append(copyright)
52 if header:
53 contents.append(header)
54 if body:
55 contents.append(body)
56 if footer:
57 contents.append(footer)
58
59 return "\n\n".join(contents)
60
61 def generate_copyright(self):
62 return """/* THIS FILE IS GENERATED. DO NOT EDIT. */
63
64/*
65 * XGL
66 *
67 * Copyright (C) 2014 LunarG, Inc.
68 *
69 * Permission is hereby granted, free of charge, to any person obtaining a
70 * copy of this software and associated documentation files (the "Software"),
71 * to deal in the Software without restriction, including without limitation
72 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
73 * and/or sell copies of the Software, and to permit persons to whom the
74 * Software is furnished to do so, subject to the following conditions:
75 *
76 * The above copyright notice and this permission notice shall be included
77 * in all copies or substantial portions of the Software.
78 *
79 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
80 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
81 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
82 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
83 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
84 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
85 * DEALINGS IN THE SOFTWARE.
86 */"""
87
88 def generate_header(self):
89 return "\n".join(["#include <" + h + ">" for h in self.headers])
90
91 def generate_body(self):
92 pass
93
94 def generate_footer(self):
95 pass
96
97 # Return set of printf '%' qualifier and input to that qualifier
Tobin Ehlise7271572014-11-19 15:52:46 -070098 def _get_printf_params(self, xgl_type, name, output_param):
Tobin Ehlis12076fc2014-10-22 09:06:33 -060099 # TODO : Need ENUM and STRUCT checks here
100 if "_TYPE" in xgl_type: # TODO : This should be generic ENUM check
101 return ("%s", "string_%s(%s)" % (xgl_type.strip('const ').strip('*'), name))
102 if "XGL_CHAR*" == xgl_type:
103 return ("%s", name)
104 if "UINT64" in xgl_type:
105 if '*' in xgl_type:
106 return ("%lu", "*%s" % name)
107 return ("%lu", name)
108 if "FLOAT" in xgl_type:
109 if '[' in xgl_type: # handle array, current hard-coded to 4 (TODO: Make this dynamic)
110 return ("[%f, %f, %f, %f]", "%s[0], %s[1], %s[2], %s[3]" % (name, name, name, name))
111 return ("%f", name)
Tobin Ehlis3a1cc8d2014-11-11 17:28:22 -0700112 if "BOOL" in xgl_type or 'xcb_randr_crtc_t' in xgl_type:
Tobin Ehlis12076fc2014-10-22 09:06:33 -0600113 return ("%u", name)
Tobin Ehlis3a1cc8d2014-11-11 17:28:22 -0700114 if True in [t in xgl_type for t in ["INT", "SIZE", "FLAGS", "MASK", "xcb_window_t"]]:
Tobin Ehlis12076fc2014-10-22 09:06:33 -0600115 if '[' in xgl_type: # handle array, current hard-coded to 4 (TODO: Make this dynamic)
116 return ("[%i, %i, %i, %i]", "%s[0], %s[1], %s[2], %s[3]" % (name, name, name, name))
117 if '*' in xgl_type:
118 return ("%i", "*%s" % name)
119 return ("%i", name)
Tobin Ehlis3a1cc8d2014-11-11 17:28:22 -0700120 # TODO : This is special-cased as there's only one "format" param currently and it's nice to expand it
121 if "XGL_FORMAT" == xgl_type and "format" == name:
122 return ("{format.channelFormat = %s, format.numericFormat = %s}", "string_XGL_CHANNEL_FORMAT(format.channelFormat), string_XGL_NUM_FORMAT(format.numericFormat)")
Tobin Ehlise7271572014-11-19 15:52:46 -0700123 if output_param:
Tobin Ehlis12076fc2014-10-22 09:06:33 -0600124 return ("%p", "(void*)*%s" % name)
125 return ("%p", "(void*)%s" % name)
126
Tobin Ehlisd49efcb2014-11-25 17:43:26 -0700127 def _generate_dispatch_entrypoints(self, qual="", layer="Generic", no_addr=False):
Tobin Ehlis12076fc2014-10-22 09:06:33 -0600128 if qual:
129 qual += " "
130
Tobin Ehlisa363cfa2014-11-25 16:59:27 -0700131 layer_name = layer
Tobin Ehlisd49efcb2014-11-25 17:43:26 -0700132 if no_addr:
133 layer_name = "%sNoAddr" % layer
Tobin Ehlis12076fc2014-10-22 09:06:33 -0600134 funcs = []
135 for proto in self.protos:
136 if proto.name != "GetProcAddr" and proto.name != "InitAndEnumerateGpus":
Tobin Ehlisa363cfa2014-11-25 16:59:27 -0700137 if "Generic" == layer:
Tobin Ehlis12076fc2014-10-22 09:06:33 -0600138 decl = proto.c_func(prefix="xgl", attr="XGLAPI")
139 param0_name = proto.params[0].name
140 ret_val = ''
141 stmt = ''
142 if proto.ret != "XGL_VOID":
143 ret_val = "XGL_RESULT result = "
144 stmt = " return result;\n"
Jon Ashburnf7a08742014-11-25 11:08:42 -0700145 if proto.name == "EnumerateLayers":
146 c_call = proto.c_call().replace("(" + proto.params[0].name, "((XGL_PHYSICAL_GPU)gpuw->nextObject", 1)
147 funcs.append('%s%s\n'
148 '{\n'
149 ' if (gpu != NULL) {\n'
150 ' XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) %s;\n'
151 ' printf("At start of layered %s\\n");\n'
152 ' pCurObj = gpuw;\n'
153 ' pthread_once(&tabOnce, initLayerTable);\n'
154 ' %snextTable.%s;\n'
155 ' printf("Completed layered %s\\n");\n'
156 ' fflush(stdout);\n'
157 ' %s'
158 ' } else {\n'
159 ' if (pOutLayerCount == NULL || pOutLayers == NULL || pOutLayers[0] == NULL)\n'
160 ' return XGL_ERROR_INVALID_POINTER;\n'
161 ' // This layer compatible with all GPUs\n'
162 ' *pOutLayerCount = 1;\n'
163 ' strncpy(pOutLayers[0], "%s", maxStringSize);\n'
164 ' return XGL_SUCCESS;\n'
165 ' }\n'
Tobin Ehlisd49efcb2014-11-25 17:43:26 -0700166 '}' % (qual, decl, proto.params[0].name, proto.name, ret_val, c_call, proto.name, stmt, layer_name))
Jon Ashburnf7a08742014-11-25 11:08:42 -0700167 elif proto.params[0].ty != "XGL_PHYSICAL_GPU":
Tobin Ehlis12076fc2014-10-22 09:06:33 -0600168 funcs.append('%s%s\n'
169 '{\n'
170 ' %snextTable.%s;\n'
171 '%s'
172 '}' % (qual, decl, ret_val, proto.c_call(), stmt))
173 else:
174 c_call = proto.c_call().replace("(" + proto.params[0].name, "((XGL_PHYSICAL_GPU)gpuw->nextObject", 1)
175 funcs.append('%s%s\n'
176 '{\n'
177 ' XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) %s;\n'
178 ' printf("At start of layered %s\\n");\n'
179 ' pCurObj = gpuw;\n'
180 ' pthread_once(&tabOnce, initLayerTable);\n'
181 ' %snextTable.%s;\n'
182 ' printf("Completed layered %s\\n");\n'
Courtney Goeltzenleuchterb412d212014-11-18 10:40:29 -0700183 ' fflush(stdout);\n'
Tobin Ehlis12076fc2014-10-22 09:06:33 -0600184 '%s'
185 '}' % (qual, decl, proto.params[0].name, proto.name, ret_val, c_call, proto.name, stmt))
Tobin Ehlisa363cfa2014-11-25 16:59:27 -0700186 elif "APIDump" in layer:
Tobin Ehlis12076fc2014-10-22 09:06:33 -0600187 decl = proto.c_func(prefix="xgl", attr="XGLAPI")
188 param0_name = proto.params[0].name
189 ret_val = ''
190 stmt = ''
Tobin Ehlis083e9062014-10-23 08:19:47 -0600191 cis_param_index = [] # Store list of indices when func has struct params
Tobin Ehlise7271572014-11-19 15:52:46 -0700192 create_params = 0 # Num of params at end of function that are created and returned as output values
193 if 'WsiX11CreatePresentableImage' in proto.name:
194 create_params = -2
195 elif 'Create' in proto.name or 'Alloc' in proto.name or 'MapMemory' in proto.name:
196 create_params = -1
Tobin Ehlis12076fc2014-10-22 09:06:33 -0600197 if proto.ret != "XGL_VOID":
198 ret_val = "XGL_RESULT result = "
199 stmt = " return result;\n"
Tobin Ehlisea3d21b2014-11-12 13:11:15 -0700200 f_open = ''
201 f_close = ''
Tobin Ehlisa363cfa2014-11-25 16:59:27 -0700202 if "File" in layer:
Tobin Ehlisdbcd2572014-11-21 09:35:53 -0700203 file_mode = "a"
204 if 'CreateDevice' in proto.name:
205 file_mode = "w"
Tobin Ehlisd009bae2014-11-24 15:46:55 -0700206 f_open = 'unsigned int tid = pthread_self();\n pthread_mutex_lock( &file_lock );\n pOutFile = fopen(outFileName, "%s");\n ' % (file_mode)
207 log_func = 'fprintf(pOutFile, "t{%%u} xgl%s(' % proto.name
Tobin Ehlis2b9313e2014-11-20 12:18:45 -0700208 f_close = '\n fclose(pOutFile);\n pthread_mutex_unlock( &file_lock );'
Tobin Ehlisea3d21b2014-11-12 13:11:15 -0700209 else:
Tobin Ehlisd009bae2014-11-24 15:46:55 -0700210 f_open = 'unsigned int tid = pthread_self();\n pthread_mutex_lock( &print_lock );\n '
211 log_func = 'printf("t{%%u} xgl%s(' % proto.name
Tobin Ehlis2b9313e2014-11-20 12:18:45 -0700212 f_close = '\n pthread_mutex_unlock( &print_lock );'
Tobin Ehlisd009bae2014-11-24 15:46:55 -0700213 print_vals = ', getTIDIndex()'
Tobin Ehlis12076fc2014-10-22 09:06:33 -0600214 pindex = 0
215 for p in proto.params:
Tobin Ehlise7271572014-11-19 15:52:46 -0700216 # TODO : Need to handle xglWsiX11CreatePresentableImage for which the last 2 params are returned vals
217 cp = False
218 if 0 != create_params:
219 # If this is any of the N last params of the func, treat as output
220 for y in range(-1, create_params-1, -1):
221 if p.name == proto.params[y].name:
222 cp = True
223 (pft, pfi) = self._get_printf_params(p.ty, p.name, cp)
Tobin Ehlisd49efcb2014-11-25 17:43:26 -0700224 if no_addr and "%p" == pft:
225 (pft, pfi) = ("%s", '"addr"')
Tobin Ehlis12076fc2014-10-22 09:06:33 -0600226 log_func += '%s = %s, ' % (p.name, pft)
227 print_vals += ', %s' % (pfi)
Tobin Ehlis083e9062014-10-23 08:19:47 -0600228 # TODO : Just want this to be simple check for params of STRUCT type
229 if "pCreateInfo" in p.name or ('const' in p.ty and '*' in p.ty and False not in [tmp_ty not in p.ty for tmp_ty in ['XGL_CHAR', 'XGL_VOID', 'XGL_CMD_BUFFER', 'XGL_QUEUE_SEMAPHORE', 'XGL_FENCE', 'XGL_SAMPLER', 'XGL_UINT32']]):
Tobin Ehlis3a1cc8d2014-11-11 17:28:22 -0700230 if 'Wsi' not in proto.name:
231 cis_param_index.append(pindex)
Tobin Ehlis12076fc2014-10-22 09:06:33 -0600232 pindex += 1
233 log_func = log_func.strip(', ')
234 if proto.ret != "XGL_VOID":
235 log_func += ') = %s\\n"'
Courtney Goeltzenleuchterb412d212014-11-18 10:40:29 -0700236 print_vals += ', string_XGL_RESULT(result)'
Tobin Ehlis12076fc2014-10-22 09:06:33 -0600237 else:
238 log_func += ')\\n"'
239 log_func = '%s%s);' % (log_func, print_vals)
Tobin Ehlis083e9062014-10-23 08:19:47 -0600240 if len(cis_param_index) > 0:
241 log_func += '\n char *pTmpStr;'
242 for sp_index in cis_param_index:
243 cis_print_func = 'xgl_print_%s' % (proto.params[sp_index].ty.strip('const ').strip('*').lower())
244 log_func += '\n if (%s) {' % (proto.params[sp_index].name)
245 log_func += '\n pTmpStr = %s(%s, " ");' % (cis_print_func, proto.params[sp_index].name)
Tobin Ehlisd49efcb2014-11-25 17:43:26 -0700246 if "File" in layer:
247 if no_addr:
248 log_func += '\n fprintf(pOutFile, " %s (addr)\\n%%s\\n", pTmpStr);' % (proto.params[sp_index].name)
249 else:
250 log_func += '\n fprintf(pOutFile, " %s (%%p)\\n%%s\\n", (void*)%s, pTmpStr);' % (proto.params[sp_index].name, proto.params[sp_index].name)
Tobin Ehlisea3d21b2014-11-12 13:11:15 -0700251 else:
Tobin Ehlisd49efcb2014-11-25 17:43:26 -0700252 if no_addr:
253 log_func += '\n printf(" %s (addr)\\n%%s\\n", pTmpStr);' % (proto.params[sp_index].name)
254 else:
255 log_func += '\n printf(" %s (%%p)\\n%%s\\n", (void*)%s, pTmpStr);' % (proto.params[sp_index].name, proto.params[sp_index].name)
Tobin Ehlisd009bae2014-11-24 15:46:55 -0700256 log_func += '\n fflush(stdout);'
Tobin Ehlis083e9062014-10-23 08:19:47 -0600257 log_func += '\n free(pTmpStr);\n }'
Jon Ashburnf7a08742014-11-25 11:08:42 -0700258 if proto.name == "EnumerateLayers":
259 c_call = proto.c_call().replace("(" + proto.params[0].name, "((XGL_PHYSICAL_GPU)gpuw->nextObject", 1)
260 funcs.append('%s%s\n'
261 '{\n'
262 ' if (gpu != NULL) {\n'
263 ' XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) %s;\n'
264 ' pCurObj = gpuw;\n'
265 ' pthread_once(&tabOnce, initLayerTable);\n'
266 ' %snextTable.%s;\n'
267 ' %s %s %s\n'
268 ' %s'
269 ' } else {\n'
270 ' if (pOutLayerCount == NULL || pOutLayers == NULL || pOutLayers[0] == NULL)\n'
271 ' return XGL_ERROR_INVALID_POINTER;\n'
272 ' // This layer compatible with all GPUs\n'
273 ' *pOutLayerCount = 1;\n'
274 ' strncpy(pOutLayers[0], "%s", maxStringSize);\n'
275 ' return XGL_SUCCESS;\n'
276 ' }\n'
Tobin Ehlisd49efcb2014-11-25 17:43:26 -0700277 '}' % (qual, decl, proto.params[0].name, ret_val, c_call,f_open, log_func, f_close, stmt, layer_name))
Jon Ashburnf7a08742014-11-25 11:08:42 -0700278 elif proto.params[0].ty != "XGL_PHYSICAL_GPU":
Tobin Ehlis12076fc2014-10-22 09:06:33 -0600279 funcs.append('%s%s\n'
280 '{\n'
281 ' %snextTable.%s;\n'
Tobin Ehlisea3d21b2014-11-12 13:11:15 -0700282 ' %s%s%s\n'
Tobin Ehlis12076fc2014-10-22 09:06:33 -0600283 '%s'
Tobin Ehlisea3d21b2014-11-12 13:11:15 -0700284 '}' % (qual, decl, ret_val, proto.c_call(), f_open, log_func, f_close, stmt))
Tobin Ehlis12076fc2014-10-22 09:06:33 -0600285 else:
286 c_call = proto.c_call().replace("(" + proto.params[0].name, "((XGL_PHYSICAL_GPU)gpuw->nextObject", 1)
287 funcs.append('%s%s\n'
288 '{\n'
289 ' XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) %s;\n'
290 ' pCurObj = gpuw;\n'
291 ' pthread_once(&tabOnce, initLayerTable);\n'
292 ' %snextTable.%s;\n'
Tobin Ehlisea3d21b2014-11-12 13:11:15 -0700293 ' %s%s%s\n'
Tobin Ehlis12076fc2014-10-22 09:06:33 -0600294 '%s'
Tobin Ehlisea3d21b2014-11-12 13:11:15 -0700295 '}' % (qual, decl, proto.params[0].name, ret_val, c_call, f_open, log_func, f_close, stmt))
Tobin Ehlisa363cfa2014-11-25 16:59:27 -0700296 elif "ObjectTracker" == layer:
Tobin Ehlisca915872014-11-18 11:28:33 -0700297 obj_type_mapping = {"XGL_PHYSICAL_GPU" : "XGL_OBJECT_TYPE_PHYSICAL_GPU", "XGL_DEVICE" : "XGL_OBJECT_TYPE_DEVICE",
298 "XGL_QUEUE" : "XGL_OBJECT_TYPE_QUEUE", "XGL_QUEUE_SEMAPHORE" : "XGL_OBJECT_TYPE_QUEUE_SEMAPHORE",
299 "XGL_GPU_MEMORY" : "XGL_OBJECT_TYPE_GPU_MEMORY", "XGL_FENCE" : "XGL_OBJECT_TYPE_FENCE",
300 "XGL_QUERY_POOL" : "XGL_OBJECT_TYPE_QUERY_POOL", "XGL_EVENT" : "XGL_OBJECT_TYPE_EVENT",
301 "XGL_IMAGE" : "XGL_OBJECT_TYPE_IMAGE", "XGL_DESCRIPTOR_SET" : "XGL_OBJECT_TYPE_DESCRIPTOR_SET",
302 "XGL_CMD_BUFFER" : "XGL_OBJECT_TYPE_CMD_BUFFER", "XGL_SAMPLER" : "XGL_OBJECT_TYPE_SAMPLER",
303 "XGL_PIPELINE" : "XGL_OBJECT_TYPE_PIPELINE", "XGL_PIPELINE_DELTA" : "XGL_OBJECT_TYPE_PIPELINE_DELTA",
304 "XGL_SHADER" : "XGL_OBJECT_TYPE_SHADER", "XGL_IMAGE_VIEW" : "XGL_OBJECT_TYPE_IMAGE_VIEW",
305 "XGL_COLOR_ATTACHMENT_VIEW" : "XGL_OBJECT_TYPE_COLOR_ATTACHMENT_VIEW", "XGL_DEPTH_STENCIL_VIEW" : "XGL_OBJECT_TYPE_DEPTH_STENCIL_VIEW",
306 "XGL_VIEWPORT_STATE_OBJECT" : "XGL_OBJECT_TYPE_VIEWPORT_STATE", "XGL_RASTER_STATE_OBJECT" : "XGL_OBJECT_TYPE_RASTER_STATE",
307 "XGL_MSAA_STATE_OBJECT" : "XGL_OBJECT_TYPE_MSAA_STATE", "XGL_COLOR_BLEND_STATE_OBJECT" : "XGL_OBJECT_TYPE_COLOR_BLEND_STATE",
308 "XGL_DEPTH_STENCIL_STATE_OBJECT" : "XGL_OBJECT_TYPE_DEPTH_STENCIL_STATE", "XGL_BASE_OBJECT" : "ll_get_obj_type(object)",
309 "XGL_OBJECT" : "ll_get_obj_type(object)"}
310
Tobin Ehlis12076fc2014-10-22 09:06:33 -0600311 decl = proto.c_func(prefix="xgl", attr="XGLAPI")
312 param0_name = proto.params[0].name
Tobin Ehlisca915872014-11-18 11:28:33 -0700313 p0_type = proto.params[0].ty
Tobin Ehlis12076fc2014-10-22 09:06:33 -0600314 create_line = ''
315 destroy_line = ''
Tobin Ehlisca915872014-11-18 11:28:33 -0700316 if 'DbgRegisterMsgCallback' in proto.name:
317 using_line = ' // This layer intercepts callbacks\n'
318 using_line += ' XGL_LAYER_DBG_FUNCTION_NODE *pNewDbgFuncNode = (XGL_LAYER_DBG_FUNCTION_NODE*)malloc(sizeof(XGL_LAYER_DBG_FUNCTION_NODE));\n'
319 using_line += ' if (!pNewDbgFuncNode)\n'
320 using_line += ' return XGL_ERROR_OUT_OF_MEMORY;\n'
321 using_line += ' pNewDbgFuncNode->pfnMsgCallback = pfnMsgCallback;\n'
322 using_line += ' pNewDbgFuncNode->pUserData = pUserData;\n'
323 using_line += ' pNewDbgFuncNode->pNext = pDbgFunctionHead;\n'
324 using_line += ' pDbgFunctionHead = pNewDbgFuncNode;\n'
325 elif 'DbgUnregisterMsgCallback' in proto.name:
326 using_line = ' XGL_LAYER_DBG_FUNCTION_NODE *pTrav = pDbgFunctionHead;\n'
327 using_line += ' XGL_LAYER_DBG_FUNCTION_NODE *pPrev = pTrav;\n'
328 using_line += ' while (pTrav) {\n'
329 using_line += ' if (pTrav->pfnMsgCallback == pfnMsgCallback) {\n'
330 using_line += ' pPrev->pNext = pTrav->pNext;\n'
331 using_line += ' if (pDbgFunctionHead == pTrav)\n'
332 using_line += ' pDbgFunctionHead = pTrav->pNext;\n'
333 using_line += ' free(pTrav);\n'
334 using_line += ' break;\n'
335 using_line += ' }\n'
336 using_line += ' pPrev = pTrav;\n'
337 using_line += ' pTrav = pTrav->pNext;\n'
338 using_line += ' }\n'
339 elif 'GlobalOption' in proto.name:
Tobin Ehlis12076fc2014-10-22 09:06:33 -0600340 using_line = ''
Tobin Ehlisca915872014-11-18 11:28:33 -0700341 else:
342 using_line = ' ll_increment_use_count((XGL_VOID*)%s, %s);\n' % (param0_name, obj_type_mapping[p0_type])
343 if 'Create' in proto.name or 'Alloc' in proto.name:
344 create_line = ' ll_insert_obj((XGL_VOID*)*%s, %s);\n' % (proto.params[-1].name, obj_type_mapping[proto.params[-1].ty.strip('*')])
345 if 'DestroyObject' in proto.name:
346 destroy_line = ' ll_destroy_obj((XGL_VOID*)%s);\n' % (param0_name)
347 using_line = ''
348 else:
349 if 'Destroy' in proto.name or 'Free' in proto.name:
350 destroy_line = ' ll_remove_obj_type((XGL_VOID*)%s, %s);\n' % (param0_name, obj_type_mapping[p0_type])
351 using_line = ''
352 if 'DestroyDevice' in proto.name:
353 destroy_line += ' // Report any remaining objects in LL\n objNode *pTrav = pGlobalHead;\n while (pTrav) {\n'
354 destroy_line += ' char str[1024];\n'
355 destroy_line += ' sprintf(str, "OBJ ERROR : %s object %p has not been destroyed (was used %lu times).", string_XGL_OBJECT_TYPE(pTrav->obj.objType), pTrav->obj.pObj, pTrav->obj.numUses);\n'
356 destroy_line += ' layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, device, 0, OBJTRACK_OBJECT_LEAK, "OBJTRACK", str);\n'
357 destroy_line += ' pTrav = pTrav->pNextGlobal;\n }\n'
Tobin Ehlis12076fc2014-10-22 09:06:33 -0600358 ret_val = ''
359 stmt = ''
360 if proto.ret != "XGL_VOID":
361 ret_val = "XGL_RESULT result = "
362 stmt = " return result;\n"
Jon Ashburnf7a08742014-11-25 11:08:42 -0700363 if proto.name == "EnumerateLayers":
364 c_call = proto.c_call().replace("(" + proto.params[0].name, "((XGL_PHYSICAL_GPU)gpuw->nextObject", 1)
365 funcs.append('%s%s\n'
366 '{\n'
367 ' if (gpu != NULL) {\n'
368 ' XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) %s;\n'
369 ' %s'
370 ' pCurObj = gpuw;\n'
371 ' pthread_once(&tabOnce, initLayerTable);\n'
372 ' %snextTable.%s;\n'
373 ' %s%s'
374 ' %s'
375 ' } else {\n'
376 ' if (pOutLayerCount == NULL || pOutLayers == NULL || pOutLayers[0] == NULL)\n'
377 ' return XGL_ERROR_INVALID_POINTER;\n'
378 ' // This layer compatible with all GPUs\n'
379 ' *pOutLayerCount = 1;\n'
380 ' strncpy(pOutLayers[0], "%s", maxStringSize);\n'
381 ' return XGL_SUCCESS;\n'
382 ' }\n'
Tobin Ehlisd49efcb2014-11-25 17:43:26 -0700383 '}' % (qual, decl, proto.params[0].name, using_line, ret_val, c_call, create_line, destroy_line, stmt, layer_name))
Jon Ashburnf7a08742014-11-25 11:08:42 -0700384 elif proto.params[0].ty != "XGL_PHYSICAL_GPU":
Tobin Ehlis12076fc2014-10-22 09:06:33 -0600385 funcs.append('%s%s\n'
386 '{\n'
387 '%s'
388 ' %snextTable.%s;\n'
389 '%s%s'
390 '%s'
391 '}' % (qual, decl, using_line, ret_val, proto.c_call(), create_line, destroy_line, stmt))
392 else:
393 c_call = proto.c_call().replace("(" + proto.params[0].name, "((XGL_PHYSICAL_GPU)gpuw->nextObject", 1)
394 funcs.append('%s%s\n'
395 '{\n'
396 ' XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) %s;\n'
397 '%s'
398 ' pCurObj = gpuw;\n'
399 ' pthread_once(&tabOnce, initLayerTable);\n'
400 ' %snextTable.%s;\n'
401 '%s%s'
402 '%s'
403 '}' % (qual, decl, proto.params[0].name, using_line, ret_val, c_call, create_line, destroy_line, stmt))
404
405 # TODO : Put this code somewhere so it gets called at the end if objects not deleted :
406 # // Report any remaining objects in LL
407 # objNode *pTrav = pObjLLHead;
408 # while (pTrav) {
409 # printf("WARN : %s object %p has not been destroyed.\n", pTrav->objType, pTrav->pObj);
410 # }
411
412 return "\n\n".join(funcs)
413
Tobin Ehlisca915872014-11-18 11:28:33 -0700414 def _generate_extensions(self):
415 exts = []
416 exts.append('XGL_UINT64 objTrackGetObjectCount(XGL_OBJECT_TYPE type)')
417 exts.append('{')
418 exts.append(' return (type == XGL_OBJECT_TYPE_ANY) ? numTotalObjs : numObjs[type];')
419 exts.append('}')
420 exts.append('')
421 exts.append('XGL_RESULT objTrackGetObjects(XGL_OBJECT_TYPE type, XGL_UINT64 objCount, OBJTRACK_NODE* pObjNodeArray)')
422 exts.append('{')
423 exts.append(" // This bool flags if we're pulling all objs or just a single class of objs")
424 exts.append(' XGL_BOOL bAllObjs = (type == XGL_OBJECT_TYPE_ANY);')
425 exts.append(' // Check the count first thing')
426 exts.append(' XGL_UINT64 maxObjCount = (bAllObjs) ? numTotalObjs : numObjs[type];')
427 exts.append(' if (objCount > maxObjCount) {')
428 exts.append(' char str[1024];')
429 exts.append(' sprintf(str, "OBJ ERROR : Received objTrackGetObjects() request for %lu objs, but there are only %lu objs of type %s", objCount, maxObjCount, string_XGL_OBJECT_TYPE(type));')
430 exts.append(' layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, 0, 0, OBJTRACK_OBJCOUNT_MAX_EXCEEDED, "OBJTRACK", str);')
431 exts.append(' return XGL_ERROR_INVALID_VALUE;')
432 exts.append(' }')
433 exts.append(' objNode* pTrav = (bAllObjs) ? pGlobalHead : pObjectHead[type];')
434 exts.append(' for (XGL_UINT64 i = 0; i < objCount; i++) {')
435 exts.append(' if (!pTrav) {')
436 exts.append(' char str[1024];')
437 exts.append(' sprintf(str, "OBJ INTERNAL ERROR : Ran out of %s objs! Should have %lu, but only copied %lu and not the requested %lu.", string_XGL_OBJECT_TYPE(type), maxObjCount, i, objCount);')
438 exts.append(' layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, 0, 0, OBJTRACK_INTERNAL_ERROR, "OBJTRACK", str);')
439 exts.append(' return XGL_ERROR_UNKNOWN;')
440 exts.append(' }')
441 exts.append(' memcpy(&pObjNodeArray[i], pTrav, sizeof(OBJTRACK_NODE));')
442 exts.append(' pTrav = (bAllObjs) ? pTrav->pNextGlobal : pTrav->pNextObj;')
443 exts.append(' }')
444 exts.append(' return XGL_SUCCESS;')
445 exts.append('}')
446
447 return "\n".join(exts)
448
449 def _generate_layer_gpa_function(self, prefix="xgl", extensions=[]):
Tobin Ehlis12076fc2014-10-22 09:06:33 -0600450 func_body = []
451 func_body.append("XGL_LAYER_EXPORT XGL_VOID* XGLAPI xglGetProcAddr(XGL_PHYSICAL_GPU gpu, const XGL_CHAR* funcName)\n"
452 "{\n"
453 " XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;\n"
454 " if (gpu == NULL)\n"
455 " return NULL;\n"
456 " pCurObj = gpuw;\n"
457 " pthread_once(&tabOnce, initLayerTable);\n\n"
458 ' if (!strncmp("xglGetProcAddr", (const char *) funcName, sizeof("xglGetProcAddr")))\n'
459 ' return xglGetProcAddr;')
Tobin Ehlisca915872014-11-18 11:28:33 -0700460 if 0 != len(extensions):
461 for ext_name in extensions:
462 func_body.append(' else if (!strncmp("%s", (const char *) funcName, sizeof("%s")))\n'
463 ' return %s;' % (ext_name, ext_name, ext_name))
Tobin Ehlis12076fc2014-10-22 09:06:33 -0600464 for name in xgl.icd_dispatch_table:
465 if name == "GetProcAddr":
466 continue
467 if name == "InitAndEnumerateGpus":
468 func_body.append(' else if (!strncmp("%s%s", (const char *) funcName, sizeof("%s%s")))\n'
469 ' return nextTable.%s;' % (prefix, name, prefix, name, name))
470 else:
471 func_body.append(' else if (!strncmp("%s%s", (const char *) funcName, sizeof("%s%s")))\n'
472 ' return %s%s;' % (prefix, name, prefix, name, prefix, name))
473
474 func_body.append(" else {\n"
475 " XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;\n"
476 " if (gpuw->pGPA == NULL)\n"
477 " return NULL;\n"
478 " return gpuw->pGPA(gpuw->nextObject, funcName);\n"
479 " }\n"
480 "}\n")
481 return "\n".join(func_body)
482
483 def _generate_layer_dispatch_table(self, prefix='xgl'):
484 func_body = []
485 func_body.append('static void initLayerTable()\n'
486 '{\n'
487 ' GetProcAddrType fpNextGPA;\n'
488 ' fpNextGPA = pCurObj->pGPA;\n'
489 ' assert(fpNextGPA);\n');
490
491 for name in xgl.icd_dispatch_table:
492 func_body.append(' %sType fp%s = fpNextGPA((XGL_PHYSICAL_GPU) pCurObj->nextObject, (XGL_CHAR *) "%s%s");\n'
493 ' nextTable.%s = fp%s;' % (name, name, prefix, name, name, name))
494
495 func_body.append("}\n")
496 return "\n".join(func_body)
497
Tobin Ehlis811b5532014-12-01 12:53:53 -0700498 def _generate_trace_func_ptrs(self):
499 func_ptrs = []
500 func_ptrs.append('// Pointers to real functions and declarations of hooked functions')
501 func_ptrs.append('#ifdef WIN32')
502 func_ptrs.append('extern INIT_ONCE gInitOnce;')
503 for proto in self.protos:
504 if 'Dbg' not in proto.name and 'Wsi' not in proto.name:
505 func_ptrs.append('#define __HOOKED_xgl%s hooked_xgl%s' % (proto.name, proto.name))
506
507 func_ptrs.append('\n#elif defined(PLATFORM_LINUX)')
508 func_ptrs.append('extern pthread_once_t gInitOnce;')
509 for proto in self.protos:
510 if 'Dbg' not in proto.name and 'Wsi' not in proto.name:
511 func_ptrs.append('#define __HOOKED_xgl%s xgl%s' % (proto.name, proto.name))
512
513 func_ptrs.append('#endif\n')
514 return "\n".join(func_ptrs)
515
516 def _generate_trace_func_protos(self):
517 func_protos = []
518 func_protos.append('// Hooked function prototypes\n')
519 for proto in self.protos:
520 if 'Dbg' not in proto.name and 'Wsi' not in proto.name:
521 func_protos.append('%s;' % proto.c_func(prefix="__HOOKED_xgl", attr="XGLAPI"))
522
523 return "\n".join(func_protos)
524
525 def _generate_func_ptr_assignments(self):
526 func_ptr_assign = []
527 for proto in self.protos:
528 if 'Dbg' not in proto.name and 'Wsi' not in proto.name:
529 func_ptr_assign.append('static %s( XGLAPI * real_xgl%s)(' % (proto.ret, proto.name))
530 for p in proto.params:
531 if 'color' == p.name:
532 func_ptr_assign.append(' %s %s[4],' % (p.ty.replace('[4]', ''), p.name))
533 else:
534 func_ptr_assign.append(' %s %s,' % (p.ty, p.name))
535 func_ptr_assign[-1] = func_ptr_assign[-1].replace(',', ') = xgl%s;\n' % (proto.name))
536 func_ptr_assign.append('static BOOL isHooked = FALSE;\n')
537 return "\n".join(func_ptr_assign)
538
539 def _generate_attach_hooks(self):
540 hooks_txt = []
541 hooks_txt.append('void AttachHooks()\n{\n BOOL hookSuccess = TRUE;\n#if defined(WIN32)')
542 hooks_txt.append(' Mhook_BeginMultiOperation(FALSE);')
543 hooks_txt.append(' if (real_xglInitAndEnumerateGpus != NULL)')
544 hooks_txt.append(' {\n isHooked = TRUE;')
545 hook_operator = '='
546 for proto in self.protos:
547 if 'Dbg' not in proto.name and 'Wsi' not in proto.name:
548 hooks_txt.append(' hookSuccess %s Mhook_SetHook((PVOID*)&real_xgl%s, hooked_xgl%s);' % (hook_operator, proto.name, proto.name))
549 hook_operator = '&='
550 hooks_txt.append(' }\n')
551 hooks_txt.append(' if (!hookSuccess)\n {')
552 hooks_txt.append(' glv_LogError("Failed to hook XGL.");\n }\n')
553 hooks_txt.append(' Mhook_EndMultiOperation();\n')
554 hooks_txt.append('#elif defined(__linux__)')
555 hooks_txt.append(' if (real_xglInitAndEnumerateGpus == xglInitAndEnumerateGpus)')
556 hooks_txt.append(' hookSuccess = glv_platform_get_next_lib_sym((PVOID*)&real_xglInitAndEnumerateGpus,"xglInitAndEnumerateGpus");')
557 hooks_txt.append(' isHooked = TRUE;')
558 for proto in self.protos:
559 if 'Dbg' not in proto.name and 'Wsi' not in proto.name and 'InitAndEnumerateGpus' not in proto.name:
560 hooks_txt.append(' hookSuccess %s glv_platform_get_next_lib_sym((PVOID*)&real_xgl%s, "xgl%s");' % (hook_operator, proto.name, proto.name))
561 hooks_txt.append(' if (!hookSuccess)\n {')
562 hooks_txt.append(' glv_LogError("Failed to hook XGL.");\n }\n')
563 hooks_txt.append('#endif\n}\n')
564 return "\n".join(hooks_txt)
565
566 def _generate_detach_hooks(self):
567 hooks_txt = []
568 hooks_txt.append('void DetachHooks()\n{\n#ifdef __linux__\n return;\n#elif defined(WIN32)')
569 hooks_txt.append(' BOOL unhookSuccess = TRUE;\n if (real_xglGetGpuInfo != NULL)\n {')
570 hook_operator = '='
571 for proto in self.protos:
572 if 'Dbg' not in proto.name and 'Wsi' not in proto.name:
573 hooks_txt.append(' unhookSuccess %s Mhook_Unhook((PVOID*)&real_xgl%s);' % (hook_operator, proto.name))
574 hook_operator = '&='
575 hooks_txt.append(' }\n isHooked = FALSE;\n')
576 hooks_txt.append(' if (!unhookSuccess)\n {')
577 hooks_txt.append(' glv_LogError("Failed to unhook XGL.");\n }')
578 hooks_txt.append('#endif\n}')
579 hooks_txt.append('#ifdef WIN32\nINIT_ONCE gInitOnce = INIT_ONCE_STATIC_INIT;\n#elif defined(PLATFORM_LINUX)\npthread_once_t gInitOnce = PTHREAD_ONCE_INIT;\n#endif\n')
580 return "\n".join(hooks_txt)
581
582 def _generate_init_tracer(self):
583 init_tracer = []
584 init_tracer.append('void InitTracer()\n{')
585 init_tracer.append(' gMessageStream = glv_MessageStream_create(FALSE, "127.0.0.1", GLV_BASE_PORT + GLV_TID_XGL);')
586 init_tracer.append(' glv_trace_set_trace_file(glv_FileLike_create_msg(gMessageStream));')
587 init_tracer.append('// glv_tracelog_set_log_file(glv_FileLike_create_file(fopen("glv_log_traceside.txt","w")));')
588 init_tracer.append(' glv_tracelog_set_tracer_id(GLV_TID_XGL);\n}\n')
589 return "\n".join(init_tracer)
590
591 # InitAndEnumerateGpus is unique enough that it gets custom generation code
592 def _gen_iande_gpus(self):
593 iae_body = []
594 iae_body.append('GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglInitAndEnumerateGpus(')
595 iae_body.append(' const XGL_APPLICATION_INFO* pAppInfo,')
596 iae_body.append(' const XGL_ALLOC_CALLBACKS* pAllocCb,')
597 iae_body.append(' XGL_UINT maxGpus,')
598 iae_body.append(' XGL_UINT* pGpuCount,')
599 iae_body.append(' XGL_PHYSICAL_GPU* pGpus)')
600 iae_body.append('{')
601 iae_body.append(' glv_trace_packet_header* pHeader;')
602 iae_body.append(' XGL_RESULT result;')
603 iae_body.append(' uint64_t startTime;')
604 iae_body.append(' struct_xglInitAndEnumerateGpus* pPacket;')
605 iae_body.append('')
606 iae_body.append(' glv_platform_thread_once(&gInitOnce, InitTracer);')
607 iae_body.append(' SEND_ENTRYPOINT_ID(xglInitAndEnumerateGpus);')
608 iae_body.append(' if (real_xglInitAndEnumerateGpus == xglInitAndEnumerateGpus)')
609 iae_body.append(' {')
610 iae_body.append(' glv_platform_get_next_lib_sym((void **) &real_xglInitAndEnumerateGpus,"xglInitAndEnumerateGpus");')
611 iae_body.append(' }')
612 iae_body.append(' startTime = glv_get_time();')
613 iae_body.append(' result = real_xglInitAndEnumerateGpus(pAppInfo, pAllocCb, maxGpus, pGpuCount, pGpus);')
614 iae_body.append('')
615 iae_body.append(' // since we do not know how many gpus will be found must create trace packet after calling xglInit')
616 iae_body.append(' CREATE_TRACE_PACKET(xglInitAndEnumerateGpus, calc_size_XGL_APPLICATION_INFO(pAppInfo) + ((pAllocCb == NULL) ? 0 :sizeof(XGL_ALLOC_CALLBACKS))')
617 iae_body.append(' + sizeof(XGL_UINT) + ((pGpus && pGpuCount) ? *pGpuCount * sizeof(XGL_PHYSICAL_GPU) : 0));')
618 iae_body.append(' pHeader->entrypoint_begin_time = startTime;')
619 iae_body.append(' if (isHooked == FALSE) {')
620 iae_body.append(' AttachHooks();')
621 iae_body.append(' AttachHooks_xgldbg();')
622 iae_body.append(' AttachHooks_xglwsix11ext();')
623 iae_body.append(' }')
624 iae_body.append(' pPacket = interpret_body_as_xglInitAndEnumerateGpus(pHeader);')
625 iae_body.append(' add_XGL_APPLICATION_INFO_to_packet(pHeader, (XGL_APPLICATION_INFO**)&(pPacket->pAppInfo), pAppInfo);')
626 iae_body.append(' if (pAllocCb) {')
627 iae_body.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pAllocCb), sizeof(XGL_ALLOC_CALLBACKS), pAllocCb);')
628 iae_body.append(' glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pAllocCb));')
629 iae_body.append(' }')
630 iae_body.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pGpuCount), sizeof(XGL_UINT), pGpuCount);')
631 iae_body.append(' glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pGpuCount));')
632 iae_body.append(' if (pGpuCount && pGpus)')
633 iae_body.append(' {')
634 iae_body.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pGpus), sizeof(XGL_PHYSICAL_GPU) * *pGpuCount, pGpus);')
635 iae_body.append(' glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pGpus));')
636 iae_body.append(' }')
637 iae_body.append(' pPacket->maxGpus = maxGpus;')
638 iae_body.append(' pPacket->result = result;')
639 iae_body.append(' FINISH_TRACE_PACKET();')
640 iae_body.append(' return result;')
641 iae_body.append('}\n')
642 return "\n".join(iae_body)
643
644 def _gen_unmap_memory(self):
645 um_body = []
646 um_body.append('GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglUnmapMemory(')
647 um_body.append(' XGL_GPU_MEMORY mem)')
648 um_body.append('{')
649 um_body.append(' glv_trace_packet_header* pHeader;')
650 um_body.append(' XGL_RESULT result;')
651 um_body.append(' struct_xglUnmapMemory* pPacket;')
652 um_body.append(' XGLAllocInfo *entry;')
653 um_body.append(' SEND_ENTRYPOINT_PARAMS("xglUnmapMemory(mem %p)\\n", mem);')
654 um_body.append(' // insert into packet the data that was written by CPU between the xglMapMemory call and here')
655 um_body.append(' // Note must do this prior to the real xglUnMap() or else may get a FAULT')
656 um_body.append(' entry = find_mem_info_entry(mem);')
657 um_body.append(' CREATE_TRACE_PACKET(xglUnmapMemory, (entry) ? entry->size : 0);')
658 um_body.append(' pPacket = interpret_body_as_xglUnmapMemory(pHeader);')
659 um_body.append(' if (entry)')
660 um_body.append(' {')
661 um_body.append(' assert(entry->handle == mem);')
662 um_body.append(' glv_add_buffer_to_trace_packet(pHeader, (void**) &(pPacket->pData), entry->size, entry->pData);')
663 um_body.append(' glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pData));')
664 um_body.append(' entry->pData = NULL;')
665 um_body.append(' }')
666 um_body.append(' result = real_xglUnmapMemory(mem);')
667 um_body.append(' pPacket->mem = mem;')
668 um_body.append(' pPacket->result = result;')
669 um_body.append(' FINISH_TRACE_PACKET();')
670 um_body.append(' return result;')
671 um_body.append('}\n')
672 return "\n".join(um_body)
673
674#EL == EnumerateLayers
675#I think this another case where you have to make the real call prior to CREATE_TRACE_PACKET(). SInce you
676#don't know how many layers will be returned or how big the strings will be. Alternatively, could be
677#on the safe side of CREATE_TRACE_PACKET with maxStringSize*maxLayerCount.
678#EL also needs a loop where add a trace buffer for each layer, depending on how you CREATE_TRACE_PACKET.
679
680 def _generate_trace_funcs(self):
681 func_body = []
682 for proto in self.protos:
683 if 'InitAndEnumerateGpus' == proto.name:
684 func_body.append(self._gen_iande_gpus())
685 elif 'UnmapMemory' == proto.name:
686 func_body.append(self._gen_unmap_memory())
687 elif 'Dbg' not in proto.name and 'Wsi' not in proto.name:
688 packet_update_txt = ''
689 return_txt = ''
690 packet_size = ''
691 in_data_size = False # flag when we need to capture local input size variable for in/out size
692 buff_ptr_indices = []
693 func_body.append('GLVTRACER_EXPORT %s XGLAPI __HOOKED_xgl%s(' % (proto.ret, proto.name))
694 for p in proto.params: # TODO : For all of the ptr types, check them for NULL and return 0 is NULL
695 if 'color' == p.name:
696 func_body.append(' %s %s[4],' % (p.ty.replace('[4]', ''), p.name))
697 else:
698 func_body.append(' %s %s,' % (p.ty, p.name))
699 if '*' in p.ty and 'pSysMem' != p.name:
700 if 'pData' == p.name:
701 if 'dataSize' == proto.params[proto.params.index(p)-1].name:
702 packet_size += 'dataSize + '
703 elif 'counterCount' == proto.params[proto.params.index(p)-1].name:
704 packet_size += 'sizeof(%s) + ' % p.ty.strip('*').strip('const ')
705 else:
706 packet_size += '((pDataSize != NULL && pData != NULL) ? *pDataSize : 0) + '
707 elif '**' in p.ty and 'VOID' in p.ty:
708 packet_size += 'sizeof(XGL_VOID*) + '
709 elif 'VOID' in p.ty:
710 packet_size += 'sizeof(%s) + ' % p.name
711 elif 'CHAR' in p.ty:
712 packet_size += '((%s != NULL) ? strlen((const char *)%s) + 1 : 0) + ' % (p.name, p.name)
713 elif 'DEVICE_CREATE_INFO' in p.ty:
714 packet_size += 'calc_size_XGL_DEVICE_CREATE_INFO(pCreateInfo) + '
715 elif 'pDataSize' in p.name:
716 packet_size += '((pDataSize != NULL) ? sizeof(XGL_SIZE) : 0) + '
717 in_data_size = True;
718 elif 'IMAGE_SUBRESOURCE' in p.ty and 'pSubresource' == p.name:
719 packet_size += '((pSubresource != NULL) ? sizeof(XGL_IMAGE_SUBRESOURCE) : 0) + '
720 else:
721 packet_size += 'sizeof(%s) + ' % p.ty.strip('*').strip('const ')
722 buff_ptr_indices.append(proto.params.index(p))
723 else:
724 if 'color' == p.name:
725 packet_update_txt += ' memcpy((void*)pPacket->color, color, 4 * sizeof(XGL_UINT32));\n'
726 else:
727 packet_update_txt += ' pPacket->%s = %s;\n' % (p.name, p.name)
728 if 'Count' in p.name and proto.params[-1].name != p.name and p.name not in ['queryCount', 'vertexCount', 'indexCount', 'startCounter'] and proto.name not in ['CmdLoadAtomicCounters', 'CmdSaveAtomicCounters']:
729 packet_size += '%s*' % p.name
730 if '' == packet_size:
731 packet_size = '0'
732 else:
733 packet_size = packet_size.strip(' + ')
734 func_body[-1] = func_body[-1].replace(',', ')')
735 func_body.append('{\n glv_trace_packet_header* pHeader;')
736 if 'VOID' not in proto.ret or '*' in proto.ret:
737 func_body.append(' %s result;' % proto.ret)
738 return_txt = 'result = '
739 if in_data_size:
740 func_body.append(' XGL_SIZE dataSizeIn = (pDataSize == NULL) ? 0 : *pDataSize;')
741 func_body.append(' struct_xgl%s* pPacket = NULL;' % proto.name)
742 func_body.append(' SEND_ENTRYPOINT_ID(xgl%s);' % proto.name)
743 if 'EnumerateLayers' == proto.name:
744 func_body.append(' %sreal_xgl%s;' % (return_txt, proto.c_call()))
745 func_body.append(' XGL_SIZE totStringSize = 0;')
746 func_body.append(' uint32_t i = 0;')
747 func_body.append(' for (i = 0; i < *pOutLayerCount; i++)')
748 func_body.append(' totStringSize += (pOutLayers[i] != NULL) ? strlen((const char*)pOutLayers[i]) + 1: 0;')
749 func_body.append(' CREATE_TRACE_PACKET(xgl%s, totStringSize);' % (proto.name))
750 elif proto.name in ['CreateShader', 'CreateGraphicsPipeline', 'CreateComputePipeline']:
751 func_body.append(' size_t customSize;')
752 if 'CreateShader' == proto.name:
753 func_body.append(' customSize = (pCreateInfo != NULL) ? pCreateInfo->codeSize : 0;')
754 func_body.append(' CREATE_TRACE_PACKET(xglCreateShader, sizeof(XGL_SHADER_CREATE_INFO) + sizeof(XGL_SHADER) + customSize);')
755 elif 'CreateGraphicsPipeline' == proto.name:
756 func_body.append(' customSize = calculate_pipeline_state_size(pCreateInfo->pNext);')
757 func_body.append(' CREATE_TRACE_PACKET(xglCreateGraphicsPipeline, sizeof(XGL_GRAPHICS_PIPELINE_CREATE_INFO) + sizeof(XGL_PIPELINE) + customSize);')
758 else: #'CreateComputePipeline'
759 func_body.append(' customSize = calculate_pipeline_state_size(pCreateInfo->pNext);')
760 func_body.append(' CREATE_TRACE_PACKET(xglCreateComputePipeline, sizeof(XGL_COMPUTE_PIPELINE_CREATE_INFO) + sizeof(XGL_PIPELINE) + customSize + calculate_pipeline_shader_size(&pCreateInfo->cs));')
761 func_body.append(' %sreal_xgl%s;' % (return_txt, proto.c_call()))
762 else:
763 func_body.append(' CREATE_TRACE_PACKET(xgl%s, %s);' % (proto.name, packet_size))
764 func_body.append(' %sreal_xgl%s;' % (return_txt, proto.c_call()))
765 func_body.append(' pPacket = interpret_body_as_xgl%s(pHeader);' % proto.name)
766 func_body.append(packet_update_txt.strip('\n'))
767 if 'MapMemory' == proto.name: # Custom code for MapMem case
768 func_body.append(' if (ppData != NULL)')
769 func_body.append(' {')
770 func_body.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->ppData), sizeof(XGL_VOID*), *ppData);')
771 func_body.append(' glv_finalize_buffer_address(pHeader, (void**)&(pPacket->ppData));')
772 func_body.append(' add_data_to_mem_info(mem, *ppData);')
773 func_body.append(' }')
774 func_body.append(' pPacket->result = result;')
775 func_body.append(' FINISH_TRACE_PACKET();')
776 else:
777 # TODO : Clean this up. Too much custom code and branching.
778 for idx in buff_ptr_indices:
779 if 'DEVICE_CREATE_INFO' in proto.params[idx].ty:
780 func_body.append(' add_XGL_DEVICE_CREATE_INFO_to_packet(pHeader, (XGL_DEVICE_CREATE_INFO**) &(pPacket->pCreateInfo), pCreateInfo);')
781 elif 'CHAR' in proto.params[idx].ty:
782 func_body.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->%s), ((%s != NULL) ? strlen((const char *)%s) + 1 : 0), %s);' % (proto.params[idx].name, proto.params[idx].name, proto.params[idx].name, proto.params[idx].name))
783 elif 'Count' in proto.params[idx-1].name and 'queryCount' != proto.params[idx-1].name:
784 func_body.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->%s), %s*sizeof(%s), %s);' % (proto.params[idx].name, proto.params[idx-1].name, proto.params[idx].ty.strip('*').strip('const '), proto.params[idx].name))
785 elif 'dataSize' == proto.params[idx].name:
786 func_body.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->%s), dataSize, %s);' % (proto.params[idx].name, proto.params[idx].name))
787 elif 'pDataSize' == proto.params[idx].name:
788 func_body.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->%s), sizeof(XGL_SIZE), &dataSizeIn);' % (proto.params[idx].name))
789 elif 'pData' == proto.params[idx].name:
790 if 'dataSize' == proto.params[idx-1].name:
791 func_body.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->%s), dataSize, %s);' % (proto.params[idx].name, proto.params[idx].name))
792 elif in_data_size:
793 func_body.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->%s), dataSizeIn, %s);' % (proto.params[idx].name, proto.params[idx].name))
794 else:
795 func_body.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->%s), (pDataSize != NULL && pData != NULL) ? *pDataSize : 0, %s);' % (proto.params[idx].name, proto.params[idx].name))
796 else:
797 func_body.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->%s), sizeof(%s), %s);' % (proto.params[idx].name, proto.params[idx].ty.strip('*').strip('const '), proto.params[idx].name))
798 # Some custom add_* and finalize_* function calls for Create* API calls
799 if proto.name in ['CreateShader', 'CreateGraphicsPipeline', 'CreateComputePipeline']:
800 if 'CreateShader' == proto.name:
801 func_body.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCreateInfo->pCode), customSize, pCreateInfo->pCode);')
802 func_body.append(' glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCreateInfo->pCode));')
803 elif 'CreateGraphicsPipeline' == proto.name:
804 func_body.append(' add_pipeline_state_to_trace_packet(pHeader, (XGL_VOID**)&pPacket->pCreateInfo->pNext, pCreateInfo->pNext);')
805 else:
806 func_body.append(' add_pipeline_state_to_trace_packet(pHeader, (XGL_VOID**)&(pPacket->pCreateInfo->pNext), pCreateInfo->pNext);')
807 func_body.append(' add_pipeline_shader_to_trace_packet(pHeader, (XGL_PIPELINE_SHADER*)&pPacket->pCreateInfo->cs, &pCreateInfo->cs);')
808 func_body.append(' finalize_pipeline_shader_address(pHeader, &pPacket->pCreateInfo->cs);')
809 if 'VOID' not in proto.ret or '*' in proto.ret:
810 func_body.append(' pPacket->result = result;')
811 for idx in buff_ptr_indices:
812 if 'DEVICE_CREATE_INFO' not in proto.params[idx].ty:
813 func_body.append(' glv_finalize_buffer_address(pHeader, (void**)&(pPacket->%s));' % (proto.params[idx].name))
814 func_body.append(' FINISH_TRACE_PACKET();')
815 if 'AllocMemory' in proto.name:
816 func_body.append(' add_new_handle_to_mem_info(*pMem, pAllocInfo->allocationSize, NULL);')
817 elif 'FreeMemory' in proto.name:
818 func_body.append(' rm_handle_from_mem_info(mem);')
819 if 'VOID' not in proto.ret or '*' in proto.ret:
820 func_body.append(' return result;')
821 func_body.append('}\n')
822 return "\n".join(func_body)
823
824 def _generate_helper_funcs(self):
825 hf_body = []
826 hf_body.append('// Support for shadowing CPU mapped memory')
827 hf_body.append('typedef struct _XGLAllocInfo {')
828 hf_body.append(' XGL_GPU_SIZE size;')
829 hf_body.append(' XGL_GPU_MEMORY handle;')
830 hf_body.append(' XGL_VOID *pData;')
831 hf_body.append(' BOOL valid;')
832 hf_body.append('} XGLAllocInfo;')
833 hf_body.append('typedef struct _XGLMemInfo {')
834 hf_body.append(' unsigned int numEntrys;')
835 hf_body.append(' XGLAllocInfo *pEntrys;')
836 hf_body.append(' XGLAllocInfo *pLastMapped;')
837 hf_body.append(' unsigned int capacity;')
838 hf_body.append('} XGLMemInfo;')
839 hf_body.append('')
840 hf_body.append('static XGLMemInfo mInfo = {0, NULL, NULL, 0};')
841 hf_body.append('')
842 hf_body.append('static void init_mem_info_entrys(XGLAllocInfo *ptr, const unsigned int num)')
843 hf_body.append('{')
844 hf_body.append(' unsigned int i;')
845 hf_body.append(' for (i = 0; i < num; i++)')
846 hf_body.append(' {')
847 hf_body.append(' XGLAllocInfo *entry = ptr + i;')
848 hf_body.append(' entry->pData = NULL;')
849 hf_body.append(' entry->size = 0;')
850 hf_body.append(' entry->handle = NULL;')
851 hf_body.append(' entry->valid = FALSE;')
852 hf_body.append(' }')
853 hf_body.append('}')
854 hf_body.append('')
855 hf_body.append('static void init_mem_info()')
856 hf_body.append('{')
857 hf_body.append(' mInfo.numEntrys = 0;')
858 hf_body.append(' mInfo.capacity = 1024;')
859 hf_body.append(' mInfo.pLastMapped = NULL;')
860 hf_body.append('')
861 hf_body.append(' mInfo.pEntrys = GLV_NEW_ARRAY(XGLAllocInfo, mInfo.capacity);')
862 hf_body.append('')
863 hf_body.append(' if (mInfo.pEntrys == NULL)')
864 hf_body.append(' glv_LogError("init_mem_info() malloc failed\\n");')
865 hf_body.append(' else')
866 hf_body.append(' init_mem_info_entrys(mInfo.pEntrys, mInfo.capacity);')
867 hf_body.append('}')
868 hf_body.append('')
869 hf_body.append('static void delete_mem_info()')
870 hf_body.append('{')
871 hf_body.append(' GLV_DELETE(mInfo.pEntrys);')
872 hf_body.append(' mInfo.pEntrys = NULL;')
873 hf_body.append(' mInfo.numEntrys = 0;')
874 hf_body.append(' mInfo.capacity = 0;')
875 hf_body.append(' mInfo.pLastMapped = NULL;')
876 hf_body.append('}')
877 hf_body.append('')
878 hf_body.append('static XGLAllocInfo * get_mem_info_entry()')
879 hf_body.append('{')
880 hf_body.append(' unsigned int i;')
881 hf_body.append(' XGLAllocInfo *entry;')
882 hf_body.append(' if (mInfo.numEntrys > mInfo.capacity)')
883 hf_body.append(' {')
884 hf_body.append(' glv_LogError("get_mem_info_entry() bad internal state numEntrys\\n");')
885 hf_body.append(' return NULL;')
886 hf_body.append(' }')
887 hf_body.append('')
888 hf_body.append(' if (mInfo.numEntrys == mInfo.capacity)')
889 hf_body.append(' { // grow the array 2x')
890 hf_body.append(' mInfo.capacity *= 2;')
891 hf_body.append(' mInfo.pEntrys = (XGLAllocInfo *) GLV_REALLOC(mInfo.pEntrys, mInfo.capacity * sizeof(XGLAllocInfo));')
892 hf_body.append(' //init the newly added entrys')
893 hf_body.append(' init_mem_info_entrys(mInfo.pEntrys + mInfo.capacity / 2, mInfo.capacity / 2);')
894 hf_body.append(' }')
895 hf_body.append('')
896 hf_body.append(' assert(mInfo.numEntrys < mInfo.capacity);')
897 hf_body.append(' entry = mInfo.pEntrys;')
898 hf_body.append(' for (i = 0; i < mInfo.capacity; i++)')
899 hf_body.append(' {')
900 hf_body.append(' if ((entry + i)->valid == FALSE)')
901 hf_body.append(' return entry + i;')
902 hf_body.append(' }')
903 hf_body.append('')
904 hf_body.append(' glv_LogError("get_mem_info_entry() did not find an entry\\n");')
905 hf_body.append(' return NULL;')
906 hf_body.append('}')
907 hf_body.append('')
908 hf_body.append('static XGLAllocInfo * find_mem_info_entry(const XGL_GPU_MEMORY handle)')
909 hf_body.append('{')
910 hf_body.append(' XGLAllocInfo *entry = mInfo.pEntrys;')
911 hf_body.append(' unsigned int i;')
912 hf_body.append(' if (mInfo.pLastMapped && mInfo.pLastMapped->handle == handle && mInfo.pLastMapped->valid)')
913 hf_body.append(' return mInfo.pLastMapped;')
914 hf_body.append(' for (i = 0; i < mInfo.numEntrys; i++)')
915 hf_body.append(' {')
916 hf_body.append(' if ((entry + i)->valid && (handle == (entry + i)->handle))')
917 hf_body.append(' return entry + i;')
918 hf_body.append(' }')
919 hf_body.append('')
920 hf_body.append(' return NULL;')
921 hf_body.append('}')
922 hf_body.append('')
923 hf_body.append('static void add_new_handle_to_mem_info(const XGL_GPU_MEMORY handle, XGL_GPU_SIZE size, XGL_VOID *pData)')
924 hf_body.append('{')
925 hf_body.append(' XGLAllocInfo *entry;')
926 hf_body.append('')
927 hf_body.append(' if (mInfo.capacity == 0)')
928 hf_body.append(' init_mem_info();')
929 hf_body.append('')
930 hf_body.append(' entry = get_mem_info_entry();')
931 hf_body.append(' if (entry)')
932 hf_body.append(' {')
933 hf_body.append(' entry->valid = TRUE;')
934 hf_body.append(' entry->handle = handle;')
935 hf_body.append(' entry->size = size;')
936 hf_body.append(' entry->pData = pData; // NOTE: xglFreeMemory will free this mem, so no malloc()')
937 hf_body.append(' mInfo.numEntrys++;')
938 hf_body.append(' }')
939 hf_body.append('}')
940 hf_body.append('')
941 hf_body.append('static void add_data_to_mem_info(const XGL_GPU_MEMORY handle, XGL_VOID *pData)')
942 hf_body.append('{')
943 hf_body.append(' XGLAllocInfo *entry = find_mem_info_entry(handle);')
944 hf_body.append('')
945 hf_body.append(' if (entry)')
946 hf_body.append(' {')
947 hf_body.append(' entry->pData = pData;')
948 hf_body.append(' }')
949 hf_body.append(' mInfo.pLastMapped = entry;')
950 hf_body.append('}')
951 hf_body.append('')
952 hf_body.append('static void rm_handle_from_mem_info(const XGL_GPU_MEMORY handle)')
953 hf_body.append('{')
954 hf_body.append(' XGLAllocInfo *entry = find_mem_info_entry(handle);')
955 hf_body.append('')
956 hf_body.append(' if (entry)')
957 hf_body.append(' {')
958 hf_body.append(' entry->valid = FALSE;')
959 hf_body.append(' entry->pData = NULL;')
960 hf_body.append(' entry->size = 0;')
961 hf_body.append(' entry->handle = NULL;')
962 hf_body.append('')
963 hf_body.append(' mInfo.numEntrys--;')
964 hf_body.append(' if (entry == mInfo.pLastMapped)')
965 hf_body.append(' mInfo.pLastMapped = NULL;')
966 hf_body.append(' if (mInfo.numEntrys == 0)')
967 hf_body.append(' delete_mem_info();')
968 hf_body.append(' }')
969 hf_body.append('}')
970 hf_body.append('')
971 hf_body.append('static size_t calculate_pipeline_shader_size(const XGL_PIPELINE_SHADER* shader)')
972 hf_body.append('{')
973 hf_body.append(' size_t size = 0;')
974 hf_body.append(' XGL_UINT i, j;')
975 hf_body.append(' ')
976 hf_body.append(' size += sizeof(XGL_PIPELINE_SHADER);')
977 hf_body.append(' // descriptor sets')
978 hf_body.append(' for (i = 0; i < XGL_MAX_DESCRIPTOR_SETS; i++)')
979 hf_body.append(' {')
980 hf_body.append(' for (j = 0; j < shader->descriptorSetMapping[i].descriptorCount; j++)')
981 hf_body.append(' {')
982 hf_body.append(' size += sizeof(XGL_DESCRIPTOR_SLOT_INFO);')
983 hf_body.append(' if (shader->descriptorSetMapping[i].pDescriptorInfo[j].slotObjectType == XGL_SLOT_NEXT_DESCRIPTOR_SET)')
984 hf_body.append(' {')
985 hf_body.append(' size += sizeof(XGL_DESCRIPTOR_SET_MAPPING);')
986 hf_body.append(' }')
987 hf_body.append(' }')
988 hf_body.append(' }')
989 hf_body.append('')
990 hf_body.append(' // constant buffers')
991 hf_body.append(' if (shader->linkConstBufferCount > 0 && shader->pLinkConstBufferInfo != NULL)')
992 hf_body.append(' {')
993 hf_body.append(' XGL_UINT i;')
994 hf_body.append(' for (i = 0; i < shader->linkConstBufferCount; i++)')
995 hf_body.append(' {')
996 hf_body.append(' size += sizeof(XGL_LINK_CONST_BUFFER);')
997 hf_body.append(' size += shader->pLinkConstBufferInfo[i].bufferSize;')
998 hf_body.append(' }')
999 hf_body.append(' }')
1000 hf_body.append(' return size;')
1001 hf_body.append('}')
1002 hf_body.append('')
1003 hf_body.append('static void add_pipeline_shader_to_trace_packet(glv_trace_packet_header* pHeader, XGL_PIPELINE_SHADER* packetShader, const XGL_PIPELINE_SHADER* paramShader)')
1004 hf_body.append('{')
1005 hf_body.append(' XGL_UINT i, j;')
1006 hf_body.append(' // descriptor sets')
1007 hf_body.append(' for (i = 0; i < XGL_MAX_DESCRIPTOR_SETS; i++)')
1008 hf_body.append(' {')
1009 hf_body.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)&(packetShader->descriptorSetMapping[i].pDescriptorInfo), sizeof(XGL_DESCRIPTOR_SLOT_INFO)* paramShader->descriptorSetMapping[i].descriptorCount, paramShader->descriptorSetMapping[i].pDescriptorInfo);')
1010 hf_body.append(' for (j = 0; j < paramShader->descriptorSetMapping[i].descriptorCount; j++)')
1011 hf_body.append(' {')
1012 hf_body.append(' if (paramShader->descriptorSetMapping[i].pDescriptorInfo[j].slotObjectType == XGL_SLOT_NEXT_DESCRIPTOR_SET)')
1013 hf_body.append(' {')
1014 hf_body.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)&(packetShader->descriptorSetMapping[i].pDescriptorInfo[j].pNextLevelSet), sizeof(XGL_DESCRIPTOR_SET_MAPPING), paramShader->descriptorSetMapping[i].pDescriptorInfo[j].pNextLevelSet);')
1015 hf_body.append(' }')
1016 hf_body.append(' }')
1017 hf_body.append(' packetShader->descriptorSetMapping[i].descriptorCount = paramShader->descriptorSetMapping[i].descriptorCount;')
1018 hf_body.append(' }')
1019 hf_body.append('')
1020 hf_body.append(' // constant buffers')
1021 hf_body.append(' if (paramShader->linkConstBufferCount > 0 && paramShader->pLinkConstBufferInfo != NULL)')
1022 hf_body.append(' {')
1023 hf_body.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)&(packetShader->pLinkConstBufferInfo), sizeof(XGL_LINK_CONST_BUFFER) * paramShader->linkConstBufferCount, paramShader->pLinkConstBufferInfo);')
1024 hf_body.append(' for (i = 0; i < paramShader->linkConstBufferCount; i++)')
1025 hf_body.append(' {')
1026 hf_body.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)&(packetShader->pLinkConstBufferInfo[i].pBufferData), packetShader->pLinkConstBufferInfo[i].bufferSize, paramShader->pLinkConstBufferInfo[i].pBufferData);')
1027 hf_body.append(' }')
1028 hf_body.append(' }')
1029 hf_body.append('}')
1030 hf_body.append('')
1031 hf_body.append('static void finalize_pipeline_shader_address(glv_trace_packet_header* pHeader, const XGL_PIPELINE_SHADER* packetShader)')
1032 hf_body.append('{')
1033 hf_body.append(' XGL_UINT i, j;')
1034 hf_body.append(' // descriptor sets')
1035 hf_body.append(' for (i = 0; i < XGL_MAX_DESCRIPTOR_SETS; i++)')
1036 hf_body.append(' {')
1037 hf_body.append(' for (j = 0; j < packetShader->descriptorSetMapping[i].descriptorCount; j++)')
1038 hf_body.append(' {')
1039 hf_body.append(' if (packetShader->descriptorSetMapping[i].pDescriptorInfo[j].slotObjectType == XGL_SLOT_NEXT_DESCRIPTOR_SET)')
1040 hf_body.append(' {')
1041 hf_body.append(' glv_finalize_buffer_address(pHeader, (void**)&(packetShader->descriptorSetMapping[i].pDescriptorInfo[j].pNextLevelSet));')
1042 hf_body.append(' }')
1043 hf_body.append(' }')
1044 hf_body.append(' glv_finalize_buffer_address(pHeader, (void**)&(packetShader->descriptorSetMapping[i].pDescriptorInfo));')
1045 hf_body.append(' }')
1046 hf_body.append('')
1047 hf_body.append(' // constant buffers')
1048 hf_body.append(' if (packetShader->linkConstBufferCount > 0 && packetShader->pLinkConstBufferInfo != NULL)')
1049 hf_body.append(' {')
1050 hf_body.append(' for (i = 0; i < packetShader->linkConstBufferCount; i++)')
1051 hf_body.append(' {')
1052 hf_body.append(' glv_finalize_buffer_address(pHeader, (void**)&(packetShader->pLinkConstBufferInfo[i].pBufferData));')
1053 hf_body.append(' }')
1054 hf_body.append(' glv_finalize_buffer_address(pHeader, (void**)&(packetShader->pLinkConstBufferInfo));')
1055 hf_body.append(' }')
1056 hf_body.append('}')
1057 hf_body.append('')
1058 hf_body.append('static size_t calculate_pipeline_state_size(const XGL_VOID* pState)')
1059 hf_body.append('{')
1060 hf_body.append(' const XGL_GRAPHICS_PIPELINE_CREATE_INFO* pNext = pState;')
1061 hf_body.append(' size_t totalStateSize = 0;')
1062 hf_body.append(' while (pNext)')
1063 hf_body.append(' {')
1064 hf_body.append(' switch (pNext->sType)')
1065 hf_body.append(' {')
1066 hf_body.append(' case XGL_STRUCTURE_TYPE_PIPELINE_IA_STATE_CREATE_INFO:')
1067 hf_body.append(' totalStateSize += sizeof(XGL_PIPELINE_IA_STATE_CREATE_INFO);')
1068 hf_body.append(' break;')
1069 hf_body.append(' case XGL_STRUCTURE_TYPE_PIPELINE_TESS_STATE_CREATE_INFO:')
1070 hf_body.append(' totalStateSize += sizeof(XGL_PIPELINE_TESS_STATE_CREATE_INFO);')
1071 hf_body.append(' break;')
1072 hf_body.append(' case XGL_STRUCTURE_TYPE_PIPELINE_RS_STATE_CREATE_INFO:')
1073 hf_body.append(' totalStateSize += sizeof(XGL_PIPELINE_RS_STATE_CREATE_INFO);')
1074 hf_body.append(' break;')
1075 hf_body.append(' case XGL_STRUCTURE_TYPE_PIPELINE_DB_STATE_CREATE_INFO:')
1076 hf_body.append(' totalStateSize += sizeof(XGL_PIPELINE_DB_STATE_CREATE_INFO);')
1077 hf_body.append(' break;')
1078 hf_body.append(' case XGL_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO:')
1079 hf_body.append(' totalStateSize += sizeof(XGL_PIPELINE_CB_STATE);')
1080 hf_body.append(' break;')
1081 hf_body.append(' case XGL_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO:')
1082 hf_body.append(' {')
1083 hf_body.append(' const XGL_PIPELINE_SHADER_STAGE_CREATE_INFO* pShaderStage = (const XGL_PIPELINE_SHADER_STAGE_CREATE_INFO*)pNext;')
1084 hf_body.append(' totalStateSize += (sizeof(XGL_PIPELINE_SHADER_STAGE_CREATE_INFO) + calculate_pipeline_shader_size(&pShaderStage->shader));')
1085 hf_body.append(' break;')
1086 hf_body.append(' }')
1087 hf_body.append(' case XGL_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_CREATE_INFO:')
1088 hf_body.append(' {')
1089 hf_body.append(' const XGL_PIPELINE_VERTEX_INPUT_CREATE_INFO* pVi = (const XGL_PIPELINE_VERTEX_INPUT_CREATE_INFO*)pNext;')
1090 hf_body.append(' totalStateSize += sizeof(XGL_PIPELINE_VERTEX_INPUT_CREATE_INFO) + pVi->bindingCount * sizeof(XGL_VERTEX_INPUT_BINDING_DESCRIPTION)')
1091 hf_body.append(' + pVi->attributeCount * sizeof(XGL_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION);')
1092 hf_body.append(' break;')
1093 hf_body.append(' }')
1094 hf_body.append(' default:')
1095 hf_body.append(' assert(0);')
1096 hf_body.append(' }')
1097 hf_body.append(' pNext = (XGL_GRAPHICS_PIPELINE_CREATE_INFO*)pNext->pNext;')
1098 hf_body.append(' }')
1099 hf_body.append(' return totalStateSize;')
1100 hf_body.append('}')
1101 hf_body.append('')
1102 hf_body.append('static void add_pipeline_state_to_trace_packet(glv_trace_packet_header* pHeader, XGL_VOID** ppOut, const XGL_VOID* pIn)')
1103 hf_body.append('{')
1104 hf_body.append(' const XGL_GRAPHICS_PIPELINE_CREATE_INFO* pInNow = pIn;')
1105 hf_body.append(' XGL_GRAPHICS_PIPELINE_CREATE_INFO** ppOutNext = (XGL_GRAPHICS_PIPELINE_CREATE_INFO**)ppOut;')
1106 hf_body.append(' while (pInNow != NULL)')
1107 hf_body.append(' {')
1108 hf_body.append(' XGL_GRAPHICS_PIPELINE_CREATE_INFO** ppOutNow = ppOutNext;')
1109 hf_body.append(' ppOutNext = NULL;')
1110 hf_body.append('')
1111 hf_body.append(' switch (pInNow->sType)')
1112 hf_body.append(' {')
1113 hf_body.append(' case XGL_STRUCTURE_TYPE_PIPELINE_IA_STATE_CREATE_INFO:')
1114 hf_body.append(' {')
1115 hf_body.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)(ppOutNow), sizeof(XGL_PIPELINE_IA_STATE_CREATE_INFO), pInNow);')
1116 hf_body.append(' ppOutNext = (XGL_GRAPHICS_PIPELINE_CREATE_INFO**)&(*ppOutNow)->pNext;')
1117 hf_body.append(' glv_finalize_buffer_address(pHeader, (void**)(ppOutNow));')
1118 hf_body.append(' break;')
1119 hf_body.append(' }')
1120 hf_body.append(' case XGL_STRUCTURE_TYPE_PIPELINE_TESS_STATE_CREATE_INFO:')
1121 hf_body.append(' {')
1122 hf_body.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)(ppOutNow), sizeof(XGL_PIPELINE_TESS_STATE_CREATE_INFO), pInNow);')
1123 hf_body.append(' ppOutNext = (XGL_GRAPHICS_PIPELINE_CREATE_INFO**)&(*ppOutNow)->pNext;')
1124 hf_body.append(' glv_finalize_buffer_address(pHeader, (void**)(ppOutNow));')
1125 hf_body.append(' break;')
1126 hf_body.append(' }')
1127 hf_body.append(' case XGL_STRUCTURE_TYPE_PIPELINE_RS_STATE_CREATE_INFO:')
1128 hf_body.append(' {')
1129 hf_body.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)(ppOutNow), sizeof(XGL_PIPELINE_RS_STATE_CREATE_INFO), pInNow);')
1130 hf_body.append(' ppOutNext = (XGL_GRAPHICS_PIPELINE_CREATE_INFO**)&(*ppOutNow)->pNext;')
1131 hf_body.append(' glv_finalize_buffer_address(pHeader, (void**)(ppOutNow));')
1132 hf_body.append(' break;')
1133 hf_body.append(' }')
1134 hf_body.append(' case XGL_STRUCTURE_TYPE_PIPELINE_DB_STATE_CREATE_INFO:')
1135 hf_body.append(' {')
1136 hf_body.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)(ppOutNow), sizeof(XGL_PIPELINE_DB_STATE_CREATE_INFO), pInNow);')
1137 hf_body.append(' ppOutNext = (XGL_GRAPHICS_PIPELINE_CREATE_INFO**)&(*ppOutNow)->pNext;')
1138 hf_body.append(' glv_finalize_buffer_address(pHeader, (void**)(ppOutNow));')
1139 hf_body.append(' break;')
1140 hf_body.append(' }')
1141 hf_body.append(' case XGL_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO:')
1142 hf_body.append(' {')
1143 hf_body.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)(ppOutNow), sizeof(XGL_PIPELINE_CB_STATE), pInNow);')
1144 hf_body.append(' ppOutNext = (XGL_GRAPHICS_PIPELINE_CREATE_INFO**)&(*ppOutNow)->pNext;')
1145 hf_body.append(' glv_finalize_buffer_address(pHeader, (void**)(ppOutNow));')
1146 hf_body.append(' break;')
1147 hf_body.append(' }')
1148 hf_body.append(' case XGL_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO:')
1149 hf_body.append(' {')
1150 hf_body.append(' XGL_PIPELINE_SHADER_STAGE_CREATE_INFO* pPacket = NULL;')
1151 hf_body.append(' XGL_PIPELINE_SHADER_STAGE_CREATE_INFO* pInPacket = NULL;')
1152 hf_body.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)(ppOutNow), sizeof(XGL_PIPELINE_SHADER_STAGE_CREATE_INFO), pInNow);')
1153 hf_body.append(' pPacket = (XGL_PIPELINE_SHADER_STAGE_CREATE_INFO*) *ppOutNow;')
1154 hf_body.append(' pInPacket = (XGL_PIPELINE_SHADER_STAGE_CREATE_INFO*) pInNow;')
1155 hf_body.append(' add_pipeline_shader_to_trace_packet(pHeader, &pPacket->shader, &pInPacket->shader);')
1156 hf_body.append(' finalize_pipeline_shader_address(pHeader, &pPacket->shader);')
1157 hf_body.append(' ppOutNext = (XGL_GRAPHICS_PIPELINE_CREATE_INFO**)&(*ppOutNow)->pNext;')
1158 hf_body.append(' glv_finalize_buffer_address(pHeader, (void**)(ppOutNow));')
1159 hf_body.append(' break;')
1160 hf_body.append(' }')
1161 hf_body.append(' case XGL_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_CREATE_INFO:')
1162 hf_body.append(' {')
1163 hf_body.append(' XGL_PIPELINE_VERTEX_INPUT_CREATE_INFO *pPacket = NULL;')
1164 hf_body.append(' XGL_PIPELINE_VERTEX_INPUT_CREATE_INFO *pIn = NULL;')
1165 hf_body.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)(ppOutNow), sizeof(XGL_PIPELINE_VERTEX_INPUT_CREATE_INFO), pInNow);')
1166 hf_body.append(' pPacket = (XGL_PIPELINE_VERTEX_INPUT_CREATE_INFO*) *ppOutNow;')
1167 hf_body.append(' pIn = (XGL_PIPELINE_VERTEX_INPUT_CREATE_INFO*) pInNow;')
1168 hf_body.append(' glv_add_buffer_to_trace_packet(pHeader, (void **) &pPacket->pVertexBindingDescriptions, pIn->bindingCount * sizeof(XGL_VERTEX_INPUT_BINDING_DESCRIPTION), pIn->pVertexBindingDescriptions);')
1169 hf_body.append(' glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pVertexBindingDescriptions));')
1170 hf_body.append(' glv_add_buffer_to_trace_packet(pHeader, (void **) &pPacket->pVertexAttributeDescriptions, pIn->attributeCount * sizeof(XGL_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION), pIn->pVertexAttributeDescriptions);')
1171 hf_body.append(' glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pVertexAttributeDescriptions));')
1172 hf_body.append(' ppOutNext = (XGL_GRAPHICS_PIPELINE_CREATE_INFO**)&(*ppOutNow)->pNext;')
1173 hf_body.append(' glv_finalize_buffer_address(pHeader, (void**)(ppOutNow));')
1174 hf_body.append(' break;')
1175 hf_body.append(' }')
1176 hf_body.append(' default:')
1177 hf_body.append(' assert(!"Encountered an unexpected type in pipeline state list");')
1178 hf_body.append(' }')
1179 hf_body.append(' pInNow = (XGL_GRAPHICS_PIPELINE_CREATE_INFO*)pInNow->pNext;')
1180 hf_body.append(' }')
1181 hf_body.append(' return;')
1182 hf_body.append('}')
1183 return "\n".join(hf_body)
1184
Tobin Ehlis0a604842014-12-05 11:38:22 -07001185 def _generate_packet_id_enum(self):
1186 pid_enum = []
1187 pid_enum.append('enum GLV_TRACE_PACKET_ID_XGL')
1188 pid_enum.append('{')
1189 first_func = True
1190 for proto in self.protos:
1191 if first_func:
1192 first_func = False
1193 pid_enum.append(' GLV_TPI_XGL_xgl%s = GLV_TPI_BEGIN_API_HERE,' % proto.name)
1194 else:
1195 pid_enum.append(' GLV_TPI_XGL_xgl%s,' % proto.name)
1196 pid_enum.append('};\n')
1197 return "\n".join(pid_enum)
1198
1199 def _generate_interp_func(self):
1200 interp_func_body = []
1201 interp_func_body.append('static glv_trace_packet_header* interpret_trace_packet_xgl(glv_trace_packet_header* pHeader)')
1202 interp_func_body.append('{')
1203 interp_func_body.append(' if (pHeader == NULL)')
1204 interp_func_body.append(' {')
1205 interp_func_body.append(' return NULL;')
1206 interp_func_body.append(' }')
1207 interp_func_body.append(' switch (pHeader->packet_id)')
1208 interp_func_body.append(' {')
1209 for proto in self.protos:
1210 interp_func_body.append(' case GLV_TPI_XGL_xgl%s:\n {' % proto.name)
1211 header_prefix = 'h'
1212 if 'Wsi' in proto.name or 'Dbg' in proto.name:
1213 header_prefix = 'pH'
1214 interp_func_body.append(' return interpret_body_as_xgl%s(pHeader)->%seader;\n }' % (proto.name, header_prefix))
1215 interp_func_body.append(' default:')
1216 interp_func_body.append(' return NULL;')
1217 interp_func_body.append(' }')
1218 interp_func_body.append(' return NULL;')
1219 interp_func_body.append('}')
1220 return "\n".join(interp_func_body)
Tobin Ehlis811b5532014-12-01 12:53:53 -07001221
Tobin Ehlis12076fc2014-10-22 09:06:33 -06001222class LayerFuncsSubcommand(Subcommand):
1223 def generate_header(self):
1224 return '#include <xglLayer.h>\n#include "loader.h"'
1225
1226 def generate_body(self):
1227 return self._generate_dispatch_entrypoints("static", True)
1228
1229class LayerDispatchSubcommand(Subcommand):
1230 def generate_header(self):
1231 return '#include "layer_wrappers.h"'
1232
1233 def generate_body(self):
1234 return self._generate_layer_dispatch_table()
1235
1236class GenericLayerSubcommand(Subcommand):
1237 def generate_header(self):
1238 return '#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <assert.h>\n#include <pthread.h>\n#include "xglLayer.h"\n\nstatic XGL_LAYER_DISPATCH_TABLE nextTable;\nstatic XGL_BASE_LAYER_OBJECT *pCurObj;\nstatic pthread_once_t tabOnce = PTHREAD_ONCE_INIT;\n'
1239
1240 def generate_body(self):
1241 body = [self._generate_layer_dispatch_table(),
Tobin Ehlisa363cfa2014-11-25 16:59:27 -07001242 self._generate_dispatch_entrypoints("XGL_LAYER_EXPORT", "Generic"),
Tobin Ehlis12076fc2014-10-22 09:06:33 -06001243 self._generate_layer_gpa_function()]
1244
1245 return "\n\n".join(body)
1246
1247class ApiDumpSubcommand(Subcommand):
1248 def generate_header(self):
Tobin Ehlisd009bae2014-11-24 15:46:55 -07001249 header_txt = []
1250 header_txt.append('#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <assert.h>\n#include <pthread.h>\n#include "xglLayer.h"\n#include "xgl_struct_string_helper.h"\n\nstatic XGL_LAYER_DISPATCH_TABLE nextTable;\nstatic XGL_BASE_LAYER_OBJECT *pCurObj;\nstatic pthread_once_t tabOnce = PTHREAD_ONCE_INIT;\npthread_mutex_t print_lock = PTHREAD_MUTEX_INITIALIZER;\n')
1251 header_txt.append('#define MAX_TID 513')
1252 header_txt.append('static pthread_t tidMapping[MAX_TID] = {0};')
1253 header_txt.append('static uint32_t maxTID = 0;')
1254 header_txt.append('// Map actual TID to an index value and return that index')
1255 header_txt.append('// This keeps TIDs in range from 0-MAX_TID and simplifies compares between runs')
1256 header_txt.append('static uint32_t getTIDIndex() {')
1257 header_txt.append(' pthread_t tid = pthread_self();')
1258 header_txt.append(' for (uint32_t i = 0; i < maxTID; i++) {')
1259 header_txt.append(' if (tid == tidMapping[i])')
1260 header_txt.append(' return i;')
1261 header_txt.append(' }')
1262 header_txt.append(" // Don't yet have mapping, set it and return newly set index")
1263 header_txt.append(' uint32_t retVal = (uint32_t)maxTID;')
1264 header_txt.append(' tidMapping[maxTID++] = tid;')
1265 header_txt.append(' assert(maxTID < MAX_TID);')
1266 header_txt.append(' return retVal;')
1267 header_txt.append('}')
1268 return "\n".join(header_txt)
Tobin Ehlis12076fc2014-10-22 09:06:33 -06001269
1270 def generate_body(self):
1271 body = [self._generate_layer_dispatch_table(),
Tobin Ehlisa363cfa2014-11-25 16:59:27 -07001272 self._generate_dispatch_entrypoints("XGL_LAYER_EXPORT", "APIDump"),
Tobin Ehlis12076fc2014-10-22 09:06:33 -06001273 self._generate_layer_gpa_function()]
1274
1275 return "\n\n".join(body)
1276
Tobin Ehlisea3d21b2014-11-12 13:11:15 -07001277class ApiDumpFileSubcommand(Subcommand):
1278 def generate_header(self):
Tobin Ehlisd009bae2014-11-24 15:46:55 -07001279 header_txt = []
1280 header_txt.append('#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <assert.h>\n#include <pthread.h>\n#include "xglLayer.h"\n#include "xgl_struct_string_helper.h"\n\nstatic XGL_LAYER_DISPATCH_TABLE nextTable;\nstatic XGL_BASE_LAYER_OBJECT *pCurObj;\nstatic pthread_once_t tabOnce = PTHREAD_ONCE_INIT;\n\nstatic FILE* pOutFile;\nstatic char* outFileName = "xgl_apidump.txt";\npthread_mutex_t file_lock = PTHREAD_MUTEX_INITIALIZER;\n')
1281 header_txt.append('#define MAX_TID 513')
1282 header_txt.append('static pthread_t tidMapping[MAX_TID] = {0};')
1283 header_txt.append('static uint32_t maxTID = 0;')
1284 header_txt.append('// Map actual TID to an index value and return that index')
1285 header_txt.append('// This keeps TIDs in range from 0-MAX_TID and simplifies compares between runs')
1286 header_txt.append('static uint32_t getTIDIndex() {')
1287 header_txt.append(' pthread_t tid = pthread_self();')
1288 header_txt.append(' for (uint32_t i = 0; i < maxTID; i++) {')
1289 header_txt.append(' if (tid == tidMapping[i])')
1290 header_txt.append(' return i;')
1291 header_txt.append(' }')
1292 header_txt.append(" // Don't yet have mapping, set it and return newly set index")
1293 header_txt.append(' uint32_t retVal = (uint32_t)maxTID;')
1294 header_txt.append(' tidMapping[maxTID++] = tid;')
1295 header_txt.append(' assert(maxTID < MAX_TID);')
1296 header_txt.append(' return retVal;')
1297 header_txt.append('}')
1298 return "\n".join(header_txt)
Tobin Ehlisea3d21b2014-11-12 13:11:15 -07001299
1300 def generate_body(self):
1301 body = [self._generate_layer_dispatch_table(),
Tobin Ehlisa363cfa2014-11-25 16:59:27 -07001302 self._generate_dispatch_entrypoints("XGL_LAYER_EXPORT", "APIDumpFile"),
Tobin Ehlisea3d21b2014-11-12 13:11:15 -07001303 self._generate_layer_gpa_function()]
1304
1305 return "\n\n".join(body)
1306
Tobin Ehlisd49efcb2014-11-25 17:43:26 -07001307class ApiDumpNoAddrSubcommand(Subcommand):
1308 def generate_header(self):
1309 header_txt = []
1310 header_txt.append('#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <assert.h>\n#include <pthread.h>\n#include "xglLayer.h"\n#include "xgl_struct_string_helper_no_addr.h"\n\nstatic XGL_LAYER_DISPATCH_TABLE nextTable;\nstatic XGL_BASE_LAYER_OBJECT *pCurObj;\nstatic pthread_once_t tabOnce = PTHREAD_ONCE_INIT;\npthread_mutex_t print_lock = PTHREAD_MUTEX_INITIALIZER;\n')
1311 header_txt.append('#define MAX_TID 513')
1312 header_txt.append('static pthread_t tidMapping[MAX_TID] = {0};')
1313 header_txt.append('static uint32_t maxTID = 0;')
1314 header_txt.append('// Map actual TID to an index value and return that index')
1315 header_txt.append('// This keeps TIDs in range from 0-MAX_TID and simplifies compares between runs')
1316 header_txt.append('static uint32_t getTIDIndex() {')
1317 header_txt.append(' pthread_t tid = pthread_self();')
1318 header_txt.append(' for (uint32_t i = 0; i < maxTID; i++) {')
1319 header_txt.append(' if (tid == tidMapping[i])')
1320 header_txt.append(' return i;')
1321 header_txt.append(' }')
1322 header_txt.append(" // Don't yet have mapping, set it and return newly set index")
1323 header_txt.append(' uint32_t retVal = (uint32_t)maxTID;')
1324 header_txt.append(' tidMapping[maxTID++] = tid;')
1325 header_txt.append(' assert(maxTID < MAX_TID);')
1326 header_txt.append(' return retVal;')
1327 header_txt.append('}')
1328 return "\n".join(header_txt)
1329
1330 def generate_body(self):
1331 body = [self._generate_layer_dispatch_table(),
1332 self._generate_dispatch_entrypoints("XGL_LAYER_EXPORT", "APIDump", True),
1333 self._generate_layer_gpa_function()]
1334
1335 return "\n\n".join(body)
1336
Tobin Ehlis12076fc2014-10-22 09:06:33 -06001337class ObjectTrackerSubcommand(Subcommand):
1338 def generate_header(self):
1339 header_txt = []
1340 header_txt.append('#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <assert.h>\n#include <pthread.h>')
Tobin Ehlisca915872014-11-18 11:28:33 -07001341 header_txt.append('#include "object_track.h"\n\nstatic XGL_LAYER_DISPATCH_TABLE nextTable;\nstatic XGL_BASE_LAYER_OBJECT *pCurObj;')
1342 header_txt.append('static pthread_once_t tabOnce = PTHREAD_ONCE_INIT;\nstatic long long unsigned int object_track_index = 0;')
1343 header_txt.append('// Ptr to LL of dbg functions')
1344 header_txt.append('static XGL_LAYER_DBG_FUNCTION_NODE *pDbgFunctionHead = NULL;')
1345 header_txt.append('// Utility function to handle reporting')
1346 header_txt.append('// If callbacks are enabled, use them, otherwise use printf')
1347 header_txt.append('static XGL_VOID layerCbMsg(XGL_DBG_MSG_TYPE msgType,')
1348 header_txt.append(' XGL_VALIDATION_LEVEL validationLevel,')
1349 header_txt.append(' XGL_BASE_OBJECT srcObject,')
1350 header_txt.append(' XGL_SIZE location,')
1351 header_txt.append(' XGL_INT msgCode,')
1352 header_txt.append(' const XGL_CHAR* pLayerPrefix,')
1353 header_txt.append(' const XGL_CHAR* pMsg)')
1354 header_txt.append('{')
1355 header_txt.append(' XGL_LAYER_DBG_FUNCTION_NODE *pTrav = pDbgFunctionHead;')
1356 header_txt.append(' if (pTrav) {')
1357 header_txt.append(' while (pTrav) {')
1358 header_txt.append(' pTrav->pfnMsgCallback(msgType, validationLevel, srcObject, location, msgCode, pMsg, pTrav->pUserData);')
1359 header_txt.append(' pTrav = pTrav->pNext;')
Tobin Ehlis12076fc2014-10-22 09:06:33 -06001360 header_txt.append(' }')
Tobin Ehlis12076fc2014-10-22 09:06:33 -06001361 header_txt.append(' }')
Tobin Ehlisca915872014-11-18 11:28:33 -07001362 header_txt.append(' else {')
1363 header_txt.append(' switch (msgType) {')
1364 header_txt.append(' case XGL_DBG_MSG_ERROR:')
1365 header_txt.append(' printf("{%s}ERROR : %s\\n", pLayerPrefix, pMsg);')
1366 header_txt.append(' break;')
1367 header_txt.append(' case XGL_DBG_MSG_WARNING:')
1368 header_txt.append(' printf("{%s}WARN : %s\\n", pLayerPrefix, pMsg);')
1369 header_txt.append(' break;')
1370 header_txt.append(' case XGL_DBG_MSG_PERF_WARNING:')
1371 header_txt.append(' printf("{%s}PERF_WARN : %s\\n", pLayerPrefix, pMsg);')
1372 header_txt.append(' break;')
1373 header_txt.append(' default:')
1374 header_txt.append(' printf("{%s}INFO : %s\\n", pLayerPrefix, pMsg);')
1375 header_txt.append(' break;')
Tobin Ehlis12076fc2014-10-22 09:06:33 -06001376 header_txt.append(' }')
Tobin Ehlisca915872014-11-18 11:28:33 -07001377 header_txt.append(' }')
1378 header_txt.append('}')
1379 header_txt.append('// We maintain a "Global" list which links every object and a')
1380 header_txt.append('// per-Object list which just links objects of a given type')
1381 header_txt.append('// The object node has both pointers so the actual nodes are shared between the two lists')
1382 header_txt.append('typedef struct _objNode {')
1383 header_txt.append(' OBJTRACK_NODE obj;')
1384 header_txt.append(' struct _objNode *pNextObj;')
1385 header_txt.append(' struct _objNode *pNextGlobal;')
1386 header_txt.append('} objNode;')
1387 header_txt.append('static objNode *pObjectHead[XGL_NUM_OBJECT_TYPE] = {0};')
1388 header_txt.append('static objNode *pGlobalHead = NULL;')
1389 header_txt.append('static uint64_t numObjs[XGL_NUM_OBJECT_TYPE] = {0};')
1390 header_txt.append('static uint64_t numTotalObjs = 0;')
1391 header_txt.append('// Debug function to print global list and each individual object list')
1392 header_txt.append('static void ll_print_lists()')
1393 header_txt.append('{')
1394 header_txt.append(' objNode* pTrav = pGlobalHead;')
1395 header_txt.append(' printf("=====GLOBAL OBJECT LIST (%lu total objs):\\n", numTotalObjs);')
1396 header_txt.append(' while (pTrav) {')
1397 header_txt.append(' printf(" ObjNode (%p) w/ %s obj %p has pNextGlobal %p\\n", (void*)pTrav, string_XGL_OBJECT_TYPE(pTrav->obj.objType), pTrav->obj.pObj, (void*)pTrav->pNextGlobal);')
1398 header_txt.append(' pTrav = pTrav->pNextGlobal;')
1399 header_txt.append(' }')
1400 header_txt.append(' for (uint32_t i = 0; i < XGL_NUM_OBJECT_TYPE; i++) {')
1401 header_txt.append(' pTrav = pObjectHead[i];')
1402 header_txt.append(' if (pTrav) {')
1403 header_txt.append(' printf("=====%s OBJECT LIST (%lu objs):\\n", string_XGL_OBJECT_TYPE(pTrav->obj.objType), numObjs[i]);')
1404 header_txt.append(' while (pTrav) {')
1405 header_txt.append(' printf(" ObjNode (%p) w/ %s obj %p has pNextObj %p\\n", (void*)pTrav, string_XGL_OBJECT_TYPE(pTrav->obj.objType), pTrav->obj.pObj, (void*)pTrav->pNextObj);')
1406 header_txt.append(' pTrav = pTrav->pNextObj;')
1407 header_txt.append(' }')
1408 header_txt.append(' }')
1409 header_txt.append(' }')
1410 header_txt.append('}')
1411 header_txt.append('static void ll_insert_obj(XGL_VOID* pObj, XGL_OBJECT_TYPE objType) {')
1412 header_txt.append(' char str[1024];')
1413 header_txt.append(' sprintf(str, "OBJ[%llu] : CREATE %s object %p", object_track_index++, string_XGL_OBJECT_TYPE(objType), (void*)pObj);')
1414 header_txt.append(' layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, pObj, 0, OBJTRACK_NONE, "OBJTRACK", str);')
1415 header_txt.append(' objNode* pNewObjNode = (objNode*)malloc(sizeof(objNode));')
1416 header_txt.append(' pNewObjNode->obj.pObj = pObj;')
1417 header_txt.append(' pNewObjNode->obj.objType = objType;')
1418 header_txt.append(' pNewObjNode->obj.numUses = 0;')
1419 header_txt.append(' // insert at front of global list')
1420 header_txt.append(' pNewObjNode->pNextGlobal = pGlobalHead;')
1421 header_txt.append(' pGlobalHead = pNewObjNode;')
1422 header_txt.append(' // insert at front of object list')
1423 header_txt.append(' pNewObjNode->pNextObj = pObjectHead[objType];')
1424 header_txt.append(' pObjectHead[objType] = pNewObjNode;')
1425 header_txt.append(' // increment obj counts')
1426 header_txt.append(' numObjs[objType]++;')
1427 header_txt.append(' numTotalObjs++;')
1428 header_txt.append(' //sprintf(str, "OBJ_STAT : %lu total objs & %lu %s objs.", numTotalObjs, numObjs[objType], string_XGL_OBJECT_TYPE(objType));')
1429 header_txt.append(' //ll_print_lists();')
1430 header_txt.append('}')
1431 header_txt.append('// Traverse global list and return type for given object')
1432 header_txt.append('static XGL_OBJECT_TYPE ll_get_obj_type(XGL_OBJECT object) {')
1433 header_txt.append(' objNode *pTrav = pGlobalHead;')
1434 header_txt.append(' while (pTrav) {')
1435 header_txt.append(' if (pTrav->obj.pObj == object)')
1436 header_txt.append(' return pTrav->obj.objType;')
1437 header_txt.append(' pTrav = pTrav->pNextGlobal;')
1438 header_txt.append(' }')
1439 header_txt.append(' char str[1024];')
1440 header_txt.append(' sprintf(str, "Attempting look-up on obj %p but it is NOT in the global list!", (void*)object);')
1441 header_txt.append(' layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, object, 0, OBJTRACK_MISSING_OBJECT, "OBJTRACK", str);')
1442 header_txt.append(' return XGL_OBJECT_TYPE_UNKNOWN;')
1443 header_txt.append('}')
1444 header_txt.append('static uint64_t ll_get_obj_uses(XGL_VOID* pObj, XGL_OBJECT_TYPE objType) {')
1445 header_txt.append(' objNode *pTrav = pObjectHead[objType];')
1446 header_txt.append(' while (pTrav) {')
1447 header_txt.append(' if (pTrav->obj.pObj == pObj) {')
1448 header_txt.append(' return pTrav->obj.numUses;')
1449 header_txt.append(' }')
1450 header_txt.append(' pTrav = pTrav->pNextObj;')
Tobin Ehlis12076fc2014-10-22 09:06:33 -06001451 header_txt.append(' }')
1452 header_txt.append(' return 0;')
1453 header_txt.append('}')
Tobin Ehlisca915872014-11-18 11:28:33 -07001454 header_txt.append('static void ll_increment_use_count(XGL_VOID* pObj, XGL_OBJECT_TYPE objType) {')
1455 header_txt.append(' objNode *pTrav = pObjectHead[objType];')
Tobin Ehlis12076fc2014-10-22 09:06:33 -06001456 header_txt.append(' while (pTrav) {')
Tobin Ehlisca915872014-11-18 11:28:33 -07001457 header_txt.append(' if (pTrav->obj.pObj == pObj) {')
1458 header_txt.append(' pTrav->obj.numUses++;')
1459 header_txt.append(' char str[1024];')
1460 header_txt.append(' sprintf(str, "OBJ[%llu] : USING %s object %p (%lu total uses)", object_track_index++, string_XGL_OBJECT_TYPE(objType), (void*)pObj, pTrav->obj.numUses);')
1461 header_txt.append(' layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, pObj, 0, OBJTRACK_NONE, "OBJTRACK", str);')
1462 header_txt.append(' return;')
1463 header_txt.append(' }')
1464 header_txt.append(' pTrav = pTrav->pNextObj;')
1465 header_txt.append(' }')
1466 header_txt.append(' // If we do not find obj, insert it and then increment count')
1467 header_txt.append(' char str[1024];')
1468 header_txt.append(' sprintf(str, "Unable to increment count for obj %p, will add to list as %s type and increment count", pObj, string_XGL_OBJECT_TYPE(objType));')
1469 header_txt.append(' layerCbMsg(XGL_DBG_MSG_WARNING, XGL_VALIDATION_LEVEL_0, pObj, 0, OBJTRACK_UNKNOWN_OBJECT, "OBJTRACK", str);')
1470 header_txt.append('')
1471 header_txt.append(' ll_insert_obj(pObj, objType);')
1472 header_txt.append(' ll_increment_use_count(pObj, objType);')
1473 header_txt.append('}')
1474 header_txt.append('// We usually do not know Obj type when we destroy it so have to fetch')
1475 header_txt.append('// Type from global list w/ ll_destroy_obj()')
1476 header_txt.append('// and then do the full removal from both lists w/ ll_remove_obj_type()')
1477 header_txt.append('static void ll_remove_obj_type(XGL_VOID* pObj, XGL_OBJECT_TYPE objType) {')
1478 header_txt.append(' objNode *pTrav = pObjectHead[objType];')
1479 header_txt.append(' objNode *pPrev = pObjectHead[objType];')
1480 header_txt.append(' while (pTrav) {')
1481 header_txt.append(' if (pTrav->obj.pObj == pObj) {')
1482 header_txt.append(' pPrev->pNextObj = pTrav->pNextObj;')
1483 header_txt.append(' // update HEAD of Obj list as needed')
1484 header_txt.append(' if (pObjectHead[objType] == pTrav)')
1485 header_txt.append(' pObjectHead[objType] = pTrav->pNextObj;')
1486 header_txt.append(' assert(numObjs[objType] > 0);')
1487 header_txt.append(' numObjs[objType]--;')
1488 header_txt.append(' char str[1024];')
1489 header_txt.append(' sprintf(str, "OBJ[%llu] : DESTROY %s object %p", object_track_index++, string_XGL_OBJECT_TYPE(objType), (void*)pObj);')
1490 header_txt.append(' layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, pObj, 0, OBJTRACK_NONE, "OBJTRACK", str);')
Tobin Ehlis12076fc2014-10-22 09:06:33 -06001491 header_txt.append(' return;')
1492 header_txt.append(' }')
1493 header_txt.append(' pPrev = pTrav;')
Tobin Ehlisca915872014-11-18 11:28:33 -07001494 header_txt.append(' pTrav = pTrav->pNextObj;')
Tobin Ehlis12076fc2014-10-22 09:06:33 -06001495 header_txt.append(' }')
Tobin Ehlisca915872014-11-18 11:28:33 -07001496 header_txt.append(' char str[1024];')
1497 header_txt.append(' sprintf(str, "OBJ INTERNAL ERROR : Obj %p was in global list but not in %s list", pObj, string_XGL_OBJECT_TYPE(objType));')
1498 header_txt.append(' layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, pObj, 0, OBJTRACK_INTERNAL_ERROR, "OBJTRACK", str);')
1499 header_txt.append('}')
1500 header_txt.append('// Parse global list to find obj type, then remove obj from obj type list, finally')
1501 header_txt.append('// remove obj from global list')
1502 header_txt.append('static void ll_destroy_obj(XGL_VOID* pObj) {')
1503 header_txt.append(' objNode *pTrav = pGlobalHead;')
1504 header_txt.append(' objNode *pPrev = pGlobalHead;')
1505 header_txt.append(' while (pTrav) {')
1506 header_txt.append(' if (pTrav->obj.pObj == pObj) {')
1507 header_txt.append(' ll_remove_obj_type(pObj, pTrav->obj.objType);')
1508 header_txt.append(' pPrev->pNextGlobal = pTrav->pNextGlobal;')
1509 header_txt.append(' // update HEAD of global list if needed')
1510 header_txt.append(' if (pGlobalHead == pTrav)')
1511 header_txt.append(' pGlobalHead = pTrav->pNextGlobal;')
1512 header_txt.append(' free(pTrav);')
1513 header_txt.append(' assert(numTotalObjs > 0);')
1514 header_txt.append(' numTotalObjs--;')
1515 header_txt.append(' char str[1024];')
1516 header_txt.append(' sprintf(str, "OBJ_STAT Removed %s obj %p that was used %lu times (%lu total objs & %lu %s objs).", string_XGL_OBJECT_TYPE(pTrav->obj.objType), pTrav->obj.pObj, pTrav->obj.numUses, numTotalObjs, numObjs[pTrav->obj.objType], string_XGL_OBJECT_TYPE(pTrav->obj.objType));')
1517 header_txt.append(' layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, pObj, 0, OBJTRACK_NONE, "OBJTRACK", str);')
1518 header_txt.append(' return;')
1519 header_txt.append(' }')
1520 header_txt.append(' pPrev = pTrav;')
1521 header_txt.append(' pTrav = pTrav->pNextGlobal;')
1522 header_txt.append(' }')
1523 header_txt.append(' char str[1024];')
1524 header_txt.append(' sprintf(str, "Unable to remove obj %p. Was it created? Has it already been destroyed?", pObj);')
1525 header_txt.append(' layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, pObj, 0, OBJTRACK_DESTROY_OBJECT_FAILED, "OBJTRACK", str);')
Tobin Ehlis12076fc2014-10-22 09:06:33 -06001526 header_txt.append('}')
1527
1528 return "\n".join(header_txt)
1529
1530 def generate_body(self):
1531 body = [self._generate_layer_dispatch_table(),
Tobin Ehlisa363cfa2014-11-25 16:59:27 -07001532 self._generate_dispatch_entrypoints("XGL_LAYER_EXPORT", "ObjectTracker"),
Tobin Ehlisca915872014-11-18 11:28:33 -07001533 self._generate_extensions(),
1534 self._generate_layer_gpa_function(extensions=['objTrackGetObjectCount', 'objTrackGetObjects'])]
Tobin Ehlis12076fc2014-10-22 09:06:33 -06001535
1536 return "\n\n".join(body)
Courtney Goeltzenleuchterb412d212014-11-18 10:40:29 -07001537
Tobin Ehlis811b5532014-12-01 12:53:53 -07001538class GlaveTraceHeader(Subcommand):
1539 def generate_header(self):
1540 header_txt = []
1541 header_txt.append('#include "glvtrace_xgl_xgl_structs.h"')
1542 header_txt.append('#include "glvtrace_xgl_packet_id.h"\n')
1543 header_txt.append('void AttachHooks();')
1544 header_txt.append('void DetachHooks();')
1545 header_txt.append('void InitTracer();\n')
1546 return "\n".join(header_txt)
1547
1548 def generate_body(self):
1549 body = [self._generate_trace_func_ptrs(),
1550 self._generate_trace_func_protos()]
1551
1552 return "\n".join(body)
1553
1554class GlaveTraceC(Subcommand):
1555 def generate_header(self):
1556 header_txt = []
1557 header_txt.append('#include "glv_platform.h"')
1558 header_txt.append('#include "glv_common.h"')
1559 header_txt.append('#include "glvtrace_xgl_xgl.h"')
1560 header_txt.append('#include "glvtrace_xgl_xgldbg.h"')
1561 header_txt.append('#include "glvtrace_xgl_xglwsix11ext.h"')
1562 header_txt.append('#include "glv_interconnect.h"')
1563 header_txt.append('#include "glv_filelike.h"')
1564 header_txt.append('#ifdef WIN32')
1565 header_txt.append('#include "mhook/mhook-lib/mhook.h"')
1566 header_txt.append('#endif')
1567 header_txt.append('#include "glv_trace_packet_utils.h"')
1568 header_txt.append('#include <stdio.h>\n')
1569 return "\n".join(header_txt)
1570
1571 def generate_body(self):
1572 body = [self._generate_func_ptr_assignments(),
1573 self._generate_attach_hooks(),
1574 self._generate_detach_hooks(),
1575 self._generate_init_tracer(),
1576 self._generate_helper_funcs(),
1577 self._generate_trace_funcs()]
1578
1579 return "\n".join(body)
1580
Tobin Ehlis0a604842014-12-05 11:38:22 -07001581class GlavePacketID(Subcommand):
1582 def generate_header(self):
1583 header_txt = []
1584 header_txt.append('#pragma once')
1585 header_txt.append('#include "glv_trace_packet_utils.h"')
1586 header_txt.append('#include "glv_interconnect.h"')
1587 header_txt.append('#include "glvtrace_xgl_xgl_structs.h"')
1588 header_txt.append('#include "glvtrace_xgl_xgldbg_structs.h"')
1589 header_txt.append('#include "glvtrace_xgl_xglwsix11ext_structs.h"')
1590 header_txt.append('#define SEND_ENTRYPOINT_ID(entrypoint) ;')
1591 header_txt.append('//#define SEND_ENTRYPOINT_ID(entrypoint) glv_TraceInfo(#entrypoint "\\n");\n')
1592 header_txt.append('#define SEND_ENTRYPOINT_PARAMS(entrypoint, ...) ;')
1593 header_txt.append('//#define SEND_ENTRYPOINT_PARAMS(entrypoint, ...) glv_TraceInfo(entrypoint, __VA_ARGS__);\n')
1594 header_txt.append('#define CREATE_TRACE_PACKET(entrypoint, buffer_bytes_needed) \\')
1595 header_txt.append(' pHeader = glv_create_trace_packet(GLV_TID_XGL, GLV_TPI_XGL_##entrypoint, sizeof(struct_##entrypoint), buffer_bytes_needed);\n')
1596 header_txt.append('#define FINISH_TRACE_PACKET() \\')
1597 header_txt.append(' glv_finalize_trace_packet(pHeader); \\')
1598 header_txt.append(' glv_write_trace_packet(pHeader, glv_trace_get_trace_file()); \\')
1599 header_txt.append(' glv_delete_trace_packet(&pHeader);')
1600 return "\n".join(header_txt)
1601
1602 def generate_body(self):
1603 body = [self._generate_packet_id_enum(),
1604 self._generate_interp_func()]
1605
1606 return "\n".join(body)
1607
Tobin Ehlis12076fc2014-10-22 09:06:33 -06001608def main():
1609 subcommands = {
1610 "layer-funcs" : LayerFuncsSubcommand,
1611 "layer-dispatch" : LayerDispatchSubcommand,
Tobin Ehlisa363cfa2014-11-25 16:59:27 -07001612 "Generic" : GenericLayerSubcommand,
1613 "ApiDump" : ApiDumpSubcommand,
1614 "ApiDumpFile" : ApiDumpFileSubcommand,
Tobin Ehlisd49efcb2014-11-25 17:43:26 -07001615 "ApiDumpNoAddr" : ApiDumpNoAddrSubcommand,
Tobin Ehlisa363cfa2014-11-25 16:59:27 -07001616 "ObjectTracker" : ObjectTrackerSubcommand,
Tobin Ehlis811b5532014-12-01 12:53:53 -07001617 "glave-trace-h" : GlaveTraceHeader,
1618 "glave-trace-c" : GlaveTraceC,
Tobin Ehlis0a604842014-12-05 11:38:22 -07001619 "glave-packet-id" : GlavePacketID,
Tobin Ehlis12076fc2014-10-22 09:06:33 -06001620 }
1621
1622 if len(sys.argv) < 2 or sys.argv[1] not in subcommands:
1623 print("Usage: %s <subcommand> [options]" % sys.argv[0])
1624 print
1625 print("Available sucommands are: %s" % " ".join(subcommands))
1626 exit(1)
1627
1628 subcmd = subcommands[sys.argv[1]](sys.argv[2:])
1629 subcmd.run()
1630
1631if __name__ == "__main__":
1632 main()