blob: d400516d6c592220137c6fa08a7c0e04c85826cd [file] [log] [blame]
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001#!/usr/bin/env python3
2#
3# Vulkan
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
26import os, sys
Jon Ashburncb622a12015-08-06 17:22:53 -060027
Jon Ashburn4d9cfd22015-08-04 13:35:25 -060028
29# add main repo directory so vulkan.py can be imported. This needs to be a complete path.
30glv_scripts_path = os.path.dirname(os.path.abspath(__file__))
Jon Ashburncb622a12015-08-06 17:22:53 -060031main_path = os.path.abspath(glv_scripts_path + "/../")
Jon Ashburn4d9cfd22015-08-04 13:35:25 -060032sys.path.append(main_path)
Jon Ashburncb622a12015-08-06 17:22:53 -060033from source_line_info import sourcelineinfo
Jon Ashburn4d9cfd22015-08-04 13:35:25 -060034
Jon Ashburncb622a12015-08-06 17:22:53 -060035import vulkan
36
37# vulkan.py doesn't include all the extensions (debug_report missing)
38headers = []
39objects = []
40protos = []
41for ext in vulkan.extensions_all:
42 headers.extend(ext.headers)
43 objects.extend(ext.objects)
44 protos.extend(ext.protos)
Jon Ashburn4d9cfd22015-08-04 13:35:25 -060045
46class Subcommand(object):
47 def __init__(self, argv):
48 self.argv = argv
49 self.extName = argv
Jon Ashburncb622a12015-08-06 17:22:53 -060050 self.headers = headers
51 self.objects = objects
52 self.protos = protos
Jon Ashburn4d9cfd22015-08-04 13:35:25 -060053 self.lineinfo = sourcelineinfo()
54
55 def run(self):
56 print(self.generate(self.extName))
57
58 def generate(self, extName):
59 copyright = self.generate_copyright()
60 header = self.generate_header(extName)
61 body = self.generate_body()
62 footer = self.generate_footer()
63 contents = []
64 if copyright:
65 contents.append(copyright)
66 if header:
67 contents.append(header)
68 if body:
69 contents.append(body)
70 if footer:
71 contents.append(footer)
72
73 return "\n\n".join(contents)
74
75 def generate_copyright(self):
76 return """/* THIS FILE IS GENERATED. DO NOT EDIT. */
77
78/*
79 * Vulkan
80 *
81 * Copyright (C) 2014 LunarG, Inc.
82 *
83 * Permission is hereby granted, free of charge, to any person obtaining a
84 * copy of this software and associated documentation files (the "Software"),
85 * to deal in the Software without restriction, including without limitation
86 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
87 * and/or sell copies of the Software, and to permit persons to whom the
88 * Software is furnished to do so, subject to the following conditions:
89 *
90 * The above copyright notice and this permission notice shall be included
91 * in all copies or substantial portions of the Software.
92 *
93 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
94 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
95 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
96 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
97 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
98 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
99 * DEALINGS IN THE SOFTWARE.
100 */"""
101
102 def generate_header(self, extName):
103 return "\n".join(["#include <" + h + ">" for h in self.headers])
104
105 def generate_body(self):
106 pass
107
108 def generate_footer(self):
109 pass
110
Jon Ashburn4d9cfd22015-08-04 13:35:25 -0600111 def _generate_trace_func_ptrs(self):
112 func_ptrs = []
113 func_ptrs.append('// Pointers to real functions and declarations of hooked functions')
114 func_ptrs.append('#ifdef WIN32')
115 func_ptrs.append('extern INIT_ONCE gInitOnce;')
116 for proto in vulkan.core.protos:
117 func_ptrs.append('#define __HOOKED_vk%s hooked_vk%s' % (proto.name, proto.name))
118
119 func_ptrs.append('\n#elif defined(PLATFORM_LINUX)')
120 func_ptrs.append('extern pthread_once_t gInitOnce;')
121 for proto in vulkan.core.protos:
122 func_ptrs.append('#define __HOOKED_vk%s vk%s' % (proto.name, proto.name))
123
124 func_ptrs.append('#endif\n')
125 return "\n".join(func_ptrs)
126
127 def _generate_trace_func_ptrs_ext(self, extName):
128 func_ptrs = []
129 func_ptrs.append('#ifdef WIN32')
Jon Ashburncb622a12015-08-06 17:22:53 -0600130 for ext in vulkan.extensions_all:
Jon Ashburn4d9cfd22015-08-04 13:35:25 -0600131 if (extName.lower() == ext.name.lower()):
132 for proto in ext.protos:
133 func_ptrs.append('#define __HOOKED_vk%s hooked_vk%s' % (proto.name, proto.name))
134
135 func_ptrs.append('#elif defined(__linux__)')
Jon Ashburncb622a12015-08-06 17:22:53 -0600136 for ext in vulkan.extensions_all:
Jon Ashburn4d9cfd22015-08-04 13:35:25 -0600137 if (extName.lower() == ext.name.lower()):
138 for proto in ext.protos:
139 func_ptrs.append('#define __HOOKED_vk%s vk%s' % (proto.name, proto.name))
140
141 func_ptrs.append('#endif\n')
142 return "\n".join(func_ptrs)
143
144 def _generate_trace_func_protos(self):
145 func_protos = []
146 func_protos.append('// Hooked function prototypes\n')
147 for proto in self.protos:
148 if 'Dbg' not in proto.name and 'WSI' not in proto.name:
149 func_protos.append('GLVTRACER_EXPORT %s;' % proto.c_func(prefix="__HOOKED_vk", attr="VKAPI"))
150
151 return "\n".join(func_protos)
152
153 def _generate_trace_func_protos_ext(self, extName):
154 func_protos = []
155 func_protos.append('// Hooked function prototypes\n')
Jon Ashburncb622a12015-08-06 17:22:53 -0600156 for ext in vulkan.extensions_all:
Jon Ashburn4d9cfd22015-08-04 13:35:25 -0600157 if (extName.lower() == ext.name.lower()):
158 for proto in ext.protos:
159 func_protos.append('GLVTRACER_EXPORT %s;' % proto.c_func(prefix="__HOOKED_vk", attr="VKAPI"))
160
161 return "\n".join(func_protos)
162
163
164 def _generate_trace_real_func_ptr_protos(self):
165 func_ptr_assign = []
166 func_ptr_assign.append('')
167 for proto in self.protos:
168 func_ptr_assign.append('extern %s( VKAPI * real_vk%s)(' % (proto.ret, proto.name))
169 for p in proto.params:
170 func_ptr_assign.append(' %s %s,' % (p.ty, p.name))
171 func_ptr_assign[-1] = func_ptr_assign[-1].replace(',', ');\n')
172 return "\n".join(func_ptr_assign)
173
174 def _generate_func_ptr_assignments(self):
175 func_ptr_assign = []
176 for proto in self.protos:
177 if 'Dbg' not in proto.name and 'WSI' not in proto.name:
178 func_ptr_assign.append('%s( VKAPI * real_vk%s)(' % (proto.ret, proto.name))
179 for p in proto.params:
180 func_ptr_assign.append(' %s %s,' % (p.ty, p.name))
181 func_ptr_assign[-1] = func_ptr_assign[-1].replace(',', ') = vk%s;\n' % (proto.name))
182 return "\n".join(func_ptr_assign)
183
184
185 def _generate_func_ptr_assignments_ext(self, extName):
186 func_ptr_assign = []
Jon Ashburncb622a12015-08-06 17:22:53 -0600187 for ext in vulkan.extensions_all:
Jon Ashburn4d9cfd22015-08-04 13:35:25 -0600188 if ext.name.lower() == extName.lower():
189 for proto in ext.protos:
190 func_ptr_assign.append('%s( VKAPI * real_vk%s)(' % (proto.ret, proto.name))
191 for p in proto.params:
192 func_ptr_assign.append(' %s %s,' % (p.ty, p.name))
193 func_ptr_assign[-1] = func_ptr_assign[-1].replace(',', ');\n')
194 return "\n".join(func_ptr_assign)
195
196 def _generate_attach_hooks(self):
197 hooks_txt = []
198 hooks_txt.append('// declared as extern in glvtrace_vk_helpers.h')
199 hooks_txt.append('BOOL isHooked = FALSE;\n')
200 hooks_txt.append('void AttachHooks()\n{\n BOOL hookSuccess = TRUE;\n#if defined(WIN32)')
201 hooks_txt.append(' Mhook_BeginMultiOperation(FALSE);')
202 hooks_txt.append(' if (real_vkCreateInstance != NULL)')
203 hooks_txt.append(' {\n isHooked = TRUE;')
204 hook_operator = '='
205 for proto in self.protos:
206 if 'Dbg' not in proto.name and 'WSI' not in proto.name:
207 hooks_txt.append(' hookSuccess %s Mhook_SetHook((PVOID*)&real_vk%s, hooked_vk%s);' % (hook_operator, proto.name, proto.name))
208 hook_operator = '&='
209 hooks_txt.append(' }\n')
210 hooks_txt.append(' if (!hookSuccess)\n {')
211 hooks_txt.append(' glv_LogError("Failed to hook Vulkan.");\n }\n')
212 hooks_txt.append(' Mhook_EndMultiOperation();\n')
213 hooks_txt.append('#elif defined(__linux__)')
214 hooks_txt.append(' if (real_vkCreateInstance == vkCreateInstance)')
215 hooks_txt.append(' hookSuccess = glv_platform_get_next_lib_sym((PVOID*)&real_vkCreateInstance,"vkCreateInstance");')
216 hooks_txt.append(' isHooked = TRUE;')
217 for proto in self.protos:
218 if 'Dbg' not in proto.name and 'WSI' not in proto.name and 'CreateInstance' not in proto.name:
219 hooks_txt.append(' hookSuccess %s glv_platform_get_next_lib_sym((PVOID*)&real_vk%s, "vk%s");' % (hook_operator, proto.name, proto.name))
220 hooks_txt.append(' if (!hookSuccess)\n {')
221 hooks_txt.append(' glv_LogError("Failed to hook Vulkan.");\n }\n')
222 hooks_txt.append('#endif\n}\n')
223 return "\n".join(hooks_txt)
224
225 def _generate_detach_hooks(self):
226 hooks_txt = []
227 hooks_txt.append('void DetachHooks()\n{\n#ifdef __linux__\n return;\n#elif defined(WIN32)')
228 hooks_txt.append(' BOOL unhookSuccess = TRUE;\n if (real_vkGetPhysicalDeviceProperties != NULL)\n {')
229 hook_operator = '='
230 for proto in self.protos:
231 if 'Dbg' not in proto.name and 'WSI' not in proto.name:
232 hooks_txt.append(' unhookSuccess %s Mhook_Unhook((PVOID*)&real_vk%s);' % (hook_operator, proto.name))
233 hook_operator = '&='
234 hooks_txt.append(' }\n isHooked = FALSE;')
235 hooks_txt.append(' if (!unhookSuccess)\n {')
236 hooks_txt.append(' glv_LogError("Failed to unhook Vulkan.");\n }')
237 hooks_txt.append('#endif\n}')
238 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')
239 return "\n".join(hooks_txt)
240
241 def _generate_init_funcs(self):
242 init_tracer = []
243 init_tracer.append('void send_vk_api_version_packet()\n{')
244 init_tracer.append(' packet_vkApiVersion* pPacket;')
245 init_tracer.append(' glv_trace_packet_header* pHeader;')
246 init_tracer.append(' pHeader = glv_create_trace_packet(GLV_TID_VULKAN, GLV_TPI_VK_vkApiVersion, sizeof(packet_vkApiVersion), 0);')
247 init_tracer.append(' pPacket = interpret_body_as_vkApiVersion(pHeader);')
248 init_tracer.append(' pPacket->version = VK_API_VERSION;')
249 init_tracer.append(' glv_set_packet_entrypoint_end_time(pHeader);')
250 init_tracer.append(' FINISH_TRACE_PACKET();\n}\n')
251
252 init_tracer.append('extern GLV_CRITICAL_SECTION g_memInfoLock;')
253 init_tracer.append('void InitTracer(void)\n{')
254 init_tracer.append(' const char *ipAddr = glv_get_global_var("GLVLIB_TRACE_IPADDR");')
255 init_tracer.append(' if (ipAddr == NULL)')
256 init_tracer.append(' ipAddr = "127.0.0.1";')
257 init_tracer.append(' gMessageStream = glv_MessageStream_create(FALSE, ipAddr, GLV_BASE_PORT + GLV_TID_VULKAN);')
258 init_tracer.append(' glv_trace_set_trace_file(glv_FileLike_create_msg(gMessageStream));')
259 init_tracer.append(' glv_tracelog_set_tracer_id(GLV_TID_VULKAN);')
260 init_tracer.append(' glv_create_critical_section(&g_memInfoLock);')
261 init_tracer.append(' send_vk_api_version_packet();\n}\n')
262 return "\n".join(init_tracer)
263
264 # Take a list of params and return a list of dicts w/ ptr param details
265 def _get_packet_ptr_param_list(self, params):
266 ptr_param_list = []
267 # TODO : This is a slightly nicer way to handle custom cases than initial code, however
268 # this can still be further generalized to eliminate more custom code
269 # big case to handle is when ptrs to structs have embedded data that needs to be accounted for in packet
270 custom_ptr_dict = {'VkDeviceCreateInfo': {'add_txt': 'add_VkDeviceCreateInfo_to_packet(pHeader, (VkDeviceCreateInfo**) &(pPacket->pCreateInfo), pCreateInfo)',
271 'finalize_txt': ''},
272 'VkApplicationInfo': {'add_txt': 'add_VkApplicationInfo_to_packet(pHeader, (VkApplicationInfo**)&(pPacket->pAppInfo), pAppInfo)',
273 'finalize_txt': ''},
274 'VkPhysicalDevice': {'add_txt': 'glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pGpus), *pGpuCount*sizeof(VkPhysicalDevice), pGpus)',
275 'finalize_txt': 'default'},
276 'pDataSize': {'add_txt': 'glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pDataSize), sizeof(size_t), &_dataSize)',
277 'finalize_txt': 'glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pDataSize))'},
278# 'pData': {'add_txt': 'glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pData), _dataSize, pData)',
279# 'finalize_txt': 'default'},
280 'pName': {'add_txt': 'glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pName), ((pName != NULL) ? strlen(pName) + 1 : 0), pName)',
281 'finalize_txt': 'default'},
282 'pMarker': {'add_txt': 'glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pMarker), ((pMarker != NULL) ? strlen(pMarker) + 1 : 0), pMarker)',
283 'finalize_txt': 'default'},
284 'pExtName': {'add_txt': 'glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pExtName), ((pExtName != NULL) ? strlen(pExtName) + 1 : 0), pExtName)',
285 'finalize_txt': 'default'},
286 'pDescriptorSets': {'add_txt': 'glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pDescriptorSets), customSize, pDescriptorSets)',
287 'finalize_txt': 'default'},
288 'pSparseMemoryRequirements': {'add_txt': 'glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pSparseMemoryRequirements), (*pNumRequirements) * sizeof(VkSparseImageMemoryRequirements), pSparseMemoryRequirements)',
289 'finalize_txt': 'default'},
290 'VkSparseImageFormatProperties': {'add_txt': 'glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pProperties), (*pNumProperties) * sizeof(VkSparseImageFormatProperties), pProperties)',
291 'finalize_txt': 'default'},
292 'VkSparseMemoryBindInfo': {'add_txt': 'glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pBindInfo), numBindings * sizeof(VkSparseMemoryBindInfo), pBindInfo)',
293 'finalize_txt': 'default'},
294 'VkSparseImageMemoryBindInfo': {'add_txt': 'glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pBindInfo), numBindings * sizeof(VkSparseImageMemoryBindInfo), pBindInfo)',
295 'finalize_txt': 'default'},
296# 'VkShaderCreateInfo': {'add_txt': 'glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCreateInfo), sizeof(VkShaderCreateInfo), pCreateInfo);\n'
297# ' glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCreateInfo->pCode), ((pCreateInfo != NULL) ? pCreateInfo->codeSize : 0), pCreateInfo->pCode)',
298# 'finalize_txt': 'glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCreateInfo->pCode));\n'
299# ' glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCreateInfo))'},
300 'VkFramebufferCreateInfo': {'add_txt': 'glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCreateInfo), sizeof(VkFramebufferCreateInfo), pCreateInfo);\n'
301 ' glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCreateInfo->pColorAttachments), colorCount * sizeof(VkColorAttachmentBindInfo), pCreateInfo->pColorAttachments);\n'
302 ' glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCreateInfo->pDepthStencilAttachment), dsSize, pCreateInfo->pDepthStencilAttachment)',
303 'finalize_txt': 'glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCreateInfo->pColorAttachments));\n'
304 ' glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCreateInfo->pDepthStencilAttachment));\n'
305 ' glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCreateInfo))'},
306 'VkRenderPassCreateInfo': {'add_txt': 'glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCreateInfo), sizeof(VkRenderPassCreateInfo), pCreateInfo);\n'
307 ' glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCreateInfo->pColorFormats), colorCount * sizeof(VkFormat), pCreateInfo->pColorFormats);\n'
308 ' glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCreateInfo->pColorLayouts), colorCount * sizeof(VkImageLayout), pCreateInfo->pColorLayouts);\n'
309 ' glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCreateInfo->pColorLoadOps), colorCount * sizeof(VkAttachmentLoadOp), pCreateInfo->pColorLoadOps);\n'
310 ' glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCreateInfo->pColorStoreOps), colorCount * sizeof(VkAttachmentStoreOp), pCreateInfo->pColorStoreOps);\n'
311 ' glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCreateInfo->pColorLoadClearValues), colorCount * sizeof(VkClearColor), pCreateInfo->pColorLoadClearValues)',
312 'finalize_txt': 'glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCreateInfo->pColorFormats));\n'
313 ' glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCreateInfo->pColorLayouts));\n'
314 ' glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCreateInfo->pColorLoadOps));\n'
315 ' glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCreateInfo->pColorStoreOps));\n'
316 ' glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCreateInfo->pColorLoadClearValues));\n'
317 ' glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCreateInfo))'},
318 'VkPipelineLayoutCreateInfo': {'add_txt': 'glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCreateInfo), sizeof(VkPipelineLayoutCreateInfo), pCreateInfo);\n'
319 ' glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCreateInfo->pSetLayouts), pCreateInfo->descriptorSetCount * sizeof(VkDescriptorSetLayout), pCreateInfo->pSetLayouts);',
320 'finalize_txt': 'glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCreateInfo->pSetLayouts));\n'
321 ' glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCreateInfo))'},
322 'VkDynamicViewportStateCreateInfo': {'add_txt': 'glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCreateInfo), sizeof(VkDynamicViewportStateCreateInfo), pCreateInfo);\n'
323 ' glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCreateInfo->pViewports), vpsCount * sizeof(VkViewport), pCreateInfo->pViewports);\n'
324 ' glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCreateInfo->pScissors), vpsCount * sizeof(VkRect2D), pCreateInfo->pScissors)',
325 'finalize_txt': 'glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCreateInfo->pViewports));\n'
326 ' glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCreateInfo->pScissors));\n'
327 ' glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCreateInfo))'},
328 'VkMemoryAllocInfo': {'add_txt': 'glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pAllocInfo), sizeof(VkMemoryAllocInfo), pAllocInfo);\n'
329 ' add_alloc_memory_to_trace_packet(pHeader, (void**)&(pPacket->pAllocInfo->pNext), pAllocInfo->pNext)',
330 'finalize_txt': 'glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pAllocInfo))'},
331# 'VkGraphicsPipelineCreateInfo': {'add_txt': 'glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCreateInfos), count*sizeof(VkGraphicsPipelineCreateInfo), pCreateInfos);\n'
332# ' add_VkGraphicsPipelineCreateInfos_to_trace_packet(pHeader, (VkGraphicsPipelineCreateInfo*)pPacket->pCreateInfos, pCreateInfos, count)',
333# 'finalize_txt': 'glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCreateInfos))'},
334# 'VkComputePipelineCreateInfo': {'add_txt': 'glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCreateInfos), count*sizeof(VkComputePipelineCreateInfo), pCreateInfos);\n'
335# ' add_VkComputePipelineCreateInfos_to_trace_packet(pHeader, (VkComputePipelineCreateInfo*)pPacket->pCreateInfos, pCreateInfos, count)',
336# 'finalize_txt': 'glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCreateInfos))'},
337 'VkDescriptorPoolCreateInfo': {'add_txt': 'glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCreateInfo), sizeof(VkDescriptorPoolCreateInfo), pCreateInfo);\n'
338 ' glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCreateInfo->pTypeCount), pCreateInfo->count * sizeof(VkDescriptorTypeCount), pCreateInfo->pTypeCount)',
339 'finalize_txt': 'glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCreateInfo->pTypeCount));\n'
340 ' glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCreateInfo))'},
341 'VkDescriptorSetLayoutCreateInfo': {'add_txt': 'add_create_ds_layout_to_trace_packet(pHeader, &pPacket->pCreateInfo, pCreateInfo)',
342 'finalize_txt': '// pCreateInfo finalized in add_create_ds_layout_to_trace_packet'},
343 'VkSwapChainCreateInfoWSI': {'add_txt': 'glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCreateInfo), sizeof(VkSwapChainCreateInfoWSI), pCreateInfo);\n'
344 ' glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCreateInfo->pSurfaceDescription), sizeof(VkSurfaceDescriptionWSI), pCreateInfo->pSurfaceDescription)',
345 'finalize_txt': 'glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCreateInfo->pSurfaceDescription));\n'
346 ' glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCreateInfo))'},
347 'VkShaderModuleCreateInfo': {'add_txt': 'glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCreateInfo), sizeof(VkShaderModuleCreateInfo), pCreateInfo);\n'
348 ' glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCreateInfo->pCode), pPacket->pCreateInfo->codeSize, pCreateInfo->pCode)',
349 'finalize_txt': 'glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCreateInfo->pCode));\n'
350 ' glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCreateInfo))'},
351 'VkShaderCreateInfo': {'add_txt': 'glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCreateInfo), sizeof(VkShaderModuleCreateInfo), pCreateInfo);\n'
352 ' glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCreateInfo->pName), strlen(pPacket->pCreateInfo->pName), pCreateInfo->pName)',
353 'finalize_txt': 'glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCreateInfo->pName));\n'
354 ' glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCreateInfo))'},
355 }
356
357 for p in params:
358 pp_dict = {}
359 if '*' in p.ty and p.name not in ['pSysMem', 'pReserved']:
360# LUGMAL if 'const' in p.ty.lower() and 'count' in params[params.index(p)-1].name.lower() and p.name != 'pCreateInfos':
361 if 'const' in p.ty.lower() and 'count' in params[params.index(p)-1].name.lower():
362 pp_dict['add_txt'] = 'glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->%s), %s*sizeof(%s), %s)' % (p.name, params[params.index(p)-1].name, p.ty.strip('*').replace('const ', ''), p.name)
363 elif 'pOffsets' == p.name: # TODO : This is a custom case for BindVertexBuffers last param, need to clean this up
364 pp_dict['add_txt'] = 'glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->%s), %s*sizeof(%s), %s)' % (p.name, params[params.index(p)-2].name, p.ty.strip('*').replace('const ', ''), p.name)
365 elif p.ty.strip('*').replace('const ', '') in custom_ptr_dict:
366 pp_dict['add_txt'] = custom_ptr_dict[p.ty.strip('*').replace('const ', '')]['add_txt']
367 pp_dict['finalize_txt'] = custom_ptr_dict[p.ty.strip('*').replace('const ', '')]['finalize_txt']
368 elif p.name in custom_ptr_dict:
369 pp_dict['add_txt'] = custom_ptr_dict[p.name]['add_txt']
370 pp_dict['finalize_txt'] = custom_ptr_dict[p.name]['finalize_txt']
371 # TODO : This is custom hack to account for 2 pData items with dataSize param for sizing
372 if 'pData' == p.name and 'dataSize' == params[params.index(p)-1].name:
373 pp_dict['add_txt'] = pp_dict['add_txt'].replace('_dataSize', 'dataSize')
374 else:
375 pp_dict['add_txt'] = 'glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->%s), sizeof(%s), %s)' % (p.name, p.ty.strip('*').replace('const ', ''), p.name)
376 if 'finalize_txt' not in pp_dict or 'default' == pp_dict['finalize_txt']:
377 pp_dict['finalize_txt'] = 'glv_finalize_buffer_address(pHeader, (void**)&(pPacket->%s))' % (p.name)
378 pp_dict['index'] = params.index(p)
379 ptr_param_list.append(pp_dict)
380 return ptr_param_list
381
382 # Take a list of params and return a list of packet size elements
383 def _get_packet_size(self, extName, params):
384 ps = [] # List of elements to be added together to account for packet size for given params
385 skip_list = [] # store params that are already accounted for so we don't count them twice
386 # Dict of specific params with unique custom sizes
387 custom_size_dict = {'pSetBindPoints': '(VK_SHADER_STAGE_COMPUTE * sizeof(uint32_t))', # Accounting for largest possible array
388 'VkSwapChainCreateInfoWSI' : 'vk_wsi_device_swapchain_size_vkswapchaincreateinfowsi(pCreateInfo)',
389 }
390 size_func_suffix = ''
391 if extName.lower() != "vk_core":
392 size_func_suffix = '_%s' % extName.lower()
393 for p in params:
394 #First handle custom cases
395 if p.name in ['pCreateInfo', 'pSetLayoutInfoList', 'pBeginInfo', 'pAllocInfo'] and 'wsi' not in p.ty.lower():
396 ps.append('get_struct_chain_size%s((void*)%s)' % (size_func_suffix, p.name))
397 skip_list.append(p.name)
398 elif p.name in custom_size_dict:
399 ps.append(custom_size_dict[p.name])
400 skip_list.append(p.name)
401 elif p.ty.strip('*').replace('const ', '') in custom_size_dict:
402 tmp_ty = p.ty.strip('*').replace('const ', '')
403 ps.append(custom_size_dict[tmp_ty])
404 skip_list.append(p.name)
405 # Skip any params already handled
406 if p.name in skip_list:
407 continue
408 # Now check to identify dynamic arrays which depend on two params
409 if 'count' in p.name.lower():
410 next_idx = params.index(p)+1
411 # If next element is a const *, then multiply count and array type
412 if next_idx < len(params) and '*' in params[next_idx].ty and 'const' in params[next_idx].ty.lower():
413 if '*' in p.ty:
414 ps.append('*%s*sizeof(%s)' % (p.name, params[next_idx].ty.strip('*').replace('const ', '')))
415 else:
416 ps.append('%s*sizeof(%s)' % (p.name, params[next_idx].ty.strip('*').replace('const ', '')))
417 skip_list.append(params[next_idx].name)
418 if 'bindingCount' == p.name: # TODO : This is custom case for CmdBindVertexBuffers, need to clean it up
419 ps.append('%s*sizeof(%s)' % (p.name, params[next_idx+1].ty.strip('*').replace('const ', '')))
420 skip_list.append(params[next_idx+1].name)
421 elif '*' in p.ty: # Not a custom array size we're aware of, but ptr so need to account for its size
422 ps.append('sizeof(%s)' % (p.ty.strip('*').replace('const ', '')))
423 elif '*' in p.ty and p.name not in ['pSysMem', 'pReserved']:
424 if 'pData' == p.name:
425 if 'dataSize' == params[params.index(p)-1].name:
426 ps.append('dataSize')
427 elif 'counterCount' == params[params.index(p)-1].name:
428 ps.append('sizeof(%s)' % p.ty.strip('*').replace('const ', ''))
429 else:
430 #ps.append('((pDataSize != NULL && pData != NULL) ? *pDataSize : 0)')
431 ps.append('sizeof(void*)')
432 elif '**' in p.ty and 'void' in p.ty:
433 ps.append('sizeof(void*)')
434 elif 'void' in p.ty:
435 ps.append('sizeof(%s)' % p.name)
436 elif 'char' in p.ty:
437 ps.append('((%s != NULL) ? strlen(%s) + 1 : 0)' % (p.name, p.name))
438 elif 'pDataSize' in p.name:
439 ps.append('((pDataSize != NULL) ? sizeof(size_t) : 0)')
440 elif 'IMAGE_SUBRESOURCE' in p.ty and 'pSubresource' == p.name:
441 ps.append('((pSubresource != NULL) ? sizeof(VkImage_SUBRESOURCE) : 0)')
442 else:
443 ps.append('sizeof(%s)' % (p.ty.strip('*').replace('const ', '')))
444 return ps
445
446 # Generate functions used to trace API calls and store the input and result data into a packet
447 # Here's the general flow of code insertion w/ option items flagged w/ "?"
448 # Result decl?
449 # Packet struct decl
450 # ?Special case : setup call to function first and do custom API call time tracking
451 # CREATE_PACKET
452 # call real entrypoint and get return value (if there is one)
453 # Assign packet values
454 # FINISH packet
455 # return result if needed
456 def _generate_trace_funcs(self, extName):
457 func_body = []
458 manually_written_hooked_funcs = ['AllocMemory',
459 'AllocDescriptorSets',
460 'CreateDynamicViewportState',
461 'CreateDescriptorPool',
462 'CreateFramebuffer',
463 'CreateInstance',
464 'CreateRenderPass',
465 'CreateGraphicsPipelines',
466 'CreateComputePipelines',
467 'CmdPipelineBarrier',
468 'CmdWaitEvents',
469 'CmdBeginRenderPass',
470 'EnumeratePhysicalDevices',
471 'FreeMemory',
472 'FreeDescriptorSets',
473 'FlushMappedMemoryRanges',
474 'GetGlobalExtensionProperties',
475 'GetPhysicalDeviceExtensionProperties',
476 'GetGlobalLayerProperties',
477 'GetPhysicalDeviceLayerProperties',
Jon Ashburn9e8755b2015-08-10 08:53:44 -0600478 'GetPhysicalDeviceQueueFamilyProperties',
Jon Ashburn4d9cfd22015-08-04 13:35:25 -0600479 'GetQueryPoolResults',
480 'MapMemory',
481 'UnmapMemory',
482 'UpdateDescriptorSets',
483 'GetSurfaceInfoWSI',
484 'GetSwapChainInfoWSI',
485 'QueuePresentWSI',
486 ]
487
488 # validate the manually_written_hooked_funcs list
489 protoFuncs = [proto.name for proto in self.protos]
490 for func in manually_written_hooked_funcs:
491 if func not in protoFuncs:
492 sys.exit("Entry '%s' in manually_written_hooked_funcs list is not in the vulkan function prototypes" % func)
493
494 # process each of the entrypoint prototypes
Jon Ashburncb622a12015-08-06 17:22:53 -0600495 for ext in vulkan.extensions_all:
Jon Ashburn4d9cfd22015-08-04 13:35:25 -0600496 if ext.name.lower() == extName.lower():
497 for proto in ext.protos:
498 if proto.name in manually_written_hooked_funcs:
499 func_body.append( '// __HOOKED_vk%s is manually written. Look in glvtrace_vk_trace.c\n' % proto.name)
500 else:
501 raw_packet_update_list = [] # non-ptr elements placed directly into packet
502 ptr_packet_update_list = [] # ptr elements to be updated into packet
503 return_txt = ''
504 packet_size = []
505 in_data_size = False # flag when we need to capture local input size variable for in/out size
506 func_body.append('%s' % self.lineinfo.get())
507 func_body.append('GLVTRACER_EXPORT %s VKAPI __HOOKED_vk%s(' % (proto.ret, proto.name))
508 for p in proto.params: # TODO : For all of the ptr types, check them for NULL and return 0 if NULL
509 func_body.append(' %s %s,' % (p.ty, p.name))
510 if '*' in p.ty and p.name not in ['pSysMem', 'pReserved']:
511 if 'pDataSize' in p.name:
512 in_data_size = True;
513 elif 'pfnMsgCallback' == p.name:
514 raw_packet_update_list.append(' PFN_vkDbgMsgCallback* pNonConstCallback = (PFN_vkDbgMsgCallback*)&pPacket->pfnMsgCallback;')
515 raw_packet_update_list.append(' *pNonConstCallback = pfnMsgCallback;')
516 else:
517 raw_packet_update_list.append(' pPacket->%s = %s;' % (p.name, p.name))
518 # Get list of packet size modifiers due to ptr params
519 packet_size = self._get_packet_size(extName, proto.params)
520 ptr_packet_update_list = self._get_packet_ptr_param_list(proto.params)
521 func_body[-1] = func_body[-1].replace(',', ')')
522 # End of function declaration portion, begin function body
523 func_body.append('{\n glv_trace_packet_header* pHeader;')
524 if 'void' not in proto.ret or '*' in proto.ret:
525 func_body.append(' %s result;' % proto.ret)
526 return_txt = 'result = '
527 if in_data_size:
528 func_body.append(' size_t _dataSize;')
529 func_body.append(' packet_vk%s* pPacket = NULL;' % proto.name)
530 if (0 == len(packet_size)):
531 func_body.append(' CREATE_TRACE_PACKET(vk%s, 0);' % (proto.name))
532 else:
533 func_body.append(' CREATE_TRACE_PACKET(vk%s, %s);' % (proto.name, ' + '.join(packet_size)))
534
535 # TODO: need a better way to indicate which extensions should be mapped to which Get*ProcAddr
536 if proto.name == 'GetInstanceProcAddr':
537 for iProto in self.protos:
538 if 'Dbg' in iProto.name or 'GetPhysicalDeviceSurfaceSupportWSI' in iProto.name:
539 func_body.append(' if (strcmp(pName, "vk%s") == 0) {' % (iProto.name))
540 func_body.append(' real_vk%s = (PFN_vk%s)real_vkGetInstanceProcAddr(instance, pName);' % (iProto.name, iProto.name))
541 func_body.append(' glv_set_packet_entrypoint_end_time(pHeader);')
542 func_body.append(' if (real_vk%s != NULL) {' % (iProto.name))
543 func_body.append(' result = (PFN_vkVoidFunction)__HOOKED_vk%s;' % (iProto.name))
544 func_body.append(' } else {')
545 func_body.append(' result = NULL;')
546 func_body.append(' }')
547 func_body.append(' }')
548 elif proto.name == 'GetDeviceProcAddr':
549 for dProto in self.protos:
550 if 'WSI' in dProto.name:
551 func_body.append(' if (strcmp(pName, "vk%s") == 0) {' % (dProto.name))
552 func_body.append(' real_vk%s = (PFN_vk%s)real_vkGetDeviceProcAddr(device, pName);' % (dProto.name, dProto.name))
553 func_body.append(' glv_set_packet_entrypoint_end_time(pHeader);')
554 func_body.append(' if (real_vk%s != NULL) {' % (dProto.name))
555 func_body.append(' result = (PFN_vkVoidFunction)__HOOKED_vk%s;' % (dProto.name))
556 func_body.append(' } else {')
557 func_body.append(' result = NULL;')
558 func_body.append(' }')
559 func_body.append(' }')
560 else:
561 # call real entrypoint and get return value (if there is one)
562 func_body.append(' %sreal_vk%s;' % (return_txt, proto.c_call()))
563 func_body.append(' glv_set_packet_entrypoint_end_time(pHeader);')
564
565 if in_data_size:
566 func_body.append(' _dataSize = (pDataSize == NULL || pData == NULL) ? 0 : *pDataSize;')
567 func_body.append(' pPacket = interpret_body_as_vk%s(pHeader);' % proto.name)
568 func_body.append('\n'.join(raw_packet_update_list))
569 for pp_dict in ptr_packet_update_list: #buff_ptr_indices:
570 func_body.append(' %s;' % (pp_dict['add_txt']))
571 if 'void' not in proto.ret or '*' in proto.ret:
572 func_body.append(' pPacket->result = result;')
573 for pp_dict in ptr_packet_update_list:
574 if ('DeviceCreateInfo' not in proto.params[pp_dict['index']].ty):
575 func_body.append(' %s;' % (pp_dict['finalize_txt']))
576 # All buffers should be finalized by now, and the trace packet can be finished (which sends it over the socket)
577 func_body.append(' FINISH_TRACE_PACKET();')
578 # return result if needed
579 if 'void' not in proto.ret or '*' in proto.ret:
580 func_body.append(' return result;')
581 func_body.append('}\n')
582 return "\n".join(func_body)
583
584 def _generate_packet_id_enum(self):
585 pid_enum = []
586 pid_enum.append('enum GLV_TRACE_PACKET_ID_VK')
587 pid_enum.append('{')
588 first_func = True
589 for proto in self.protos:
590 if first_func:
591 first_func = False
592 pid_enum.append(' GLV_TPI_VK_vkApiVersion = GLV_TPI_BEGIN_API_HERE,')
593 pid_enum.append(' GLV_TPI_VK_vk%s,' % proto.name)
594 else:
595 pid_enum.append(' GLV_TPI_VK_vk%s,' % proto.name)
596 pid_enum.append('};\n')
597 return "\n".join(pid_enum)
598
599 def _generate_packet_id_name_func(self):
600 func_body = []
601 func_body.append('static const char *glv_vk_packet_id_name(const enum GLV_TRACE_PACKET_ID_VK id)')
602 func_body.append('{')
603 func_body.append(' switch(id) {')
604 func_body.append(' case GLV_TPI_VK_vkApiVersion:')
605 func_body.append(' {')
606 func_body.append(' return "vkApiVersion";')
607 func_body.append(' }')
608 for proto in self.protos:
609 func_body.append(' case GLV_TPI_VK_vk%s:' % proto.name)
610 func_body.append(' {')
611 func_body.append(' return "vk%s";' % proto.name)
612 func_body.append(' }')
613 func_body.append(' default:')
614 func_body.append(' return NULL;')
615 func_body.append(' }')
616 func_body.append('}\n')
617 return "\n".join(func_body)
618
Jon Ashburn4d9cfd22015-08-04 13:35:25 -0600619 def _generate_interp_func(self):
620 interp_func_body = []
621 interp_func_body.append('%s' % self.lineinfo.get())
622 interp_func_body.append('static glv_trace_packet_header* interpret_trace_packet_vk(glv_trace_packet_header* pHeader)')
623 interp_func_body.append('{')
624 interp_func_body.append(' if (pHeader == NULL)')
625 interp_func_body.append(' {')
626 interp_func_body.append(' return NULL;')
627 interp_func_body.append(' }')
628 interp_func_body.append(' switch (pHeader->packet_id)')
629 interp_func_body.append(' {')
630 interp_func_body.append(' case GLV_TPI_VK_vkApiVersion:')
631 interp_func_body.append(' {')
632 interp_func_body.append(' return interpret_body_as_vkApiVersion(pHeader)->header;')
633 interp_func_body.append(' }')
634 for proto in self.protos:
635 interp_func_body.append(' case GLV_TPI_VK_vk%s:\n {' % proto.name)
636 header_prefix = 'h'
637 if 'WSI' in proto.name or 'Dbg' in proto.name:
638 header_prefix = 'pH'
639 interp_func_body.append(' return interpret_body_as_vk%s(pHeader)->%seader;\n }' % (proto.name, header_prefix))
640 interp_func_body.append(' default:')
641 interp_func_body.append(' return NULL;')
642 interp_func_body.append(' }')
643 interp_func_body.append(' return NULL;')
644 interp_func_body.append('}')
645 return "\n".join(interp_func_body)
646
647 def _generate_struct_util_funcs(self):
648 lineinfo = self.lineinfo
649 pid_enum = []
650 pid_enum.append('%s' % lineinfo.get())
651 pid_enum.append('//=============================================================================')
652 pid_enum.append('static void add_VkApplicationInfo_to_packet(glv_trace_packet_header* pHeader, VkApplicationInfo** ppStruct, const VkApplicationInfo *pInStruct)')
653 pid_enum.append('{')
654 pid_enum.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)ppStruct, sizeof(VkApplicationInfo), pInStruct);')
655 pid_enum.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)&((*ppStruct)->pAppName), strlen(pInStruct->pAppName) + 1, pInStruct->pAppName);')
656 pid_enum.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)&((*ppStruct)->pEngineName), strlen(pInStruct->pEngineName) + 1, pInStruct->pEngineName);')
657 pid_enum.append(' glv_finalize_buffer_address(pHeader, (void**)&((*ppStruct)->pAppName));')
658 pid_enum.append(' glv_finalize_buffer_address(pHeader, (void**)&((*ppStruct)->pEngineName));')
659 pid_enum.append(' glv_finalize_buffer_address(pHeader, (void**)&*ppStruct);')
660 pid_enum.append('};\n')
661 pid_enum.append('%s' % lineinfo.get())
662 pid_enum.append('static void add_VkInstanceCreateInfo_to_packet(glv_trace_packet_header* pHeader, VkInstanceCreateInfo** ppStruct, VkInstanceCreateInfo *pInStruct)')
663 pid_enum.append('{')
664 pid_enum.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)ppStruct, sizeof(VkInstanceCreateInfo), pInStruct);')
665 pid_enum.append(' add_VkApplicationInfo_to_packet(pHeader, (VkApplicationInfo**)&((*ppStruct)->pAppInfo), pInStruct->pAppInfo);')
666 pid_enum.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)&((*ppStruct)->pAllocCb), sizeof(VkAllocCallbacks), pInStruct->pAllocCb);')
667 pid_enum.append(' glv_finalize_buffer_address(pHeader, (void**)&((*ppStruct)->pAllocCb));')
668 # TODO138 : This is an initial pass at getting the extension/layer arrays correct, needs to be validated.
669 pid_enum.append(' uint32_t i, siz = 0;')
670 pid_enum.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)&((*ppStruct)->ppEnabledLayerNames), pInStruct->layerCount * sizeof(char*), pInStruct->ppEnabledLayerNames);')
671 pid_enum.append(' if (pInStruct->layerCount > 0) ')
672 pid_enum.append(' {')
673 pid_enum.append(' for (i = 0; i < pInStruct->layerCount; i++) {')
674 pid_enum.append(' siz = (1 + strlen(pInStruct->ppEnabledLayerNames[i]));')
675 pid_enum.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)(&(*ppStruct)->ppEnabledLayerNames[i]), siz, pInStruct->ppEnabledLayerNames[i]);')
676 pid_enum.append(' glv_finalize_buffer_address(pHeader, (void **)&(*ppStruct)->ppEnabledLayerNames[i]);')
677 pid_enum.append(' }')
678 pid_enum.append(' }')
679 pid_enum.append(' glv_finalize_buffer_address(pHeader, (void **)&(*ppStruct)->ppEnabledLayerNames);')
680 pid_enum.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)&((*ppStruct)->ppEnabledExtensionNames), pInStruct->extensionCount * sizeof(char*), pInStruct->ppEnabledExtensionNames);')
681 pid_enum.append(' if (pInStruct->extensionCount > 0) ')
682 pid_enum.append(' {')
683 pid_enum.append(' for (i = 0; i < pInStruct->extensionCount; i++) {')
684 pid_enum.append(' siz = (1 + strlen(pInStruct->ppEnabledExtensionNames[i]));')
685 pid_enum.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)(&(*ppStruct)->ppEnabledExtensionNames[i]), siz, pInStruct->ppEnabledExtensionNames[i]);')
686 pid_enum.append(' glv_finalize_buffer_address(pHeader, (void **)&(*ppStruct)->ppEnabledExtensionNames[i]);')
687 pid_enum.append(' }')
688 pid_enum.append(' }')
689 pid_enum.append(' glv_finalize_buffer_address(pHeader, (void **)&(*ppStruct)->ppEnabledExtensionNames);')
690 pid_enum.append(' glv_finalize_buffer_address(pHeader, (void**)ppStruct);')
691 pid_enum.append('}\n')
692 pid_enum.append('%s' % lineinfo.get())
693 pid_enum.append('static void add_VkDeviceCreateInfo_to_packet(glv_trace_packet_header* pHeader, VkDeviceCreateInfo** ppStruct, const VkDeviceCreateInfo *pInStruct)')
694 pid_enum.append('{')
695 pid_enum.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)ppStruct, sizeof(VkDeviceCreateInfo), pInStruct);')
696 pid_enum.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)&(*ppStruct)->pRequestedQueues, pInStruct->queueRecordCount*sizeof(VkDeviceQueueCreateInfo), pInStruct->pRequestedQueues);')
697 pid_enum.append(' glv_finalize_buffer_address(pHeader, (void**)&(*ppStruct)->pRequestedQueues);')
698 # TODO138 : This is an initial pass at getting the extension/layer arrays correct, needs to be validated.
699 pid_enum.append(' uint32_t i, siz = 0;')
700 pid_enum.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)&((*ppStruct)->ppEnabledLayerNames), pInStruct->layerCount * sizeof(char*), pInStruct->ppEnabledLayerNames);')
701 pid_enum.append(' if (pInStruct->layerCount > 0) ')
702 pid_enum.append(' {')
703 pid_enum.append(' for (i = 0; i < pInStruct->layerCount; i++) {')
704 pid_enum.append(' siz = (1 + strlen(pInStruct->ppEnabledLayerNames[i]));')
705 pid_enum.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)(&(*ppStruct)->ppEnabledLayerNames[i]), siz, pInStruct->ppEnabledLayerNames[i]);')
706 pid_enum.append(' glv_finalize_buffer_address(pHeader, (void **)&(*ppStruct)->ppEnabledLayerNames[i]);')
707 pid_enum.append(' }')
708 pid_enum.append(' }')
709 pid_enum.append(' glv_finalize_buffer_address(pHeader, (void **)&(*ppStruct)->ppEnabledLayerNames);')
710 pid_enum.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)&((*ppStruct)->ppEnabledExtensionNames), pInStruct->extensionCount * sizeof(char*), pInStruct->ppEnabledExtensionNames);')
711 pid_enum.append(' if (pInStruct->extensionCount > 0) ')
712 pid_enum.append(' {')
713 pid_enum.append(' for (i = 0; i < pInStruct->extensionCount; i++) {')
714 pid_enum.append(' siz = (1 + strlen(pInStruct->ppEnabledExtensionNames[i]));')
715 pid_enum.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)(&(*ppStruct)->ppEnabledExtensionNames[i]), siz, pInStruct->ppEnabledExtensionNames[i]);')
716 pid_enum.append(' glv_finalize_buffer_address(pHeader, (void **)&(*ppStruct)->ppEnabledExtensionNames[i]);')
717 pid_enum.append(' }')
718 pid_enum.append(' }')
719 pid_enum.append(' glv_finalize_buffer_address(pHeader, (void **)&(*ppStruct)->ppEnabledExtensionNames);')
720 pid_enum.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)&(*ppStruct)->pEnabledFeatures, sizeof(VkPhysicalDeviceFeatures), pInStruct->pEnabledFeatures);')
721 pid_enum.append(' glv_finalize_buffer_address(pHeader, (void**)&(*ppStruct)->pEnabledFeatures);')
722 pid_enum.append(' glv_finalize_buffer_address(pHeader, (void**)ppStruct);')
723 pid_enum.append('}\n')
724 pid_enum.append('%s' % lineinfo.get())
725 pid_enum.append('//=============================================================================\n')
726 pid_enum.append('static VkInstanceCreateInfo* interpret_VkInstanceCreateInfo(glv_trace_packet_header* pHeader, intptr_t ptr_variable)')
727 pid_enum.append('{')
728 pid_enum.append(' VkInstanceCreateInfo* pVkInstanceCreateInfo = (VkInstanceCreateInfo*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)ptr_variable);\n')
729 pid_enum.append(' uint32_t i;')
730 pid_enum.append(' if (pVkInstanceCreateInfo != NULL)')
731 pid_enum.append(' {')
732 pid_enum.append(' pVkInstanceCreateInfo->pAppInfo = (VkApplicationInfo*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pVkInstanceCreateInfo->pAppInfo);')
733 pid_enum.append(' pVkInstanceCreateInfo->pAllocCb = (VkAllocCallbacks*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pVkInstanceCreateInfo->pAllocCb);')
734 pid_enum.append(' VkApplicationInfo** ppAppInfo = (VkApplicationInfo**) &pVkInstanceCreateInfo->pAppInfo;')
735 pid_enum.append(' (*ppAppInfo)->pAppName = (const char*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pVkInstanceCreateInfo->pAppInfo->pAppName);')
736 pid_enum.append(' (*ppAppInfo)->pEngineName = (const char*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pVkInstanceCreateInfo->pAppInfo->pEngineName);')
737 pid_enum.append(' if (pVkInstanceCreateInfo->layerCount > 0)')
738 pid_enum.append(' {')
739 pid_enum.append(' pVkInstanceCreateInfo->ppEnabledLayerNames = (const char* const*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pVkInstanceCreateInfo->ppEnabledLayerNames);')
740 pid_enum.append(' for (i = 0; i < pVkInstanceCreateInfo->layerCount; i++) {')
741 pid_enum.append(' char** ppTmp = (char**)&pVkInstanceCreateInfo->ppEnabledLayerNames[i];')
742 pid_enum.append(' *ppTmp = (char*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pVkInstanceCreateInfo->ppEnabledLayerNames[i]);')
743 pid_enum.append(' }')
744 pid_enum.append(' }')
745 pid_enum.append(' if (pVkInstanceCreateInfo->extensionCount > 0)')
746 pid_enum.append(' {')
747 pid_enum.append(' pVkInstanceCreateInfo->ppEnabledExtensionNames = (const char* const*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pVkInstanceCreateInfo->ppEnabledExtensionNames);')
748 pid_enum.append(' for (i = 0; i < pVkInstanceCreateInfo->extensionCount; i++) {')
749 pid_enum.append(' char** ppTmp = (char**)&pVkInstanceCreateInfo->ppEnabledExtensionNames[i];')
750 pid_enum.append(' *ppTmp = (char*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pVkInstanceCreateInfo->ppEnabledExtensionNames[i]);')
751 pid_enum.append(' }')
752 pid_enum.append(' }')
753 pid_enum.append(' }\n')
754 pid_enum.append(' return pVkInstanceCreateInfo;')
755 pid_enum.append('}\n')
756 pid_enum.append('%s' % lineinfo.get())
757 pid_enum.append('static VkDeviceCreateInfo* interpret_VkDeviceCreateInfo(glv_trace_packet_header* pHeader, intptr_t ptr_variable)')
758 pid_enum.append('{')
759 pid_enum.append(' VkDeviceCreateInfo* pVkDeviceCreateInfo = (VkDeviceCreateInfo*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)ptr_variable);\n')
760 pid_enum.append(' uint32_t i;')
761 pid_enum.append(' if (pVkDeviceCreateInfo != NULL)')
762 pid_enum.append(' {')
763 pid_enum.append(' pVkDeviceCreateInfo->pRequestedQueues = (const VkDeviceQueueCreateInfo *)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pVkDeviceCreateInfo->pRequestedQueues);\n')
764 pid_enum.append(' if (pVkDeviceCreateInfo->layerCount > 0)')
765 pid_enum.append(' {')
766 pid_enum.append(' pVkDeviceCreateInfo->ppEnabledLayerNames = (const char* const*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pVkDeviceCreateInfo->ppEnabledLayerNames);')
767 pid_enum.append(' for (i = 0; i < pVkDeviceCreateInfo->layerCount; i++) {')
768 pid_enum.append(' char** ppTmp = (char**)&pVkDeviceCreateInfo->ppEnabledLayerNames[i];')
769 pid_enum.append(' *ppTmp = (char*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pVkDeviceCreateInfo->ppEnabledLayerNames[i]);')
770 pid_enum.append(' }')
771 pid_enum.append(' }')
772 pid_enum.append(' if (pVkDeviceCreateInfo->extensionCount > 0)')
773 pid_enum.append(' {')
774 pid_enum.append(' pVkDeviceCreateInfo->ppEnabledExtensionNames = (const char* const*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pVkDeviceCreateInfo->ppEnabledExtensionNames);')
775 pid_enum.append(' for (i = 0; i < pVkDeviceCreateInfo->extensionCount; i++) {')
776 pid_enum.append(' char** ppTmp = (char**)&pVkDeviceCreateInfo->ppEnabledExtensionNames[i];')
777 pid_enum.append(' *ppTmp = (char*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pVkDeviceCreateInfo->ppEnabledExtensionNames[i]);')
778 pid_enum.append(' }')
779 pid_enum.append(' }')
780 pid_enum.append(' pVkDeviceCreateInfo->pEnabledFeatures = (const VkPhysicalDeviceFeatures*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pVkDeviceCreateInfo->pEnabledFeatures);\n')
781 pid_enum.append(' }\n')
782 pid_enum.append(' return pVkDeviceCreateInfo;')
783 pid_enum.append('}\n')
784 pid_enum.append('%s' % lineinfo.get())
785 pid_enum.append('static void interpret_VkPipelineShaderStageCreateInfo(glv_trace_packet_header* pHeader, VkPipelineShaderStageCreateInfo* pShader)')
786 pid_enum.append('{')
787 pid_enum.append(' if (pShader != NULL)')
788 pid_enum.append(' {')
789 pid_enum.append(' // specialization info')
790 pid_enum.append(' pShader->pSpecializationInfo = (const VkSpecializationInfo*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pShader->pSpecializationInfo);')
791 pid_enum.append(' if (pShader->pSpecializationInfo != NULL)')
792 pid_enum.append(' {')
793 pid_enum.append(' VkSpecializationInfo* pInfo = (VkSpecializationInfo*)pShader->pSpecializationInfo;')
794 pid_enum.append(' pInfo->pMap = (const VkSpecializationMapEntry*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pShader->pSpecializationInfo->pMap);')
795 pid_enum.append(' pInfo->pData = (const void*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pShader->pSpecializationInfo->pData);')
796 pid_enum.append(' }')
797 pid_enum.append(' }')
798 pid_enum.append('}\n')
799 pid_enum.append('//=============================================================================')
800 return "\n".join(pid_enum)
801
802 # Interpret functions used on replay to read in packets and interpret their contents
803 # This code gets generated into glv_vk_vk_packets.h file
804 def _generate_interp_funcs(self):
805 # Custom txt for given function and parameter. First check if param is NULL, then insert txt if not
806 # First some common code used by both CmdWaitEvents & CmdPipelineBarrier
807 mem_barrier_interp = ['uint32_t i = 0;\n',
808 'for (i = 0; i < pPacket->memBarrierCount; i++) {\n',
809 ' void** ppMB = (void**)&(pPacket->ppMemBarriers[i]);\n',
810 ' *ppMB = glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->ppMemBarriers[i]);\n',
811 ' //VkMemoryBarrier* pBarr = (VkMemoryBarrier*)pPacket->ppMemBarriers[i];\n',
812 ' // TODO : Could fix up the pNext ptrs here if they were finalized and if we cared by switching on Barrier type and remapping\n',
813 '}']
814 create_rp_interp = ['VkRenderPassCreateInfo* pInfo = (VkRenderPassCreateInfo*)pPacket->pCreateInfo;\n',
815 'uint32_t i = 0;\n',
816 'VkAttachmentDescription **ppAD = (VkAttachmentDescription **)&(pInfo->pAttachments);\n',
817 '*ppAD = (VkAttachmentDescription*) glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pInfo->pAttachments);\n',
818 'VkSubpassDescription** ppSP = (VkSubpassDescription**)&(pInfo->pSubpasses);\n',
819 '*ppSP = (VkSubpassDescription*) glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pInfo->pSubpasses);\n',
820 'for (i=0; i<pInfo->subpassCount; i++) {\n',
Jon Ashburn9e8755b2015-08-10 08:53:44 -0600821 ' VkAttachmentReference** pAR = (VkAttachmentReference**)&(pInfo->pSubpasses[i].pInputAttachments);\n',
822 ' *pAR = (VkAttachmentReference*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pInfo->pSubpasses[i].pInputAttachments);\n',
823 ' pAR = (VkAttachmentReference**)&(pInfo->pSubpasses[i].pColorAttachments);\n',
824 ' *pAR = (VkAttachmentReference*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pInfo->pSubpasses[i].pColorAttachments);\n',
825 ' pAR = (VkAttachmentReference**)&(pInfo->pSubpasses[i].pResolveAttachments);\n',
826 ' *pAR = (VkAttachmentReference*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pInfo->pSubpasses[i].pResolveAttachments);\n',
827 ' pAR = (VkAttachmentReference**)&(pInfo->pSubpasses[i].pPreserveAttachments);\n',
828 ' *pAR = (VkAttachmentReference*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pInfo->pSubpasses[i].pPreserveAttachments);\n',
Jon Ashburn4d9cfd22015-08-04 13:35:25 -0600829 '}\n',
830 'VkSubpassDependency** ppSD = (VkSubpassDependency**)&(pInfo->pDependencies);\n',
831 '*ppSD = (VkSubpassDependency*) glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pInfo->pDependencies);\n']
832 create_gfx_pipe = ['uint32_t i;\n',
833 'uint32_t j;\n',
834 'for (i=0; i<pPacket->count; i++) {\n',
835 'if (pPacket->pCreateInfos[i].sType == VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO) {\n',
836 '// need to make a non-const pointer to the pointer so that we can properly change the original pointer to the interpretted one\n',
837 'VkGraphicsPipelineCreateInfo* pNonConst = (VkGraphicsPipelineCreateInfo*)&(pPacket->pCreateInfos[i]);\n',
838 '// shader stages array\n',
839 'pNonConst->pStages = (VkPipelineShaderStageCreateInfo*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfos[i].pStages);\n',
840 'for (j = 0; j < pPacket->pCreateInfos[i].stageCount; j++)\n',
841 '{\n',
842 ' interpret_VkPipelineShaderStageCreateInfo(pHeader, (VkPipelineShaderStageCreateInfo*)&pPacket->pCreateInfos[i].pStages[j]);\n',
843 '}\n',
844 '// Vertex Input State\n',
845 'pNonConst->pVertexInputState = (VkPipelineVertexInputStateCreateInfo*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfos[i].pVertexInputState);\n',
846 'VkPipelineVertexInputStateCreateInfo* pNonConstVIState = (VkPipelineVertexInputStateCreateInfo*)pNonConst->pVertexInputState;\n',
847 'if (pNonConstVIState) {\n',
848 ' pNonConstVIState->pVertexBindingDescriptions = (const VkVertexInputBindingDescription*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfos[i].pVertexInputState->pVertexBindingDescriptions);\n',
849 ' pNonConstVIState->pVertexAttributeDescriptions = (const VkVertexInputAttributeDescription*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfos[i].pVertexInputState->pVertexAttributeDescriptions);\n',
850 '}\n',
851 '// Input Assembly State\n',
852 'pNonConst->pInputAssemblyState = (const VkPipelineInputAssemblyStateCreateInfo*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfos[i].pInputAssemblyState);\n',
853 '// Tesselation State\n',
854 'pNonConst->pTessellationState = (const VkPipelineTessellationStateCreateInfo*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfos[i].pTessellationState);\n',
855 '// Viewport State\n',
856 'pNonConst->pViewportState = (const VkPipelineViewportStateCreateInfo*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfos[i].pViewportState);\n',
857 '// Raster State\n',
858 'pNonConst->pRasterState = (const VkPipelineRasterStateCreateInfo*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfos[i].pRasterState);\n',
859 '// MultiSample State\n',
860 'pNonConst->pMultisampleState = (const VkPipelineMultisampleStateCreateInfo*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfos[i].pMultisampleState);\n',
861 '// DepthStencil State\n',
862 'pNonConst->pDepthStencilState = (const VkPipelineDepthStencilStateCreateInfo*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfos[i].pDepthStencilState);\n',
863 '// ColorBuffer State\n',
864 'pNonConst->pColorBlendState = (const VkPipelineColorBlendStateCreateInfo*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfos[i].pColorBlendState);\n',
865 'VkPipelineColorBlendStateCreateInfo* pNonConstCbState = (VkPipelineColorBlendStateCreateInfo*)pNonConst->pColorBlendState;\n',
866 'if (pNonConstCbState)\n',
867 ' pNonConstCbState->pAttachments = (const VkPipelineColorBlendAttachmentState*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfos[i].pColorBlendState->pAttachments);\n',
868 '} else {\n',
869 ' // This is unexpected.\n',
870 ' glv_LogError("CreateGraphicsPipelines must have CreateInfo stype of VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO.");\n',
871 ' pPacket->header = NULL;\n',
872 '}\n',
873 '}\n']
874 # TODO : This code is now too large and complex, need to make codegen smarter for pointers embedded in struct params to handle those cases automatically
875 # TODO138 : Just ripped out a bunch of custom code here that was out of date. Need to scrub these function and verify they're correct
876 custom_case_dict = { #'CreateShader' : {'param': 'pCreateInfo', 'txt': ['VkShaderCreateInfo* pInfo = (VkShaderCreateInfo*)pPacket->pCreateInfo;\n',
877 # 'pInfo->pCode = glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfo->pCode);']},
878 'CreateDynamicViewportState' : {'param': 'pCreateInfo', 'txt': ['VkDynamicViewportStateCreateInfo* pInfo = (VkDynamicViewportStateCreateInfo*)pPacket->pCreateInfo;\n',
879 'pInfo->pViewports = (VkViewport*) glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfo->pViewports);\n',
880 'pInfo->pScissors = (VkRect2D*) glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfo->pScissors);']},
881 #'CreateFramebuffer' : {'param': 'pCreateInfo', 'txt': ['VkFramebufferCreateInfo* pInfo = (VkFramebufferCreateInfo*)pPacket->pCreateInfo;\n',
882 # 'pInfo->pColorAttachments = (VkColorAttachmentBindInfo*) glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfo->pColorAttachments);\n',
883 # 'pInfo->pDepthStencilAttachment = (VkDepthStencilBindInfo*) glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfo->pDepthStencilAttachment);\n']},
884 'CreateRenderPass' : {'param': 'pCreateInfo', 'txt': create_rp_interp},
885 'CreatePipelineLayout' : {'param': 'pCreateInfo', 'txt': ['VkPipelineLayoutCreateInfo* pInfo = (VkPipelineLayoutCreateInfo*)pPacket->pCreateInfo;\n',
886 'pInfo->pSetLayouts = (VkDescriptorSetLayout*) glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfo->pSetLayouts);\n']},
887 'CreateDescriptorPool' : {'param': 'pCreateInfo', 'txt': ['VkDescriptorPoolCreateInfo* pInfo = (VkDescriptorPoolCreateInfo*)pPacket->pCreateInfo;\n',
888 'pInfo->pTypeCount = (VkDescriptorTypeCount*) glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfo->pTypeCount);\n']},
889 'CmdWaitEvents' : {'param': 'ppMemBarriers', 'txt': mem_barrier_interp},
890 'CmdPipelineBarrier' : {'param': 'ppMemBarriers', 'txt': mem_barrier_interp},
891 'CreateDescriptorSetLayout' : {'param': 'pCreateInfo', 'txt': ['if (pPacket->pCreateInfo->sType == VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO) {\n',
892 ' VkDescriptorSetLayoutCreateInfo* pNext = (VkDescriptorSetLayoutCreateInfo*)pPacket->pCreateInfo;\n',
893 ' do\n',' {\n',
894 ' // need to make a non-const pointer to the pointer so that we can properly change the original pointer to the interpretted one\n',
895 ' void** ppNextVoidPtr = (void**)&(pNext->pNext);\n',
896 ' *ppNextVoidPtr = (void*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pNext->pNext);\n',
897 ' switch(pNext->sType)\n', ' {\n',
898 ' case VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO:\n',
899 ' {\n' ,
900 ' unsigned int i = 0;\n',
901 ' pNext->pBinding = (VkDescriptorSetLayoutBinding*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pNext->pBinding);\n',
902 ' for (i = 0; i < pNext->count; i++)\n',' {\n',
903 ' VkSampler** ppSamplers = (VkSampler**)&(pNext->pBinding[i].pImmutableSamplers);\n',
904 ' *ppSamplers = (VkSampler*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pNext->pBinding[i].pImmutableSamplers);\n',
905 ' }\n',
906 ' break;\n',
907 ' }\n',
908 ' default:\n',
909 ' {\n',
910 ' glv_LogError("Encountered an unexpected type in descriptor set layout create list.");\n',
911 ' pPacket->header = NULL;\n',
912 ' pNext->pNext = NULL;\n',
913 ' }\n',
914 ' }\n',
915 ' pNext = (VkDescriptorSetLayoutCreateInfo*)pNext->pNext;\n',
916 ' } while (NULL != pNext);\n',
917 '} else {\n',
918 ' // This is unexpected.\n',
919 ' glv_LogError("CreateDescriptorSetLayout must have pCreateInfo->stype of VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO.");\n',
920 ' pPacket->header = NULL;\n',
921 '}']},
922# 'BeginCommandBuffer' : {'param': 'pBeginInfo', 'txt': ['if (pPacket->pBeginInfo->sType == VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO) {\n',
923# ' // need to make a non-const pointer to the pointer so that we can properly change the original pointer to the interpretted one\n',
924# ' VkCmdBufferGraphicsBeginInfo** ppNext = (VkCmdBufferGraphicsBeginInfo**)&(pPacket->pBeginInfo->pNext);\n',
925# ' *ppNext = (VkCmdBufferGraphicsBeginInfo*) glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pBeginInfo->pNext);\n',
926# ' VkCmdBufferGraphicsBeginInfo* pNext = *ppNext;\n',
927# ' while (NULL != pNext)\n', ' {\n',
928# ' switch(pNext->sType)\n', ' {\n',
929# ' case VK_STRUCTURE_TYPE_CMD_BUFFER_GRAPHICS_BEGIN_INFO:\n',
930# ' {\n',
931# ' ppNext = (VkCmdBufferGraphicsBeginInfo**) &pNext->pNext;\n',
932# ' *ppNext = (VkCmdBufferGraphicsBeginInfo*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pNext->pNext);\n',
933# ' break;\n',
934# ' }\n',
935# ' default:\n',
936# ' {\n',
937# ' glv_LogError("Encountered an unexpected type in begin command buffer list.");\n',
938# ' pPacket->header = NULL;\n',
939# ' pNext->pNext = NULL;\n',
940# ' }\n',
941# ' }\n',
942# ' pNext = (VkCmdBufferGraphicsBeginInfo*)pNext->pNext;\n',
943# ' }\n',
944# '} else {\n',
945# ' // This is unexpected.\n',
946# ' glv_LogError("BeginCommandBuffer must have BeginInfo stype of VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO.");\n',
947# ' pPacket->header = NULL;\n',
948# '}']},
949 'AllocMemory' : {'param': 'pAllocInfo', 'txt': ['if (pPacket->pAllocInfo->sType == VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO) {\n',
950 ' VkMemoryAllocInfo** ppNext = (VkMemoryAllocInfo**) &(pPacket->pAllocInfo->pNext);\n',
951 ' *ppNext = (VkMemoryAllocInfo*) glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pAllocInfo->pNext);\n',
952 ' VkMemoryAllocInfo* pNext = (VkMemoryAllocInfo*) *ppNext;\n',
953 ' while (NULL != pNext)\n', ' {\n',
954 ' switch(pNext->sType)\n', ' {\n',
955 ' default:\n',
956 ' {\n',
957 ' glv_LogError("Encountered an unexpected type alloc memory list.");\n',
958 ' pPacket->header = NULL;\n',
959 ' pNext->pNext = NULL;\n',
960 ' }\n',
961 ' }\n',
962 ' pNext = (VkMemoryAllocInfo*)pNext->pNext;\n',
963 ' }\n',
964 '} else {\n',
965 ' // This is unexpected.\n',
966 ' glv_LogError("AllocMemory must have AllocInfo stype of VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO.");\n',
967 ' pPacket->header = NULL;\n',
968 '}']},
969 'UpdateDescriptorSets' : {'param': 'pDescriptorWrites', 'txt':
970 [ 'uint32_t i;\n',
971 'for (i = 0; i < pPacket->writeCount; i++) {\n',
972 ' VkDescriptorInfo** ppDescriptors = (VkDescriptorInfo**)&pPacket->pDescriptorWrites[i].pDescriptors;\n',
973 ' *ppDescriptors = (VkDescriptorInfo*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pDescriptorWrites[i].pDescriptors);\n',
974 '}'
975 ]},
976 'CreateGraphicsPipelines' : {'param': 'pCreateInfos', 'txt': create_gfx_pipe},
977 'CreateComputePipeline' : {'param': 'pCreateInfo', 'txt': ['interpret_VkPipelineShaderStageCreateInfo(pHeader, (VkPipelineShaderStageCreateInfo*)(&pPacket->pCreateInfo->cs));']},
Jon Ashburn9e8755b2015-08-10 08:53:44 -0600978 'CreateFramebuffer' : {'param': 'pCreateInfo', 'txt': ['VkAttachmentView** ppAV = (VkAttachmentView**)&(pPacket->pCreateInfo->pAttachments);\n',
979 '*ppAV = (VkAttachmentView*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)(pPacket->pCreateInfo->pAttachments));']},
980 'CmdBeginRenderPass' : {'param': 'pRenderPassBegin', 'txt': ['VkClearValue** ppCV = (VkClearValue**)&(pPacket->pRenderPassBegin->pClearValues);\n',
981 '*ppCV = (VkClearValue*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)(pPacket->pRenderPassBegin->pClearValues));']},
Jon Ashburn4d9cfd22015-08-04 13:35:25 -0600982 'CreateShaderModule' : {'param': 'pCreateInfo', 'txt': ['void** ppCode = (void**)&(pPacket->pCreateInfo->pCode);\n',
983 '*ppCode = (void*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfo->pCode);']},
984 'CreateShader' : {'param': 'pCreateInfo', 'txt': ['void** ppName = (void**)&(pPacket->pCreateInfo->pName);\n',
985 '*ppName = (void*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfo->pName);']},
986 'FlushMappedMemoryRanges' : {'param': 'ppData', 'txt': ['uint32_t i = 0;\n',
987 'for (i = 0; i < pPacket->memRangeCount; i++)\n',
988 '{\n',
989 ' pPacket->ppData[i] = (void*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->ppData[i]);\n',
990 '}']}}
991 if_body = []
992 if_body.append('typedef struct packet_vkApiVersion {')
993 if_body.append(' glv_trace_packet_header* header;')
994 if_body.append(' uint32_t version;')
995 if_body.append('} packet_vkApiVersion;\n')
996 if_body.append('static packet_vkApiVersion* interpret_body_as_vkApiVersion(glv_trace_packet_header* pHeader)')
997 if_body.append('{')
998 if_body.append(' packet_vkApiVersion* pPacket = (packet_vkApiVersion*)pHeader->pBody;')
999 if_body.append(' pPacket->header = pHeader;')
1000 if_body.append(' return pPacket;')
1001 if_body.append('}\n')
1002 for proto in self.protos:
1003 if 'WSI' not in proto.name and 'Dbg' not in proto.name:
1004 if 'UnmapMemory' == proto.name:
1005 proto.params.append(vulkan.Param("void*", "pData"))
1006 elif 'FlushMappedMemoryRanges' == proto.name:
1007 proto.params.append(vulkan.Param("void**", "ppData"))
1008 if_body.append('%s' % self.lineinfo.get())
1009 if_body.append('typedef struct packet_vk%s {' % proto.name)
1010 if_body.append(' glv_trace_packet_header* header;')
1011 for p in proto.params:
1012 if_body.append(' %s %s;' % (p.ty, p.name))
1013 if 'void' != proto.ret:
1014 if_body.append(' %s result;' % proto.ret)
1015 if_body.append('} packet_vk%s;\n' % proto.name)
1016 if_body.append('static packet_vk%s* interpret_body_as_vk%s(glv_trace_packet_header* pHeader)' % (proto.name, proto.name))
1017 if_body.append('{')
1018 if_body.append(' packet_vk%s* pPacket = (packet_vk%s*)pHeader->pBody;' % (proto.name, proto.name))
1019 if_body.append(' pPacket->header = pHeader;')
1020 for p in proto.params:
1021 if '*' in p.ty:
1022 if 'DeviceCreateInfo' in p.ty:
1023 if_body.append(' pPacket->%s = interpret_VkDeviceCreateInfo(pHeader, (intptr_t)pPacket->%s);' % (p.name, p.name))
1024 elif 'InstanceCreateInfo' in p.ty:
1025 if_body.append(' pPacket->%s = interpret_VkInstanceCreateInfo(pHeader, (intptr_t)pPacket->%s);' % (p.name, p.name))
1026 else:
1027 if_body.append(' pPacket->%s = (%s)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->%s);' % (p.name, p.ty, p.name))
1028 # TODO : Generalize this custom code to kill dict data struct above.
1029 # Really the point of this block is to catch params w/ embedded ptrs to structs and chains of structs
1030 if proto.name in custom_case_dict and p.name == custom_case_dict[proto.name]['param']:
1031 if_body.append(' if (pPacket->%s != NULL)' % custom_case_dict[proto.name]['param'])
1032 if_body.append(' {')
1033 if_body.append(' %s' % " ".join(custom_case_dict[proto.name]['txt']))
1034 if_body.append(' }')
1035 if_body.append(' return pPacket;')
1036 if_body.append('}\n')
1037 return "\n".join(if_body)
1038
1039 def _generate_interp_funcs_ext(self, extName):
1040 if_body = []
1041 custom_case_dict = { 'QueuePresentWSI' : {'param': 'pPresentInfo', 'txt': ['pPacket->pPresentInfo->swapChains = (VkSwapChainWSI*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)(pPacket->pPresentInfo->swapChains));\n',
1042 'pPacket->pPresentInfo->imageIndices = (uint32_t*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)(pPacket->pPresentInfo->imageIndices));']},
1043 }
Jon Ashburncb622a12015-08-06 17:22:53 -06001044 for ext in vulkan.extensions_all:
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001045 if ext.name.lower() == extName.lower():
1046 for proto in ext.protos:
1047 if_body.append('typedef struct packet_vk%s {' % proto.name)
1048 if_body.append(' glv_trace_packet_header* pHeader;')
1049 for p in proto.params:
1050 if_body.append(' %s %s;' % (p.ty, p.name))
1051 if 'void' != proto.ret:
1052 if_body.append(' %s result;' % proto.ret)
1053 if_body.append('} packet_vk%s;\n' % proto.name)
1054 if_body.append('static packet_vk%s* interpret_body_as_vk%s(glv_trace_packet_header* pHeader)' % (proto.name, proto.name))
1055 if_body.append('{')
1056 if_body.append(' packet_vk%s* pPacket = (packet_vk%s*)pHeader->pBody;' % (proto.name, proto.name))
1057 if_body.append(' pPacket->pHeader = pHeader;')
1058 for p in proto.params:
1059 if '*' in p.ty:
1060 if_body.append(' pPacket->%s = (%s)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->%s);' % (p.name, p.ty, p.name))
1061 # TODO : Generalize this custom code to kill dict data struct above.
1062 # Really the point of this block is to catch params w/ embedded ptrs to structs and chains of structs
1063 if proto.name in custom_case_dict and p.name == custom_case_dict[proto.name]['param']:
1064 if_body.append(' if (pPacket->%s != NULL)' % custom_case_dict[proto.name]['param'])
1065 if_body.append(' {')
1066 if_body.append(' %s' % " ".join(custom_case_dict[proto.name]['txt']))
1067 if_body.append(' }')
1068 if_body.append(' return pPacket;')
1069 if_body.append('}\n')
1070 return "\n".join(if_body)
1071
1072 def _generate_replay_func_ptrs(self):
1073 xf_body = []
1074 xf_body.append('struct vkFuncs {')
1075 xf_body.append(' void init_funcs(void * libHandle);')
1076 xf_body.append(' void *m_libHandle;\n')
1077 for proto in self.protos:
1078 xf_body.append(' typedef %s( VKAPI * type_vk%s)(' % (proto.ret, proto.name))
1079 for p in proto.params:
1080 xf_body.append(' %s %s,' % (p.ty, p.name))
1081 xf_body[-1] = xf_body[-1].replace(',', ');')
1082 xf_body.append(' type_vk%s real_vk%s;' % (proto.name, proto.name))
1083 xf_body.append('};')
1084 return "\n".join(xf_body)
1085
1086 def _map_decl(self, type1, type2, name):
1087 return ' std::map<%s, %s> %s;' % (type1, type2, name)
1088
1089 def _add_to_map_decl(self, type1, type2, name):
1090 txt = ' void add_to_%s_map(%s pTraceVal, %s pReplayVal)\n {\n' % (name[2:], type1, type2)
1091 #TODO138 : These checks need to vary between disp & non-disp objects
1092 #txt += ' assert(pTraceVal != 0);\n'
1093 #txt += ' assert(pReplayVal != 0);\n'
1094 txt += ' %s[pTraceVal] = pReplayVal;\n }\n' % name
1095 return txt
1096
1097 def _rm_from_map_decl(self, ty, name):
1098 txt = ' void rm_from_%s_map(const %s& key)\n {\n' % (name[2:], ty)
1099 txt += ' %s.erase(key);\n }\n' % name
1100 return txt
1101
1102 def _remap_decl(self, ty, name):
1103 txt = ' %s remap_%s(const %s& value)\n {\n' % (ty, name[2:], ty)
1104 txt += ' if (value == 0) { return 0; }\n'
1105 txt += ' std::map<%s, %s>::const_iterator q = %s.find(value);\n' % (ty, ty, name)
1106 txt += ' if (q == %s.end()) { glv_LogError("Failed to remap %s."); return VK_NULL_HANDLE; }\n' % (name, ty)
1107 txt += ' return q->second;\n }\n'
1108 return txt
1109
1110 def _generate_replay_objMemory_funcs(self):
1111 rof_body = []
1112 # Custom code for memory mapping functions for app writes into mapped memory
1113 rof_body.append('// memory mapping functions for app writes into mapped memory')
1114 rof_body.append(' bool isPendingAlloc()')
1115 rof_body.append(' {')
1116 rof_body.append(' return m_pendingAlloc;')
1117 rof_body.append(' }')
1118 rof_body.append('')
1119 rof_body.append(' void setAllocInfo(const VkMemoryAllocInfo *info, const bool pending)')
1120 rof_body.append(' {')
1121 rof_body.append(' m_pendingAlloc = pending;')
1122 rof_body.append(' m_allocInfo = *info;')
1123 rof_body.append(' }')
1124 rof_body.append('')
1125 rof_body.append(' void setMemoryDataAddr(void *pBuf)')
1126 rof_body.append(' {')
1127 rof_body.append(' if (m_mapRange.empty())')
1128 rof_body.append(' {')
1129 rof_body.append(' glv_LogError("gpuMemory::setMemoryDataAddr() m_mapRange is empty.");')
1130 rof_body.append(' return;')
1131 rof_body.append(' }')
1132 rof_body.append(' MapRange mr = m_mapRange.back();')
1133 rof_body.append(' if (mr.pData != NULL)')
1134 rof_body.append(' glv_LogWarning("gpuMemory::setMemoryDataAddr() data already mapped overwrite old mapping.");')
1135 rof_body.append(' else if (pBuf == NULL)')
1136 rof_body.append(' glv_LogWarning("gpuMemory::setMemoryDataAddr() adding NULL pointer.");')
1137 rof_body.append(' mr.pData = (uint8_t *) pBuf;')
1138 rof_body.append(' }')
1139 rof_body.append('')
1140 rof_body.append(' void setMemoryMapRange(void *pBuf, const size_t size, const size_t offset, const bool pending)')
1141 rof_body.append(' {')
1142 rof_body.append(' MapRange mr;')
1143 rof_body.append(' mr.pData = (uint8_t *) pBuf;')
1144 rof_body.append(' if (size == 0)')
1145 rof_body.append(' mr.size = m_allocInfo.allocationSize - offset;')
1146 rof_body.append(' else')
1147 rof_body.append(' mr.size = size;')
1148 rof_body.append(' mr.offset = offset;')
1149 rof_body.append(' mr.pending = pending;')
1150 rof_body.append(' m_mapRange.push_back(mr);')
1151 rof_body.append(' assert(m_allocInfo.allocationSize >= (size + offset));')
1152 rof_body.append(' }')
1153 rof_body.append('')
1154 rof_body.append(' void copyMappingData(const void* pSrcData, bool entire_map, size_t size, size_t offset)')
1155 rof_body.append(' {')
1156 rof_body.append(' if (m_mapRange.empty())')
1157 rof_body.append(' {')
1158 rof_body.append(' glv_LogError("gpuMemory::copyMappingData() m_mapRange is empty.");')
1159 rof_body.append(' return;')
1160 rof_body.append(' }')
1161 rof_body.append(' MapRange mr = m_mapRange.back();')
1162 rof_body.append(' if (!pSrcData || !mr.pData)')
1163 rof_body.append(' {')
1164 rof_body.append(' if (!pSrcData)')
1165 rof_body.append(' glv_LogError("gpuMemory::copyMappingData() null src pointer.");')
1166 rof_body.append(' else')
1167 rof_body.append(' glv_LogError("gpuMemory::copyMappingData() null dest pointer totalSize=%u.", m_allocInfo.allocationSize);')
1168 rof_body.append(' m_mapRange.pop_back();')
1169 rof_body.append(' return;')
1170 rof_body.append(' }')
1171 rof_body.append(' if (entire_map)')
1172 rof_body.append(' {')
1173 rof_body.append(' size = mr.size;')
1174 rof_body.append(' offset = mr.offset;')
1175 rof_body.append(' }')
1176 rof_body.append(' else')
1177 rof_body.append(' {')
1178 rof_body.append(' assert(offset >= mr.offset);')
1179 rof_body.append(' assert(size <= mr.size && (size + offset) <= mr.size);')
1180 rof_body.append(' }')
1181 rof_body.append(' memcpy(mr.pData + offset, pSrcData, size);')
1182 rof_body.append(' if (!mr.pending && entire_map)')
1183 rof_body.append(' m_mapRange.pop_back();')
1184 rof_body.append(' }')
1185 rof_body.append('')
1186 rof_body.append(' size_t getMemoryMapSize()')
1187 rof_body.append(' {')
1188 rof_body.append(' return (!m_mapRange.empty()) ? m_mapRange.back().size : 0;')
1189 rof_body.append(' }\n')
1190 return "\n".join(rof_body)
1191
1192 def _generate_replay_objmapper_class(self):
1193 # Create dict mapping member var names to VK type (i.e. 'm_imageViews' : 'VkImage_VIEW')
1194 obj_map_dict = {}
1195 for obj in vulkan.object_type_list:
Jon Ashburncb622a12015-08-06 17:22:53 -06001196 if (obj.startswith('Vk')):
1197 mem_var = obj.replace('Vk', '').lower()
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001198 mem_var_list = mem_var.split('_')
1199 mem_var = 'm_%s%ss' % (mem_var_list[0], "".join([m.title() for m in mem_var_list[1:]]))
Jon Ashburncb622a12015-08-06 17:22:53 -06001200 obj_map_dict[mem_var] = obj
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001201 rc_body = []
1202 rc_body.append('#define GLV_VK_OBJECT_TYPE_UNKNOWN (VkObjectType)-1')
1203 rc_body.append('')
1204 rc_body.append('typedef struct _VKAllocInfo {')
1205 rc_body.append(' VkDeviceSize size;')
1206 rc_body.append(' uint8_t *pData;')
1207 rc_body.append(' bool rangeUpdated;')
1208 rc_body.append('} VKAllocInfo;')
1209 rc_body.append('')
1210 rc_body.append('class objMemory {')
1211 rc_body.append('public:')
1212 rc_body.append(' objMemory() : m_numAllocations(0), m_pMemReqs(NULL) {}')
1213 rc_body.append(' ~objMemory() { free(m_pMemReqs);}')
1214 rc_body.append(' void setCount(const uint32_t num)')
1215 rc_body.append(' {')
1216 rc_body.append(' m_numAllocations = num;')
1217 rc_body.append(' }\n')
1218 rc_body.append(' void setReqs(const VkMemoryRequirements *pReqs, const uint32_t num)')
1219 rc_body.append(' {')
1220 rc_body.append(' if (m_numAllocations != num && m_numAllocations != 0)')
1221 rc_body.append(' glv_LogError("objMemory::setReqs, internal mismatch on number of allocations.");')
1222 rc_body.append(' if (m_pMemReqs == NULL && pReqs != NULL)')
1223 rc_body.append(' {')
1224 rc_body.append(' m_pMemReqs = (VkMemoryRequirements *) glv_malloc(num * sizeof(VkMemoryRequirements));')
1225 rc_body.append(' if (m_pMemReqs == NULL)')
1226 rc_body.append(' {')
1227 rc_body.append(' glv_LogError("objMemory::setReqs out of memory.");')
1228 rc_body.append(' return;')
1229 rc_body.append(' }')
1230 rc_body.append(' memcpy(m_pMemReqs, pReqs, num * sizeof(VkMemoryRequirements));')
1231 rc_body.append(' }')
1232 rc_body.append(' }\n')
1233 rc_body.append('private:')
1234 rc_body.append(' uint32_t m_numAllocations;')
1235 rc_body.append(' VkMemoryRequirements *m_pMemReqs;')
1236 rc_body.append('};')
1237 rc_body.append('')
1238 rc_body.append('class gpuMemory {')
1239 rc_body.append('public:')
1240 rc_body.append(' gpuMemory() : m_pendingAlloc(false) {m_allocInfo.allocationSize = 0;}')
1241 rc_body.append(' ~gpuMemory() {}')
1242 rc_body.append(self._generate_replay_objMemory_funcs())
1243 rc_body.append('private:')
1244 rc_body.append(' bool m_pendingAlloc;')
1245 rc_body.append(' struct MapRange {')
1246 rc_body.append(' bool pending;')
1247 rc_body.append(' size_t size;')
1248 rc_body.append(' size_t offset;')
1249 rc_body.append(' uint8_t* pData;')
1250 rc_body.append(' };')
1251 rc_body.append(' std::vector<MapRange> m_mapRange;')
1252 rc_body.append(' VkMemoryAllocInfo m_allocInfo;')
1253 rc_body.append('};')
1254 rc_body.append('')
1255 rc_body.append('typedef struct _imageObj {')
1256 rc_body.append(' objMemory imageMem;')
1257 rc_body.append(' VkImage replayImage;')
1258 rc_body.append(' } imageObj;')
1259 rc_body.append('')
1260 rc_body.append('typedef struct _bufferObj {')
1261 rc_body.append(' objMemory bufferMem;')
1262 rc_body.append(' VkBuffer replayBuffer;')
1263 rc_body.append(' } bufferObj;')
1264 rc_body.append('')
1265 rc_body.append('typedef struct _gpuMemObj {')
1266 rc_body.append(' gpuMemory *pGpuMem;')
1267 rc_body.append(' VkDeviceMemory replayGpuMem;')
1268 rc_body.append(' } gpuMemObj;')
1269 rc_body.append('')
1270 rc_body.append('')
1271 rc_body.append('class vkReplayObjMapper {')
1272 rc_body.append('public:')
1273 rc_body.append(' vkReplayObjMapper() {}')
1274 rc_body.append(' ~vkReplayObjMapper() {}')
1275 rc_body.append('')
1276 rc_body.append(' bool m_adjustForGPU; // true if replay adjusts behavior based on GPU')
1277 # Code for memory objects for handling replay GPU != trace GPU object memory requirements
1278 rc_body.append('void init_objMemCount(const uint64_t handle, const VkDbgObjectType objectType, const uint32_t &num)\n {')
1279 rc_body.append(' switch (objectType) {')
1280 rc_body.append(' case VK_OBJECT_TYPE_BUFFER:')
1281 rc_body.append(' {')
1282 rc_body.append(' std::map<uint64_t, bufferObj>::iterator it = m_buffers.find(handle);')
1283 rc_body.append(' if (it != m_buffers.end()) {')
1284 rc_body.append(' objMemory obj = it->second.bufferMem;')
1285 rc_body.append(' obj.setCount(num);')
1286 rc_body.append(' return;')
1287 rc_body.append(' }')
1288 rc_body.append(' break;')
1289 rc_body.append(' }')
1290 rc_body.append(' case VK_OBJECT_TYPE_IMAGE:')
1291 rc_body.append(' {')
1292 rc_body.append(' std::map<uint64_t, imageObj>::iterator it = m_images.find(handle);')
1293 rc_body.append(' if (it != m_images.end()) {')
1294 rc_body.append(' objMemory obj = it->second.imageMem;')
1295 rc_body.append(' obj.setCount(num);')
1296 rc_body.append(' return;')
1297 rc_body.append(' }')
1298 rc_body.append(' break;')
1299 rc_body.append(' }')
1300 rc_body.append(' default:')
1301 rc_body.append(' break;')
1302 rc_body.append(' }')
1303 rc_body.append(' return;')
1304 rc_body.append('}\n')
1305 rc_body.append('void init_objMemReqs(const uint64_t handle, const VkDbgObjectType objectType, const VkMemoryRequirements *pMemReqs, const unsigned int num)\n {')
1306 rc_body.append(' switch (objectType) {')
1307 rc_body.append(' case VK_OBJECT_TYPE_BUFFER:')
1308 rc_body.append(' {')
1309 rc_body.append(' std::map<uint64_t, bufferObj>::iterator it = m_buffers.find(handle);')
1310 rc_body.append(' if (it != m_buffers.end()) {')
1311 rc_body.append(' objMemory obj = it->second.bufferMem;')
1312 rc_body.append(' obj.setReqs(pMemReqs, num);')
1313 rc_body.append(' return;')
1314 rc_body.append(' }')
1315 rc_body.append(' break;')
1316 rc_body.append(' }')
1317 rc_body.append(' case VK_OBJECT_TYPE_IMAGE:')
1318 rc_body.append(' {')
1319 rc_body.append(' std::map<uint64_t, imageObj>::iterator it = m_images.find(handle);')
1320 rc_body.append(' if (it != m_images.end()) {')
1321 rc_body.append(' objMemory obj = it->second.imageMem;')
1322 rc_body.append(' obj.setReqs(pMemReqs, num);')
1323 rc_body.append(' return;')
1324 rc_body.append(' }')
1325 rc_body.append(' break;')
1326 rc_body.append(' }')
1327 rc_body.append(' default:')
1328 rc_body.append(' break;')
1329 rc_body.append(' }')
1330 rc_body.append(' return;')
1331 rc_body.append(' }')
1332 rc_body.append('')
1333 rc_body.append(' void clear_all_map_handles()\n {')
1334 for var in sorted(obj_map_dict):
1335 rc_body.append(' %s.clear();' % var)
1336 rc_body.append(' }\n')
Jon Ashburncb622a12015-08-06 17:22:53 -06001337 disp_obj_types = [obj for obj in vulkan.object_dispatch_list]
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001338 for var in sorted(obj_map_dict):
1339 # Disp objs are pts so the obj can be map key, for non-disp objs, use uint64_t handle as map key
1340 if obj_map_dict[var] in disp_obj_types:
1341 rc_body.append(self._map_decl(obj_map_dict[var], obj_map_dict[var], var))
1342 rc_body.append(self._add_to_map_decl(obj_map_dict[var], obj_map_dict[var], var))
1343 rc_body.append(self._rm_from_map_decl(obj_map_dict[var], var))
1344 rc_body.append(self._remap_decl(obj_map_dict[var], var))
1345 elif obj_map_dict[var] == 'VkImage':
1346 rc_body.append(self._map_decl('uint64_t', 'imageObj', var))
1347 rc_body.append(self._add_to_map_decl('uint64_t', 'imageObj', var))
1348 rc_body.append(self._rm_from_map_decl('uint64_t', var))
1349 rc_body.append(' uint64_t remap_images(const uint64_t& value)')
1350 rc_body.append(' {')
1351 rc_body.append(' if (value == 0) { return 0; }')
1352 rc_body.append('')
1353 rc_body.append(' std::map<uint64_t, imageObj>::const_iterator q = m_images.find(value);')
1354 rc_body.append(' if (q == m_images.end()) { glv_LogError("Failed to remap VkImage."); return VK_NULL_HANDLE; }\n')
1355 rc_body.append(' return q->second.replayImage.handle;')
1356 rc_body.append(' }\n')
1357 elif obj_map_dict[var] == 'VkBuffer':
1358 rc_body.append(self._map_decl('uint64_t', 'bufferObj', var))
1359 rc_body.append(self._add_to_map_decl('uint64_t', 'bufferObj', var))
1360 rc_body.append(self._rm_from_map_decl('uint64_t', var))
1361 rc_body.append(' uint64_t remap_buffers(const uint64_t& value)')
1362 rc_body.append(' {')
1363 rc_body.append(' if (value == 0) { return 0; }')
1364 rc_body.append('')
1365 rc_body.append(' std::map<uint64_t, bufferObj>::const_iterator q = m_buffers.find(value);')
1366 rc_body.append(' if (q == m_buffers.end()) { glv_LogError("Failed to remap VkBuffer."); return VK_NULL_HANDLE; }\n')
1367 rc_body.append(' return q->second.replayBuffer.handle;')
1368 rc_body.append(' }\n')
1369 elif obj_map_dict[var] == 'VkDeviceMemory':
1370 rc_body.append(self._map_decl('uint64_t', 'gpuMemObj', var))
1371 rc_body.append(self._add_to_map_decl('uint64_t', 'gpuMemObj', var))
1372 rc_body.append(self._rm_from_map_decl('uint64_t', var))
1373 rc_body.append(' uint64_t remap_devicememorys(const uint64_t& value)')
1374 rc_body.append(' {')
1375 rc_body.append(' if (value == 0) { return 0; }')
1376 rc_body.append('')
1377 rc_body.append(' std::map<uint64_t, gpuMemObj>::const_iterator q = m_devicememorys.find(value);')
1378 rc_body.append(' if (q == m_devicememorys.end()) { glv_LogError("Failed to remap VkDeviceMemory."); return VK_NULL_HANDLE; }')
1379 rc_body.append(' return q->second.replayGpuMem.handle;')
1380 rc_body.append(' }\n')
1381 else:
1382 rc_body.append(self._map_decl('uint64_t', 'uint64_t', var))
1383 rc_body.append(self._add_to_map_decl('uint64_t', 'uint64_t', var))
1384 rc_body.append(self._rm_from_map_decl('uint64_t', var))
1385 rc_body.append(self._remap_decl('uint64_t', var))
1386 # VkDynamicStateObject code
1387# TODO138 : Each dynamic state object is now unique so need to make sure their re-mapping is being handled correctly
1388# state_obj_remap_types = vulkan.object_dynamic_state_list
1389# state_obj_bindings = vulkan.object_dynamic_state_bind_point_list
1390# rc_body.append(' VkDynamicStateObject remap(const VkDynamicStateObject& state, const VkStateBindPoint& bindPoint)\n {')
1391# rc_body.append(' VkDynamicStateObject obj;')
1392# index = 0
1393# while index < len(state_obj_remap_types):
1394# obj = state_obj_remap_types[index]
1395# type = state_obj_bindings[index]
1396# rc_body.append(' if (bindPoint == %s) {' % type)
1397# rc_body.append(' if ((obj = remap(static_cast <%s> (state))) != VK_NULL_HANDLE)' % obj.type)
1398# rc_body.append(' return obj;')
1399# rc_body.append(' }')
1400# index += 1
1401# for obj in state_obj_remap_types:
1402# rc_body.append('// if ((obj = remap(static_cast <%s> (state))) != VK_NULL_HANDLE)' % obj.type)
1403# rc_body.append('// return obj;')
1404# rc_body.append(' glv_LogWarning("Failed to remap VkDynamicStateObject.");')
1405# rc_body.append(' return VK_NULL_HANDLE;\n }')
1406# rc_body.append(' void rm_from_map(const VkDynamicStateObject& state)\n {')
1407# for obj in state_obj_remap_types:
1408# rc_body.append(' rm_from_map(static_cast <%s> (state));' % obj.type)
1409# rc_body.append(' }')
1410# rc_body.append('')
1411 # OBJECT code
1412# TODO138 : VkObject construct is now dead, and I believe this code can die with it
1413# rc_body.append(' VkObject remap(const VkObject& object, VkObjectType objectType)\n {')
1414# rc_body.append(' VkObject obj = VK_NULL_HANDLE;')
1415# obj_remap_types = vulkan.object_type_list
1416# rc_body.append(' switch ((unsigned int)objectType) {')
1417# for obj in obj_remap_types:
1418# if obj.type not in vulkan.object_parent_list:
1419# rc_body.append(' case %s:' % obj.enum)
1420# rc_body.append(' obj = remap(static_cast <%s> (object));' % obj.type)
1421# rc_body.append(' break;')
1422# rc_body.append(' case GLV_VK_OBJECT_TYPE_UNKNOWN:')
1423# rc_body.append(' default:')
1424# rc_body.append(' obj = VK_NULL_HANDLE;')
1425# rc_body.append(' break;')
1426# rc_body.append(' }\n')
1427# rc_body.append(' if (obj == VK_NULL_HANDLE)')
1428# rc_body.append(' {')
1429# for obj in obj_remap_types:
1430# if obj.type not in vulkan.object_parent_list:
1431# rc_body.append(' if ((obj = remap(static_cast <%s> (object))) != VK_NULL_HANDLE) return obj;' % obj.type)
1432# rc_body.append(' glv_LogError("Failed to remap VkObject.");')
1433# rc_body.append(' }')
1434# rc_body.append(' return obj;')
1435# rc_body.append(' }')
1436# rc_body.append('')
1437# rc_body.append(' void rm_from_map(const VkObject& objKey, VkObjectType objectType)\n {')
1438# rc_body.append(' switch ((unsigned int)objectType) {')
1439# for obj in obj_remap_types:
1440# if obj.type not in vulkan.object_parent_list:
1441# rc_body.append(' case %s:' % obj.enum)
1442# rc_body.append(' rm_from_map(static_cast <%s> (objKey));' % (obj.type))
1443# rc_body.append(' break;')
1444# rc_body.append(' default:')
1445# rc_body.append(' assert(!"Unhandled or invalid VkObjectType passed into rm_from_map(..)");')
1446# rc_body.append(' break;')
1447# rc_body.append(' }')
1448# rc_body.append(' }')
1449 rc_body.append('};')
1450 return "\n".join(rc_body)
1451
1452 def _generate_replay_init_funcs(self):
1453 rif_body = []
1454 rif_body.append('void vkFuncs::init_funcs(void * handle)\n{\n m_libHandle = handle;')
1455 for proto in self.protos:
1456 if 'WSI' not in proto.name and 'Dbg' not in proto.name:
1457 rif_body.append(' real_vk%s = (type_vk%s)(glv_platform_get_library_entrypoint(handle, "vk%s"));' % (proto.name, proto.name, proto.name))
1458 else: # These func ptrs get assigned at GetProcAddr time
1459 rif_body.append(' real_vk%s = (type_vk%s)NULL;' % (proto.name, proto.name))
1460 rif_body.append('}')
1461 return "\n".join(rif_body)
1462
1463 def _remap_packet_param(self, funcName, paramType, paramName):
1464 remap_list = vulkan.object_type_list
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001465 param_exclude_list = ['pDescriptorSets', 'pFences']
1466 cleanParamType = paramType.strip('*').replace('const ', '')
Jon Ashburncb622a12015-08-06 17:22:53 -06001467 VulkNonDispObjects = [o for o in vulkan.object_non_dispatch_list]
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001468 for obj in remap_list:
Jon Ashburncb622a12015-08-06 17:22:53 -06001469 if obj == cleanParamType and paramName not in param_exclude_list:
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001470 objectTypeRemapParam = ''
1471 if 'VkDynamicStateObject' == cleanParamType:
1472 objectTypeRemapParam = ', pPacket->stateBindPoint'
1473 elif 'object' == paramName:
1474 if 'DbgSetObjectTag' == funcName:
1475 objectTypeRemapParam = ', GLV_VK_OBJECT_TYPE_UNKNOWN'
1476 else:
1477 objectTypeRemapParam = ', pPacket->objType'
1478 elif 'srcObject' == paramName and 'Callback' in funcName:
1479 objectTypeRemapParam = ', pPacket->objType'
1480 if '*' in paramType:
1481 if 'const ' not in paramType:
1482 result = ' %s remapped%s = m_objMapper.remap_%ss(*pPacket->%s%s);\n' % (cleanParamType, paramName, paramName.lower(), paramName, objectTypeRemapParam)
1483 result += ' if (pPacket->%s != VK_NULL_HANDLE && remapped%s == VK_NULL_HANDLE)\n' % (paramName, paramName)
1484 result += ' {\n'
1485 result += ' return glv_replay::GLV_REPLAY_ERROR;\n'
1486 result += ' }\n'
1487 return result
1488 else: # TODO : Don't remap array ptrs?
1489 return ' // pPacket->%s should have been remapped with special case code' % (paramName)
1490 if paramType in VulkNonDispObjects:
1491 result = ' %s remapped%s;\n' % (paramType, paramName)
1492 result += ' remapped%s.handle = m_objMapper.remap_%ss(pPacket->%s%s.handle);\n' % (paramName, cleanParamType.lower()[2:], paramName, objectTypeRemapParam)
1493 result += '%s\n' % self.lineinfo.get()
1494 result += ' if (pPacket->%s.handle != 0 && remapped%s.handle == 0)\n' % (paramName, paramName)
1495 result += ' {\n'
1496 result += ' return glv_replay::GLV_REPLAY_ERROR;\n'
1497 result += ' }\n'
1498 else:
1499 result = ' %s remapped%s = m_objMapper.remap_%ss(pPacket->%s%s);\n' % (paramType, paramName, cleanParamType.lower()[2:], paramName, objectTypeRemapParam)
1500 result += '%s\n' % self.lineinfo.get()
1501 result += ' if (pPacket->%s != VK_NULL_HANDLE && remapped%s == VK_NULL_HANDLE)\n' % (paramName, paramName)
1502 result += ' {\n'
1503 result += ' return glv_replay::GLV_REPLAY_ERROR;\n'
1504 result += ' }\n'
1505 return result
1506 return ' // No need to remap %s' % (paramName)
1507
1508 def _get_packet_param(self, funcName, paramType, paramName):
1509 # list of types that require remapping
1510 remap_list = vulkan.object_type_list
1511 param_exclude_list = ['pDescriptorSets', 'pFences']
1512 cleanParamType = paramType.strip('*').replace('const ', '')
1513 for obj in remap_list:
Jon Ashburncb622a12015-08-06 17:22:53 -06001514 if obj == cleanParamType and paramName not in param_exclude_list:
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001515 objectTypeRemapParam = ''
1516 if 'object' == paramName:
1517 if 'DbgSetObjectTag' == funcName:
1518 objectTypeRemapParam = ', GLV_VK_OBJECT_TYPE_UNKNOWN'
1519 else:
1520 objectTypeRemapParam = ', pPacket->objType'
1521 if '*' in paramType:
1522 if 'const ' not in paramType:
1523 return 'remapped%s' % (paramName)
1524 else: # TODO : Don't remap array ptrs?
1525 return 'pPacket->%s' % (paramName)
1526 return 'remapped%s' % (paramName)
1527 return 'pPacket->%s' % (paramName)
1528
1529 def _gen_replay_create_image(self):
1530 ci_body = []
1531 ci_body.append(' imageObj local_imageObj;')
1532 ci_body.append(' VkDevice remappedDevice = m_objMapper.remap_devices(pPacket->device);')
1533 ci_body.append(' if (remappedDevice == VK_NULL_HANDLE)')
1534 ci_body.append(' {')
1535 ci_body.append(' return glv_replay::GLV_REPLAY_ERROR;')
1536 ci_body.append(' }')
1537 ci_body.append(' replayResult = m_vkFuncs.real_vkCreateImage(remappedDevice, pPacket->pCreateInfo, &local_imageObj.replayImage);')
1538 ci_body.append(' if (replayResult == VK_SUCCESS)')
1539 ci_body.append(' {')
1540 ci_body.append(' m_objMapper.add_to_images_map(pPacket->pImage->handle, local_imageObj);')
1541 ci_body.append(' }')
1542 return "\n".join(ci_body)
1543
1544 def _gen_replay_create_buffer(self):
1545 cb_body = []
1546 cb_body.append(' bufferObj local_bufferObj;')
1547 cb_body.append(' VkDevice remappedDevice = m_objMapper.remap_devices(pPacket->device);')
1548 cb_body.append(' if (remappedDevice == VK_NULL_HANDLE)')
1549 cb_body.append(' {')
1550 cb_body.append(' return glv_replay::GLV_REPLAY_ERROR;')
1551 cb_body.append(' }')
1552 cb_body.append(' replayResult = m_vkFuncs.real_vkCreateBuffer(remappedDevice, pPacket->pCreateInfo, &local_bufferObj.replayBuffer);')
1553 cb_body.append(' if (replayResult == VK_SUCCESS)')
1554 cb_body.append(' {')
1555 cb_body.append(' m_objMapper.add_to_buffers_map(pPacket->pBuffer->handle, local_bufferObj);')
1556 cb_body.append(' }')
1557 return "\n".join(cb_body)
1558
1559 # Generate main replay case statements where actual replay API call is dispatched based on input packet data
1560 def _generate_replay(self):
1561 manually_replay_funcs = ['AllocMemory',
1562 'BeginCommandBuffer',
1563 'CreateDescriptorSetLayout',
1564 'CreateDevice',
1565 'CreateFramebuffer',
1566 'CreateGraphicsPipelines',
1567 'CreateInstance',
1568 'CreatePipelineLayout',
1569 'CreateRenderPass',
1570 'CreateShader',
1571 'CmdBeginRenderPass',
1572 'CmdBindDescriptorSets',
1573 'CmdBindVertexBuffers',
1574 'CmdPipelineBarrier',
1575 'QueuePresentWSI',
1576 'CmdWaitEvents',
1577 #'DestroyObject',
1578 'EnumeratePhysicalDevices',
1579 'FreeMemory',
1580 'FreeDescriptorSets',
1581 'FlushMappedMemoryRanges',
1582 #'GetGlobalExtensionInfo',
1583 #'GetImageSubresourceInfo',
1584 #'GetObjectInfo',
1585 #'GetPhysicalDeviceExtensionInfo',
1586 'GetPhysicalDeviceSurfaceSupportWSI',
1587 'GetSurfaceInfoWSI',
1588 'CreateSwapChainWSI',
1589 'GetSwapChainInfoWSI',
1590 #'GetPhysicalDeviceInfo',
1591 'MapMemory',
1592 #'QueuePresentWSI',
1593 'QueueSubmit',
1594 #'StorePipeline',
1595 'UnmapMemory',
1596 'UpdateDescriptorSets',
1597 'WaitForFences',
1598 #'DbgCreateMsgCallback',
1599 #'DbgDestroyMsgCallback',
1600 'CreateCommandBuffer',
1601 ]
1602 skip_funcs = ['DbgCreateMsgCallback',
1603 'DbgDestroyMsgCallback',
1604 ]
1605
1606 # validate the manually_replay_funcs list
1607 protoFuncs = [proto.name for proto in self.protos]
1608 for func in manually_replay_funcs:
1609 if func not in protoFuncs:
1610 sys.exit("Entry '%s' in manually_replay_funcs list is not in the vulkan function prototypes" % func)
1611
1612 # map protos to custom functions if body is fully custom
1613 custom_body_dict = {'CreateImage': self._gen_replay_create_image,
1614 'CreateBuffer': self._gen_replay_create_buffer }
1615 # multi-gpu Open funcs w/ list of local params to create
1616 custom_open_params = {'OpenSharedMemory': (-1,),
1617 'OpenSharedSemaphore': (-1,),
1618 'OpenPeerMemory': (-1,),
1619 'OpenPeerImage': (-1, -2,)}
1620 # Functions that create views are unique from other create functions
1621 create_view_list = ['CreateBufferView', 'CreateImageView', 'CreateAttachmentView', 'CreateComputePipeline']
1622 # Functions to treat as "Create' that don't have 'Create' in the name
1623 special_create_list = ['LoadPipeline', 'LoadPipelineDerivative', 'AllocMemory', 'GetDeviceQueue', 'PinSystemMemory', 'AllocDescriptorSets']
1624 # A couple funcs use do while loops
1625 do_while_dict = {'GetFenceStatus': 'replayResult != pPacket->result && pPacket->result == VK_SUCCESS', 'GetEventStatus': '(pPacket->result == VK_EVENT_SET || pPacket->result == VK_EVENT_RESET) && replayResult != pPacket->result'}
1626 rbody = []
1627 rbody.append('%s' % self.lineinfo.get())
1628 rbody.append('glv_replay::GLV_REPLAY_RESULT vkReplay::replay(glv_trace_packet_header *packet)')
1629 rbody.append('{')
1630 rbody.append(' glv_replay::GLV_REPLAY_RESULT returnValue = glv_replay::GLV_REPLAY_SUCCESS;')
1631 rbody.append(' VkResult replayResult = VK_ERROR_UNKNOWN;')
1632 rbody.append(' switch (packet->packet_id)')
1633 rbody.append(' {')
1634 rbody.append(' case GLV_TPI_VK_vkApiVersion:')
1635 rbody.append(' {')
1636 rbody.append(' packet_vkApiVersion* pPacket = (packet_vkApiVersion*)(packet->pBody);')
1637 rbody.append(' if (pPacket->version != VK_API_VERSION)')
1638 rbody.append(' {')
1639 rbody.append(' glv_LogError("Trace file is from Vulkan version 0x%x (%u.%u.%u), but the glave plugin only supports version 0x%x (%u.%u.%u).", pPacket->version, (pPacket->version & 0xFFC00000) >> 22, (pPacket->version & 0x003FF000) >> 12, (pPacket->version & 0x00000FFF), VK_API_VERSION, (VK_API_VERSION & 0xFFC00000) >> 22, (VK_API_VERSION & 0x003FF000) >> 12, (VK_API_VERSION & 0x00000FFF));')
1640 rbody.append(' returnValue = glv_replay::GLV_REPLAY_ERROR;')
1641 rbody.append(' }')
1642 rbody.append(' break;')
1643 rbody.append(' }')
1644 for proto in self.protos:
1645 if proto.name in skip_funcs:
1646 continue
1647 ret_value = False
1648 create_view = False
1649 create_func = False
1650 # TODO : How to handle void* return of GetProcAddr?
1651 if ('void' not in proto.ret.lower()) and ('size_t' not in proto.ret) and (proto.name not in custom_body_dict):
1652 ret_value = True
1653 if proto.name in create_view_list:
1654 create_view = True
1655 elif 'Create' in proto.name or proto.name in special_create_list:
1656 create_func = True
1657 rbody.append(' case GLV_TPI_VK_vk%s:' % proto.name)
1658 rbody.append(' {')
1659 rbody.append(' packet_vk%s* pPacket = (packet_vk%s*)(packet->pBody);' % (proto.name, proto.name))
1660 if proto.name in manually_replay_funcs:
1661 if ret_value == True:
1662 rbody.append(' replayResult = manually_replay_vk%s(pPacket);' % proto.name)
1663 else:
1664 rbody.append(' manually_replay_vk%s(pPacket);' % proto.name)
1665 elif proto.name in custom_body_dict:
1666 rbody.append(custom_body_dict[proto.name]())
1667 else:
1668 if proto.name in custom_open_params:
1669 for pidx in custom_open_params[proto.name]:
1670 rbody.append(' %s local_%s;' % (proto.params[pidx].ty.replace('const ', '').strip('*'), proto.params[pidx].name))
1671 elif create_view:
1672 rbody.append(' %s createInfo;' % (proto.params[1].ty.strip('*').replace('const ', '')))
1673 rbody.append(' memcpy(&createInfo, pPacket->pCreateInfo, sizeof(%s));' % (proto.params[1].ty.strip('*').replace('const ', '')))
1674 if 'CreateComputePipeline' == proto.name:
1675 rbody.append(' createInfo.cs.shader.handle = m_objMapper.remap_shaders(pPacket->pCreateInfo->cs.shader.handle);')
1676 elif 'CreateBufferView' == proto.name:
1677 rbody.append(' createInfo.buffer.handle = m_objMapper.remap_buffers(pPacket->pCreateInfo->buffer.handle);')
1678 else:
1679 rbody.append(' createInfo.image.handle = m_objMapper.remap_images(pPacket->pCreateInfo->image.handle);')
1680 rbody.append(' %s local_%s;' % (proto.params[-1].ty.strip('*').replace('const ', ''), proto.params[-1].name))
1681 elif create_func: # Declare local var to store created handle into
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001682 if 'AllocDescriptorSets' == proto.name:
Jon Ashburn9e8755b2015-08-10 08:53:44 -06001683 p_ty = proto.params[-1].ty.strip('*').replace('const ', '')
1684 rbody.append(' %s* local_%s = (%s*)malloc(pPacket->count * sizeof(%s));' % (p_ty, proto.params[-1].name, p_ty, p_ty))
1685 rbody.append(' VkDescriptorSetLayout* local_pSetLayouts = (VkDescriptorSetLayout*)malloc(pPacket->count * sizeof(VkDescriptorSetLayout));')
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001686 rbody.append(' for (uint32_t i = 0; i < pPacket->count; i++)')
1687 rbody.append(' {')
Jon Ashburn9e8755b2015-08-10 08:53:44 -06001688 rbody.append(' local_pSetLayouts[i].handle = m_objMapper.remap_descriptorsetlayouts(pPacket->%s[i].handle);' % (proto.params[-2].name))
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001689 rbody.append(' }')
Jon Ashburn9e8755b2015-08-10 08:53:44 -06001690 else:
1691 rbody.append(' %s local_%s;' % (proto.params[-1].ty.strip('*').replace('const ', ''), proto.params[-1].name))
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001692 elif proto.name == 'ResetFences':
1693 rbody.append(' VkFence* fences = GLV_NEW_ARRAY(VkFence, pPacket->fenceCount);')
1694 rbody.append(' for (uint32_t i = 0; i < pPacket->fenceCount; i++)')
1695 rbody.append(' {')
1696 rbody.append(' fences[i].handle = m_objMapper.remap_fences(pPacket->%s[i].handle);' % (proto.params[-1].name))
1697 rbody.append(' }')
1698 elif proto.name in do_while_dict:
1699 rbody.append(' do {')
1700
1701 for p in proto.params:
1702 if create_func or create_view:
1703 if p.name != proto.params[-1].name:
1704 rbody.append(self._remap_packet_param(proto.name, p.ty, p.name))
1705 else:
1706 rbody.append(self._remap_packet_param(proto.name, p.ty, p.name))
1707
1708 if proto.name == 'DestroyInstance':
1709 rbody.append(' if (m_vkFuncs.real_vkDbgDestroyMsgCallback != NULL)')
1710 rbody.append(' {')
1711 rbody.append(' m_vkFuncs.real_vkDbgDestroyMsgCallback(remappedinstance, m_dbgMsgCallbackObj);')
1712 rbody.append(' }')
1713 # TODO: need a better way to indicate which extensions should be mapped to which Get*ProcAddr
1714 elif proto.name == 'GetInstanceProcAddr':
1715 for iProto in self.protos:
1716 if 'Dbg' in iProto.name or 'GetPhysicalDeviceSurfaceSupportWSI' in iProto.name:
1717 rbody.append(' if (strcmp(pPacket->pName, "vk%s") == 0) {' % (iProto.name))
1718 rbody.append(' m_vkFuncs.real_vk%s = (PFN_vk%s)vk%s(remappedinstance, pPacket->pName);' % (iProto.name, iProto.name, proto.name))
1719 rbody.append(' }')
1720 elif proto.name == 'GetDeviceProcAddr':
1721 for dProto in self.protos:
1722 if 'WSI' in dProto.name:
1723 rbody.append(' if (strcmp(pPacket->pName, "vk%s") == 0) {' % (dProto.name))
1724 rbody.append(' m_vkFuncs.real_vk%s = (PFN_vk%s)vk%s(remappeddevice, pPacket->pName);' % (dProto.name, dProto.name, proto.name))
1725 rbody.append(' }')
1726
1727 # build the call to the "real_" entrypoint
1728 rr_string = ' '
1729 if ret_value:
1730 rr_string = ' replayResult = '
1731 rr_string += 'm_vkFuncs.real_vk%s(' % proto.name
1732 for p in proto.params:
1733 # For last param of Create funcs, pass address of param
1734 if create_func:
Jon Ashburn9e8755b2015-08-10 08:53:44 -06001735 if proto.name == 'AllocDescriptorSets' and ((p.name == proto.params[-2].name) or (p.name == proto.params[-1].name)):
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001736 rr_string += 'local_%s, ' % p.name
Jon Ashburn9e8755b2015-08-10 08:53:44 -06001737 elif p.name == proto.params[-1].name:
1738 rr_string += '&local_%s, ' % p.name
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001739 else:
1740 rr_string += '%s, ' % self._get_packet_param(proto.name, p.ty, p.name)
1741 else:
1742 rr_string += '%s, ' % self._get_packet_param(proto.name, p.ty, p.name)
1743 rr_string = '%s);' % rr_string[:-2]
1744 if proto.name in custom_open_params:
1745 rr_list = rr_string.split(', ')
1746 for pidx in custom_open_params[proto.name]:
1747 rr_list[pidx] = '&local_%s' % proto.params[pidx].name
1748 rr_string = ', '.join(rr_list)
1749 rr_string += ');'
1750 elif create_view:
1751 rr_list = rr_string.split(', ')
1752 rr_list[-2] = '&createInfo'
1753 rr_list[-1] = '&local_%s);' % proto.params[-1].name
1754 rr_string = ', '.join(rr_list)
1755 # this is a sneaky shortcut to use generic create code below to add_to_map
1756 create_func = True
1757 elif proto.name == 'AllocDescriptorSets':
1758 rr_string = rr_string.replace('pPacket->pSetLayouts', 'pLocalDescSetLayouts')
1759 elif proto.name == 'ResetFences':
1760 rr_string = rr_string.replace('pPacket->pFences', 'fences')
1761
1762 # insert the real_*(..) call
1763 rbody.append(rr_string)
1764
1765 # handle return values or anything that needs to happen after the real_*(..) call
1766 if 'DestroyDevice' in proto.name:
1767 rbody.append(' if (replayResult == VK_SUCCESS)')
1768 rbody.append(' {')
1769 rbody.append(' m_pCBDump = NULL;')
1770 rbody.append(' m_pDSDump = NULL;')
1771 #TODO138 : disabling snapshot
1772 #rbody.append(' m_pGlvSnapshotPrint = NULL;')
1773 rbody.append(' m_objMapper.rm_from_devices_map(pPacket->device);')
1774 rbody.append(' m_display->m_initedVK = false;')
1775 rbody.append(' }')
1776 elif 'DestroySwapChainWSI' in proto.name:
1777 rbody.append(' if (replayResult == VK_SUCCESS)')
1778 rbody.append(' {')
1779 rbody.append(' m_objMapper.rm_from_swapchainwsis_map(pPacket->swapChain.handle);')
1780 rbody.append(' }')
1781 elif 'DestroyInstance' in proto.name:
1782 rbody.append(' if (replayResult == VK_SUCCESS)')
1783 rbody.append(' {')
1784 rbody.append(' // TODO need to handle multiple instances and only clearing maps within an instance.')
1785 rbody.append(' // TODO this only works with a single instance used at any given time.')
1786 rbody.append(' m_objMapper.clear_all_map_handles();')
1787 rbody.append(' }')
1788 elif 'AllocDescriptorSets' in proto.name:
1789 rbody.append(' if (replayResult == VK_SUCCESS)')
1790 rbody.append(' {')
Jon Ashburn9e8755b2015-08-10 08:53:44 -06001791 rbody.append(' for (uint32_t i = 0; i < pPacket->count; i++) {')
1792 rbody.append(' m_objMapper.add_to_descriptorsets_map(pPacket->%s[i].handle, local_%s[i].handle);' % (proto.params[-1].name, proto.params[-1].name))
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001793 rbody.append(' }')
1794 rbody.append(' }')
Jon Ashburn9e8755b2015-08-10 08:53:44 -06001795 rbody.append(' free(local_pSetLayouts);')
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001796 rbody.append(' free(local_pDescriptorSets);')
1797 elif proto.name == 'ResetFences':
1798 rbody.append(' GLV_DELETE(fences);')
1799 elif create_func: # save handle mapping if create successful
1800 rbody.append(' if (replayResult == VK_SUCCESS)')
1801 rbody.append(' {')
1802 clean_type = proto.params[-1].ty.strip('*').replace('const ', '')
Jon Ashburncb622a12015-08-06 17:22:53 -06001803 VkNonDispObjType = [o for o in vulkan.object_non_dispatch_list]
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001804 if clean_type in VkNonDispObjType:
1805 rbody.append(' m_objMapper.add_to_%ss_map(pPacket->%s->handle, local_%s.handle);' % (clean_type.lower()[2:], proto.params[-1].name, proto.params[-1].name))
1806 else:
1807 rbody.append(' m_objMapper.add_to_%ss_map(*(pPacket->%s), local_%s);' % (clean_type.lower()[2:], proto.params[-1].name, proto.params[-1].name))
1808 if 'AllocMemory' == proto.name:
1809 rbody.append(' m_objMapper.add_entry_to_mapData(local_%s, pPacket->pAllocInfo->allocationSize);' % (proto.params[-1].name))
1810 rbody.append(' }')
1811 elif proto.name in do_while_dict:
1812 rbody[-1] = ' %s' % rbody[-1]
1813 rbody.append(' } while (%s);' % do_while_dict[proto.name])
1814 rbody.append(' if (pPacket->result != VK_NOT_READY || replayResult != VK_SUCCESS)')
1815 if ret_value:
1816 rbody.append(' CHECK_RETURN_VALUE(vk%s);' % proto.name)
1817 rbody.append(' break;')
1818 rbody.append(' }')
1819 rbody.append(' default:')
1820 rbody.append(' glv_LogWarning("Unrecognized packet_id %u, skipping.", packet->packet_id);')
1821 rbody.append(' returnValue = glv_replay::GLV_REPLAY_INVALID_ID;')
1822 rbody.append(' break;')
1823 rbody.append(' }')
1824 rbody.append(' return returnValue;')
1825 rbody.append('}')
1826 return "\n".join(rbody)
1827
1828class GlaveTraceHeader(Subcommand):
1829 def generate_header(self, extName):
1830 header_txt = []
1831 header_txt.append('#include "glv_vk_vk_packets.h"')
1832 header_txt.append('#include "glv_vk_packet_id.h"\n')
1833 header_txt.append('void AttachHooks();')
1834 header_txt.append('void DetachHooks();')
1835 header_txt.append('void InitTracer(void);\n')
1836 return "\n".join(header_txt)
1837
1838 def generate_body(self):
1839 body = [self._generate_trace_func_ptrs(),
1840 self._generate_trace_func_protos(),
1841 self._generate_trace_real_func_ptr_protos()]
1842
1843 return "\n".join(body)
1844
1845class GlaveTraceC(Subcommand):
1846 def generate_header(self, extName):
1847 header_txt = []
1848 header_txt.append('#include "glv_platform.h"')
1849 header_txt.append('#include "glv_common.h"')
1850 header_txt.append('#include "glvtrace_vk_helpers.h"')
1851 header_txt.append('#include "glvtrace_vk_vk.h"')
1852 header_txt.append('#include "glvtrace_vk_vk_debug_report_lunarg.h"')
1853 header_txt.append('#include "glvtrace_vk_vk_wsi_swapchain.h"')
1854 header_txt.append('#include "glvtrace_vk_vk_wsi_device_swapchain.h"')
1855 header_txt.append('#include "glv_interconnect.h"')
1856 header_txt.append('#include "glv_filelike.h"')
1857 header_txt.append('#include "vk_struct_size_helper.h"')
1858 header_txt.append('#ifdef WIN32')
1859 header_txt.append('#include "mhook/mhook-lib/mhook.h"')
1860 header_txt.append('#else')
1861 header_txt.append('#include <pthread.h>\n')
1862 header_txt.append('#endif')
1863 header_txt.append('#include "glv_trace_packet_utils.h"')
1864 header_txt.append('#include <stdio.h>')
1865 return "\n".join(header_txt)
1866
1867 def generate_body(self):
1868 body = [self._generate_func_ptr_assignments(),
1869 self._generate_attach_hooks(),
1870 self._generate_detach_hooks(),
1871 self._generate_init_funcs(),
1872 self._generate_trace_funcs(self.extName)]
1873
1874 return "\n".join(body)
1875
1876class GlavePacketID(Subcommand):
1877 def generate_header(self, extName):
1878 header_txt = []
1879 header_txt.append('#pragma once\n')
1880 header_txt.append('#include "glv_trace_packet_utils.h"')
1881 header_txt.append('#include "glv_trace_packet_identifiers.h"')
1882 header_txt.append('#include "glv_interconnect.h"')
1883 header_txt.append('#include "glv_vk_vk_packets.h"')
1884 header_txt.append('#include "glv_vk_vk_debug_report_lunarg_packets.h"')
1885 #header_txt.append('#include "glv_vk_vk_wsi_lunarg_packets.h"')
1886 header_txt.append('#include "glv_vk_vk_wsi_swapchain_packets.h"')
1887 header_txt.append('#include "glv_vk_vk_wsi_device_swapchain_packets.h"')
Jon Ashburncb622a12015-08-06 17:22:53 -06001888 #header_txt.append('#include "vk_enum_string_helper.h"')
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001889 header_txt.append('#ifndef _WIN32')
1890 header_txt.append(' #pragma GCC diagnostic ignored "-Wwrite-strings"')
1891 header_txt.append('#endif')
Jon Ashburncb622a12015-08-06 17:22:53 -06001892 #header_txt.append('#include "vk_struct_string_helper.h"')
1893 #header_txt.append('#include "vk_wsi_swapchain_struct_string_helper.h"')
1894 #header_txt.append('#include "vk_wsi_device_swapchain_struct_string_helper.h"')
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001895 header_txt.append('#ifndef _WIN32')
1896 header_txt.append(' #pragma GCC diagnostic warning "-Wwrite-strings"')
1897 header_txt.append('#endif')
Jon Ashburncb622a12015-08-06 17:22:53 -06001898 #header_txt.append('#include "vk_wsi_swapchain_enum_string_helper.h"')
1899 #header_txt.append('#include "vk_wsi_device_swapchain_enum_string_helper.h"')
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001900 header_txt.append('#if defined(WIN32)')
1901 header_txt.append('#define snprintf _snprintf')
1902 header_txt.append('#endif')
1903 header_txt.append('#define SEND_ENTRYPOINT_ID(entrypoint) ;')
1904 header_txt.append('//#define SEND_ENTRYPOINT_ID(entrypoint) glv_TraceInfo(#entrypoint);\n')
1905 header_txt.append('#define SEND_ENTRYPOINT_PARAMS(entrypoint, ...) ;')
1906 header_txt.append('//#define SEND_ENTRYPOINT_PARAMS(entrypoint, ...) glv_TraceInfo(entrypoint, __VA_ARGS__);\n')
1907 header_txt.append('#define CREATE_TRACE_PACKET(entrypoint, buffer_bytes_needed) \\')
1908 header_txt.append(' pHeader = glv_create_trace_packet(GLV_TID_VULKAN, GLV_TPI_VK_##entrypoint, sizeof(packet_##entrypoint), buffer_bytes_needed);\n')
1909 header_txt.append('#define FINISH_TRACE_PACKET() \\')
1910 header_txt.append(' glv_finalize_trace_packet(pHeader); \\')
1911 header_txt.append(' glv_write_trace_packet(pHeader, glv_trace_get_trace_file()); \\')
1912 header_txt.append(' glv_delete_trace_packet(&pHeader);')
1913 return "\n".join(header_txt)
1914
1915 def generate_body(self):
1916 body = [self._generate_packet_id_enum(),
1917 self._generate_packet_id_name_func(),
Jon Ashburncb622a12015-08-06 17:22:53 -06001918# self._generate_stringify_func(),
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001919 self._generate_interp_func()]
1920
1921 return "\n".join(body)
1922
1923class GlaveCoreTracePackets(Subcommand):
1924 def generate_header(self, extName):
1925 header_txt = []
1926 header_txt.append('#pragma once\n')
1927 header_txt.append('#include "vulkan.h"')
1928 header_txt.append('#include "glv_trace_packet_utils.h"\n')
1929 return "\n".join(header_txt)
1930
1931 def generate_body(self):
1932 body = [self._generate_struct_util_funcs(),
1933 self._generate_interp_funcs()]
1934
1935 return "\n".join(body)
1936
1937class GlaveExtTraceHeader(Subcommand):
1938 def generate_header(self, extName):
1939 header_txt = []
1940 header_txt.append('#pragma once\n')
1941 header_txt.append('#include "vulkan.h"')
1942 header_txt.append('#include "%s.h"' % extName.lower())
1943 return "\n".join(header_txt)
1944
1945 def generate_body(self):
1946 body = [self._generate_trace_func_ptrs_ext(self.extName),
1947 self._generate_trace_func_protos_ext(self.extName)]
1948
1949 return "\n".join(body)
1950
1951class GlaveExtTraceC(Subcommand):
1952 def generate_header(self, extName):
1953 header_txt = []
1954 header_txt.append('#include "glv_platform.h"')
1955 header_txt.append('#include "glv_common.h"')
Jon Ashburncb622a12015-08-06 17:22:53 -06001956 if extName == "vk_wsi_device_swapchain":
1957 header_txt.append('#include "vk_wsi_swapchain.h"')
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001958 header_txt.append('#include "glvtrace_vk_%s.h"' % extName.lower())
1959 header_txt.append('#include "glv_vk_%s_packets.h"' % extName.lower())
1960 header_txt.append('#include "glv_vk_packet_id.h"')
1961 header_txt.append('#include "vk_struct_size_helper.h"')
1962 header_txt.append('#include "%s_struct_size_helper.h"' % extName.lower())
1963 header_txt.append('#ifdef WIN32')
1964 header_txt.append('#include "mhook/mhook-lib/mhook.h"')
1965 header_txt.append('#endif')
1966 return "\n".join(header_txt)
1967
1968 def generate_body(self):
1969 body = [self._generate_func_ptr_assignments_ext(self.extName),
1970 self._generate_trace_funcs(self.extName)]
1971
1972 return "\n".join(body)
1973
1974class GlaveExtTracePackets(Subcommand):
1975 def generate_header(self, extName):
1976 header_txt = []
1977 header_txt.append('#pragma once\n')
1978 header_txt.append('#include "%s.h"' % extName.lower())
1979 header_txt.append('#include "glv_trace_packet_utils.h"\n')
1980 return "\n".join(header_txt)
1981
1982 def generate_body(self):
1983 body = [self._generate_interp_funcs_ext(self.extName)]
1984
1985 return "\n".join(body)
1986
1987class GlaveReplayVkFuncPtrs(Subcommand):
1988 def generate_header(self, extName):
1989 header_txt = []
1990 header_txt.append('#pragma once\n')
1991 header_txt.append('#if defined(PLATFORM_LINUX) || defined(XCB_NVIDIA)')
1992 header_txt.append('#include <xcb/xcb.h>\n')
1993 header_txt.append('#endif')
1994 header_txt.append('#include "vulkan.h"')
1995 header_txt.append('#include "vk_debug_report_lunarg.h"')
1996 header_txt.append('#include "vk_wsi_swapchain.h"')
1997 header_txt.append('#include "vk_wsi_device_swapchain.h"')
1998
1999 def generate_body(self):
2000 body = [self._generate_replay_func_ptrs()]
2001 return "\n".join(body)
2002
2003class GlaveReplayObjMapperHeader(Subcommand):
2004 def generate_header(self, extName):
2005 header_txt = []
2006 header_txt.append('#pragma once\n')
2007 header_txt.append('#include <set>')
2008 header_txt.append('#include <map>')
2009 header_txt.append('#include <vector>')
2010 header_txt.append('#include <string>')
2011 header_txt.append('#include "vulkan.h"')
2012 header_txt.append('#include "vk_debug_report_lunarg.h"')
2013 header_txt.append('#include "vk_wsi_swapchain.h"')
2014 header_txt.append('#include "vk_wsi_device_swapchain.h"')
2015 return "\n".join(header_txt)
2016
2017 def generate_body(self):
2018 body = [self._generate_replay_objmapper_class()]
2019 return "\n".join(body)
2020
2021class GlaveReplayC(Subcommand):
2022 def generate_header(self, extName):
2023 header_txt = []
2024 header_txt.append('#include "glvreplay_vk_vkreplay.h"\n')
2025 header_txt.append('#include "glvreplay_vk.h"\n')
2026 header_txt.append('#include "glvreplay_main.h"\n')
2027 header_txt.append('#include <algorithm>')
2028 header_txt.append('#include <queue>')
2029 header_txt.append('\n')
2030 header_txt.append('extern "C" {')
2031 header_txt.append('#include "glv_vk_vk_packets.h"')
2032 header_txt.append('#include "glv_vk_vk_debug_report_lunarg_packets.h"')
2033 #header_txt.append('#include "glv_vk_vk_wsi_lunarg_packets.h"')
2034 header_txt.append('#include "glv_vk_vk_wsi_swapchain_packets.h"')
2035 header_txt.append('#include "glv_vk_vk_wsi_device_swapchain_packets.h"')
2036 header_txt.append('#include "glv_vk_packet_id.h"')
Jon Ashburncb622a12015-08-06 17:22:53 -06002037 #header_txt.append('#include "vk_enum_string_helper.h"\n}\n')
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06002038
2039 return "\n".join(header_txt)
2040
2041 def generate_body(self):
2042 body = [self._generate_replay_init_funcs(),
2043 self._generate_replay()]
Jon Ashburncb622a12015-08-06 17:22:53 -06002044 body.append("}")
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06002045 return "\n".join(body)
2046
2047def main():
2048 subcommands = {
2049 "glave-trace-h" : GlaveTraceHeader,
2050 "glave-trace-c" : GlaveTraceC,
2051 "glave-packet-id" : GlavePacketID,
2052 "glave-core-trace-packets" : GlaveCoreTracePackets,
2053 "glave-ext-trace-h" : GlaveExtTraceHeader,
2054 "glave-ext-trace-c" : GlaveExtTraceC,
2055 "glave-ext-trace-packets" : GlaveExtTracePackets,
2056 "glave-replay-vk-funcs" : GlaveReplayVkFuncPtrs,
2057 "glave-replay-obj-mapper-h" : GlaveReplayObjMapperHeader,
2058 "glave-replay-c" : GlaveReplayC,
2059 }
2060
2061 if len(sys.argv) < 2 or sys.argv[1] not in subcommands:
2062 print("Usage: %s <subcommand> [options]" % sys.argv[0])
2063 print
2064 print("Available subcommands are: %s" % " ".join(subcommands))
2065 exit(1)
2066
2067 subcmd = subcommands[sys.argv[1]](sys.argv[2])
2068 subcmd.run()
2069
2070if __name__ == "__main__":
2071 main()