blob: 87f75e2e3d0439f20119a13a4c2759f2de8950e1 [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 = []
Mark Lobodzinskif39d70c2015-08-14 14:24:50 -0600198 hooks_txt.append('// declared as extern in vktrace_lib_helpers.h')
Jon Ashburn4d9cfd22015-08-04 13:35:25 -0600199 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',
Jon Ashburne70884b2015-08-25 13:33:39 -0600462 'CreateDevice',
Jon Ashburn4d9cfd22015-08-04 13:35:25 -0600463 'CreateFramebuffer',
464 'CreateInstance',
465 'CreateRenderPass',
466 'CreateGraphicsPipelines',
467 'CreateComputePipelines',
468 'CmdPipelineBarrier',
469 'CmdWaitEvents',
470 'CmdBeginRenderPass',
471 'EnumeratePhysicalDevices',
472 'FreeMemory',
473 'FreeDescriptorSets',
474 'FlushMappedMemoryRanges',
475 'GetGlobalExtensionProperties',
476 'GetPhysicalDeviceExtensionProperties',
477 'GetGlobalLayerProperties',
478 'GetPhysicalDeviceLayerProperties',
Jon Ashburn9e8755b2015-08-10 08:53:44 -0600479 'GetPhysicalDeviceQueueFamilyProperties',
Jon Ashburn4d9cfd22015-08-04 13:35:25 -0600480 'GetQueryPoolResults',
481 'MapMemory',
482 'UnmapMemory',
483 'UpdateDescriptorSets',
Ian Elliott1d44f4e2015-08-10 15:23:43 -0600484 'GetSurfacePropertiesWSI',
485 'GetSurfaceFormatsWSI',
486 'GetSurfacePresentModesWSI',
487 'CreateSwapChainWSI',
488 'GetSwapChainImagesWSI',
Jon Ashburn4d9cfd22015-08-04 13:35:25 -0600489 'QueuePresentWSI',
Cody Northrop2605cb02015-08-18 15:21:16 -0600490 'CreateDynamicStencilState',
Jon Ashburn4d9cfd22015-08-04 13:35:25 -0600491 ]
492
493 # validate the manually_written_hooked_funcs list
494 protoFuncs = [proto.name for proto in self.protos]
495 for func in manually_written_hooked_funcs:
496 if func not in protoFuncs:
497 sys.exit("Entry '%s' in manually_written_hooked_funcs list is not in the vulkan function prototypes" % func)
498
499 # process each of the entrypoint prototypes
Jon Ashburncb622a12015-08-06 17:22:53 -0600500 for ext in vulkan.extensions_all:
Jon Ashburn4d9cfd22015-08-04 13:35:25 -0600501 if ext.name.lower() == extName.lower():
502 for proto in ext.protos:
503 if proto.name in manually_written_hooked_funcs:
Mark Lobodzinskif39d70c2015-08-14 14:24:50 -0600504 func_body.append( '// __HOOKED_vk%s is manually written. Look in vktrace_vk_trace.c\n' % proto.name)
Jon Ashburn4d9cfd22015-08-04 13:35:25 -0600505 else:
506 raw_packet_update_list = [] # non-ptr elements placed directly into packet
507 ptr_packet_update_list = [] # ptr elements to be updated into packet
508 return_txt = ''
509 packet_size = []
510 in_data_size = False # flag when we need to capture local input size variable for in/out size
511 func_body.append('%s' % self.lineinfo.get())
512 func_body.append('GLVTRACER_EXPORT %s VKAPI __HOOKED_vk%s(' % (proto.ret, proto.name))
513 for p in proto.params: # TODO : For all of the ptr types, check them for NULL and return 0 if NULL
514 func_body.append(' %s %s,' % (p.ty, p.name))
515 if '*' in p.ty and p.name not in ['pSysMem', 'pReserved']:
516 if 'pDataSize' in p.name:
517 in_data_size = True;
518 elif 'pfnMsgCallback' == p.name:
519 raw_packet_update_list.append(' PFN_vkDbgMsgCallback* pNonConstCallback = (PFN_vkDbgMsgCallback*)&pPacket->pfnMsgCallback;')
520 raw_packet_update_list.append(' *pNonConstCallback = pfnMsgCallback;')
521 else:
522 raw_packet_update_list.append(' pPacket->%s = %s;' % (p.name, p.name))
523 # Get list of packet size modifiers due to ptr params
524 packet_size = self._get_packet_size(extName, proto.params)
525 ptr_packet_update_list = self._get_packet_ptr_param_list(proto.params)
526 func_body[-1] = func_body[-1].replace(',', ')')
527 # End of function declaration portion, begin function body
528 func_body.append('{\n glv_trace_packet_header* pHeader;')
529 if 'void' not in proto.ret or '*' in proto.ret:
530 func_body.append(' %s result;' % proto.ret)
531 return_txt = 'result = '
532 if in_data_size:
533 func_body.append(' size_t _dataSize;')
534 func_body.append(' packet_vk%s* pPacket = NULL;' % proto.name)
535 if (0 == len(packet_size)):
536 func_body.append(' CREATE_TRACE_PACKET(vk%s, 0);' % (proto.name))
537 else:
538 func_body.append(' CREATE_TRACE_PACKET(vk%s, %s);' % (proto.name, ' + '.join(packet_size)))
539
540 # TODO: need a better way to indicate which extensions should be mapped to which Get*ProcAddr
541 if proto.name == 'GetInstanceProcAddr':
542 for iProto in self.protos:
543 if 'Dbg' in iProto.name or 'GetPhysicalDeviceSurfaceSupportWSI' in iProto.name:
544 func_body.append(' if (strcmp(pName, "vk%s") == 0) {' % (iProto.name))
545 func_body.append(' real_vk%s = (PFN_vk%s)real_vkGetInstanceProcAddr(instance, pName);' % (iProto.name, iProto.name))
546 func_body.append(' glv_set_packet_entrypoint_end_time(pHeader);')
547 func_body.append(' if (real_vk%s != NULL) {' % (iProto.name))
548 func_body.append(' result = (PFN_vkVoidFunction)__HOOKED_vk%s;' % (iProto.name))
549 func_body.append(' } else {')
550 func_body.append(' result = NULL;')
551 func_body.append(' }')
552 func_body.append(' }')
553 elif proto.name == 'GetDeviceProcAddr':
554 for dProto in self.protos:
555 if 'WSI' in dProto.name:
556 func_body.append(' if (strcmp(pName, "vk%s") == 0) {' % (dProto.name))
557 func_body.append(' real_vk%s = (PFN_vk%s)real_vkGetDeviceProcAddr(device, pName);' % (dProto.name, dProto.name))
558 func_body.append(' glv_set_packet_entrypoint_end_time(pHeader);')
559 func_body.append(' if (real_vk%s != NULL) {' % (dProto.name))
560 func_body.append(' result = (PFN_vkVoidFunction)__HOOKED_vk%s;' % (dProto.name))
561 func_body.append(' } else {')
562 func_body.append(' result = NULL;')
563 func_body.append(' }')
564 func_body.append(' }')
565 else:
566 # call real entrypoint and get return value (if there is one)
567 func_body.append(' %sreal_vk%s;' % (return_txt, proto.c_call()))
568 func_body.append(' glv_set_packet_entrypoint_end_time(pHeader);')
569
570 if in_data_size:
571 func_body.append(' _dataSize = (pDataSize == NULL || pData == NULL) ? 0 : *pDataSize;')
572 func_body.append(' pPacket = interpret_body_as_vk%s(pHeader);' % proto.name)
573 func_body.append('\n'.join(raw_packet_update_list))
574 for pp_dict in ptr_packet_update_list: #buff_ptr_indices:
575 func_body.append(' %s;' % (pp_dict['add_txt']))
576 if 'void' not in proto.ret or '*' in proto.ret:
577 func_body.append(' pPacket->result = result;')
578 for pp_dict in ptr_packet_update_list:
579 if ('DeviceCreateInfo' not in proto.params[pp_dict['index']].ty):
580 func_body.append(' %s;' % (pp_dict['finalize_txt']))
581 # All buffers should be finalized by now, and the trace packet can be finished (which sends it over the socket)
582 func_body.append(' FINISH_TRACE_PACKET();')
583 # return result if needed
584 if 'void' not in proto.ret or '*' in proto.ret:
585 func_body.append(' return result;')
586 func_body.append('}\n')
587 return "\n".join(func_body)
588
589 def _generate_packet_id_enum(self):
590 pid_enum = []
591 pid_enum.append('enum GLV_TRACE_PACKET_ID_VK')
592 pid_enum.append('{')
593 first_func = True
594 for proto in self.protos:
595 if first_func:
596 first_func = False
597 pid_enum.append(' GLV_TPI_VK_vkApiVersion = GLV_TPI_BEGIN_API_HERE,')
598 pid_enum.append(' GLV_TPI_VK_vk%s,' % proto.name)
599 else:
600 pid_enum.append(' GLV_TPI_VK_vk%s,' % proto.name)
601 pid_enum.append('};\n')
602 return "\n".join(pid_enum)
603
604 def _generate_packet_id_name_func(self):
605 func_body = []
606 func_body.append('static const char *glv_vk_packet_id_name(const enum GLV_TRACE_PACKET_ID_VK id)')
607 func_body.append('{')
608 func_body.append(' switch(id) {')
609 func_body.append(' case GLV_TPI_VK_vkApiVersion:')
610 func_body.append(' {')
611 func_body.append(' return "vkApiVersion";')
612 func_body.append(' }')
613 for proto in self.protos:
614 func_body.append(' case GLV_TPI_VK_vk%s:' % proto.name)
615 func_body.append(' {')
616 func_body.append(' return "vk%s";' % proto.name)
617 func_body.append(' }')
618 func_body.append(' default:')
619 func_body.append(' return NULL;')
620 func_body.append(' }')
621 func_body.append('}\n')
622 return "\n".join(func_body)
623
Jon Ashburn4d9cfd22015-08-04 13:35:25 -0600624 def _generate_interp_func(self):
625 interp_func_body = []
626 interp_func_body.append('%s' % self.lineinfo.get())
627 interp_func_body.append('static glv_trace_packet_header* interpret_trace_packet_vk(glv_trace_packet_header* pHeader)')
628 interp_func_body.append('{')
629 interp_func_body.append(' if (pHeader == NULL)')
630 interp_func_body.append(' {')
631 interp_func_body.append(' return NULL;')
632 interp_func_body.append(' }')
633 interp_func_body.append(' switch (pHeader->packet_id)')
634 interp_func_body.append(' {')
635 interp_func_body.append(' case GLV_TPI_VK_vkApiVersion:')
636 interp_func_body.append(' {')
637 interp_func_body.append(' return interpret_body_as_vkApiVersion(pHeader)->header;')
638 interp_func_body.append(' }')
639 for proto in self.protos:
640 interp_func_body.append(' case GLV_TPI_VK_vk%s:\n {' % proto.name)
641 header_prefix = 'h'
642 if 'WSI' in proto.name or 'Dbg' in proto.name:
643 header_prefix = 'pH'
644 interp_func_body.append(' return interpret_body_as_vk%s(pHeader)->%seader;\n }' % (proto.name, header_prefix))
645 interp_func_body.append(' default:')
646 interp_func_body.append(' return NULL;')
647 interp_func_body.append(' }')
648 interp_func_body.append(' return NULL;')
649 interp_func_body.append('}')
650 return "\n".join(interp_func_body)
651
652 def _generate_struct_util_funcs(self):
653 lineinfo = self.lineinfo
654 pid_enum = []
655 pid_enum.append('%s' % lineinfo.get())
656 pid_enum.append('//=============================================================================')
657 pid_enum.append('static void add_VkApplicationInfo_to_packet(glv_trace_packet_header* pHeader, VkApplicationInfo** ppStruct, const VkApplicationInfo *pInStruct)')
658 pid_enum.append('{')
659 pid_enum.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)ppStruct, sizeof(VkApplicationInfo), pInStruct);')
660 pid_enum.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)&((*ppStruct)->pAppName), strlen(pInStruct->pAppName) + 1, pInStruct->pAppName);')
661 pid_enum.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)&((*ppStruct)->pEngineName), strlen(pInStruct->pEngineName) + 1, pInStruct->pEngineName);')
662 pid_enum.append(' glv_finalize_buffer_address(pHeader, (void**)&((*ppStruct)->pAppName));')
663 pid_enum.append(' glv_finalize_buffer_address(pHeader, (void**)&((*ppStruct)->pEngineName));')
664 pid_enum.append(' glv_finalize_buffer_address(pHeader, (void**)&*ppStruct);')
665 pid_enum.append('};\n')
666 pid_enum.append('%s' % lineinfo.get())
667 pid_enum.append('static void add_VkInstanceCreateInfo_to_packet(glv_trace_packet_header* pHeader, VkInstanceCreateInfo** ppStruct, VkInstanceCreateInfo *pInStruct)')
668 pid_enum.append('{')
669 pid_enum.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)ppStruct, sizeof(VkInstanceCreateInfo), pInStruct);')
670 pid_enum.append(' add_VkApplicationInfo_to_packet(pHeader, (VkApplicationInfo**)&((*ppStruct)->pAppInfo), pInStruct->pAppInfo);')
671 pid_enum.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)&((*ppStruct)->pAllocCb), sizeof(VkAllocCallbacks), pInStruct->pAllocCb);')
672 pid_enum.append(' glv_finalize_buffer_address(pHeader, (void**)&((*ppStruct)->pAllocCb));')
673 # TODO138 : This is an initial pass at getting the extension/layer arrays correct, needs to be validated.
674 pid_enum.append(' uint32_t i, siz = 0;')
675 pid_enum.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)&((*ppStruct)->ppEnabledLayerNames), pInStruct->layerCount * sizeof(char*), pInStruct->ppEnabledLayerNames);')
676 pid_enum.append(' if (pInStruct->layerCount > 0) ')
677 pid_enum.append(' {')
678 pid_enum.append(' for (i = 0; i < pInStruct->layerCount; i++) {')
679 pid_enum.append(' siz = (1 + strlen(pInStruct->ppEnabledLayerNames[i]));')
680 pid_enum.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)(&(*ppStruct)->ppEnabledLayerNames[i]), siz, pInStruct->ppEnabledLayerNames[i]);')
681 pid_enum.append(' glv_finalize_buffer_address(pHeader, (void **)&(*ppStruct)->ppEnabledLayerNames[i]);')
682 pid_enum.append(' }')
683 pid_enum.append(' }')
684 pid_enum.append(' glv_finalize_buffer_address(pHeader, (void **)&(*ppStruct)->ppEnabledLayerNames);')
685 pid_enum.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)&((*ppStruct)->ppEnabledExtensionNames), pInStruct->extensionCount * sizeof(char*), pInStruct->ppEnabledExtensionNames);')
686 pid_enum.append(' if (pInStruct->extensionCount > 0) ')
687 pid_enum.append(' {')
688 pid_enum.append(' for (i = 0; i < pInStruct->extensionCount; i++) {')
689 pid_enum.append(' siz = (1 + strlen(pInStruct->ppEnabledExtensionNames[i]));')
690 pid_enum.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)(&(*ppStruct)->ppEnabledExtensionNames[i]), siz, pInStruct->ppEnabledExtensionNames[i]);')
691 pid_enum.append(' glv_finalize_buffer_address(pHeader, (void **)&(*ppStruct)->ppEnabledExtensionNames[i]);')
692 pid_enum.append(' }')
693 pid_enum.append(' }')
694 pid_enum.append(' glv_finalize_buffer_address(pHeader, (void **)&(*ppStruct)->ppEnabledExtensionNames);')
695 pid_enum.append(' glv_finalize_buffer_address(pHeader, (void**)ppStruct);')
696 pid_enum.append('}\n')
697 pid_enum.append('%s' % lineinfo.get())
698 pid_enum.append('static void add_VkDeviceCreateInfo_to_packet(glv_trace_packet_header* pHeader, VkDeviceCreateInfo** ppStruct, const VkDeviceCreateInfo *pInStruct)')
699 pid_enum.append('{')
700 pid_enum.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)ppStruct, sizeof(VkDeviceCreateInfo), pInStruct);')
701 pid_enum.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)&(*ppStruct)->pRequestedQueues, pInStruct->queueRecordCount*sizeof(VkDeviceQueueCreateInfo), pInStruct->pRequestedQueues);')
702 pid_enum.append(' glv_finalize_buffer_address(pHeader, (void**)&(*ppStruct)->pRequestedQueues);')
703 # TODO138 : This is an initial pass at getting the extension/layer arrays correct, needs to be validated.
704 pid_enum.append(' uint32_t i, siz = 0;')
705 pid_enum.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)&((*ppStruct)->ppEnabledLayerNames), pInStruct->layerCount * sizeof(char*), pInStruct->ppEnabledLayerNames);')
706 pid_enum.append(' if (pInStruct->layerCount > 0) ')
707 pid_enum.append(' {')
708 pid_enum.append(' for (i = 0; i < pInStruct->layerCount; i++) {')
709 pid_enum.append(' siz = (1 + strlen(pInStruct->ppEnabledLayerNames[i]));')
710 pid_enum.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)(&(*ppStruct)->ppEnabledLayerNames[i]), siz, pInStruct->ppEnabledLayerNames[i]);')
711 pid_enum.append(' glv_finalize_buffer_address(pHeader, (void **)&(*ppStruct)->ppEnabledLayerNames[i]);')
712 pid_enum.append(' }')
713 pid_enum.append(' }')
714 pid_enum.append(' glv_finalize_buffer_address(pHeader, (void **)&(*ppStruct)->ppEnabledLayerNames);')
715 pid_enum.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)&((*ppStruct)->ppEnabledExtensionNames), pInStruct->extensionCount * sizeof(char*), pInStruct->ppEnabledExtensionNames);')
716 pid_enum.append(' if (pInStruct->extensionCount > 0) ')
717 pid_enum.append(' {')
718 pid_enum.append(' for (i = 0; i < pInStruct->extensionCount; i++) {')
719 pid_enum.append(' siz = (1 + strlen(pInStruct->ppEnabledExtensionNames[i]));')
720 pid_enum.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)(&(*ppStruct)->ppEnabledExtensionNames[i]), siz, pInStruct->ppEnabledExtensionNames[i]);')
721 pid_enum.append(' glv_finalize_buffer_address(pHeader, (void **)&(*ppStruct)->ppEnabledExtensionNames[i]);')
722 pid_enum.append(' }')
723 pid_enum.append(' }')
724 pid_enum.append(' glv_finalize_buffer_address(pHeader, (void **)&(*ppStruct)->ppEnabledExtensionNames);')
725 pid_enum.append(' glv_add_buffer_to_trace_packet(pHeader, (void**)&(*ppStruct)->pEnabledFeatures, sizeof(VkPhysicalDeviceFeatures), pInStruct->pEnabledFeatures);')
726 pid_enum.append(' glv_finalize_buffer_address(pHeader, (void**)&(*ppStruct)->pEnabledFeatures);')
727 pid_enum.append(' glv_finalize_buffer_address(pHeader, (void**)ppStruct);')
728 pid_enum.append('}\n')
729 pid_enum.append('%s' % lineinfo.get())
730 pid_enum.append('//=============================================================================\n')
731 pid_enum.append('static VkInstanceCreateInfo* interpret_VkInstanceCreateInfo(glv_trace_packet_header* pHeader, intptr_t ptr_variable)')
732 pid_enum.append('{')
733 pid_enum.append(' VkInstanceCreateInfo* pVkInstanceCreateInfo = (VkInstanceCreateInfo*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)ptr_variable);\n')
734 pid_enum.append(' uint32_t i;')
735 pid_enum.append(' if (pVkInstanceCreateInfo != NULL)')
736 pid_enum.append(' {')
737 pid_enum.append(' pVkInstanceCreateInfo->pAppInfo = (VkApplicationInfo*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pVkInstanceCreateInfo->pAppInfo);')
738 pid_enum.append(' pVkInstanceCreateInfo->pAllocCb = (VkAllocCallbacks*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pVkInstanceCreateInfo->pAllocCb);')
739 pid_enum.append(' VkApplicationInfo** ppAppInfo = (VkApplicationInfo**) &pVkInstanceCreateInfo->pAppInfo;')
740 pid_enum.append(' (*ppAppInfo)->pAppName = (const char*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pVkInstanceCreateInfo->pAppInfo->pAppName);')
741 pid_enum.append(' (*ppAppInfo)->pEngineName = (const char*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pVkInstanceCreateInfo->pAppInfo->pEngineName);')
742 pid_enum.append(' if (pVkInstanceCreateInfo->layerCount > 0)')
743 pid_enum.append(' {')
744 pid_enum.append(' pVkInstanceCreateInfo->ppEnabledLayerNames = (const char* const*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pVkInstanceCreateInfo->ppEnabledLayerNames);')
745 pid_enum.append(' for (i = 0; i < pVkInstanceCreateInfo->layerCount; i++) {')
746 pid_enum.append(' char** ppTmp = (char**)&pVkInstanceCreateInfo->ppEnabledLayerNames[i];')
747 pid_enum.append(' *ppTmp = (char*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pVkInstanceCreateInfo->ppEnabledLayerNames[i]);')
748 pid_enum.append(' }')
749 pid_enum.append(' }')
750 pid_enum.append(' if (pVkInstanceCreateInfo->extensionCount > 0)')
751 pid_enum.append(' {')
752 pid_enum.append(' pVkInstanceCreateInfo->ppEnabledExtensionNames = (const char* const*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pVkInstanceCreateInfo->ppEnabledExtensionNames);')
753 pid_enum.append(' for (i = 0; i < pVkInstanceCreateInfo->extensionCount; i++) {')
754 pid_enum.append(' char** ppTmp = (char**)&pVkInstanceCreateInfo->ppEnabledExtensionNames[i];')
755 pid_enum.append(' *ppTmp = (char*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pVkInstanceCreateInfo->ppEnabledExtensionNames[i]);')
756 pid_enum.append(' }')
757 pid_enum.append(' }')
758 pid_enum.append(' }\n')
759 pid_enum.append(' return pVkInstanceCreateInfo;')
760 pid_enum.append('}\n')
761 pid_enum.append('%s' % lineinfo.get())
762 pid_enum.append('static VkDeviceCreateInfo* interpret_VkDeviceCreateInfo(glv_trace_packet_header* pHeader, intptr_t ptr_variable)')
763 pid_enum.append('{')
764 pid_enum.append(' VkDeviceCreateInfo* pVkDeviceCreateInfo = (VkDeviceCreateInfo*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)ptr_variable);\n')
765 pid_enum.append(' uint32_t i;')
766 pid_enum.append(' if (pVkDeviceCreateInfo != NULL)')
767 pid_enum.append(' {')
768 pid_enum.append(' pVkDeviceCreateInfo->pRequestedQueues = (const VkDeviceQueueCreateInfo *)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pVkDeviceCreateInfo->pRequestedQueues);\n')
769 pid_enum.append(' if (pVkDeviceCreateInfo->layerCount > 0)')
770 pid_enum.append(' {')
771 pid_enum.append(' pVkDeviceCreateInfo->ppEnabledLayerNames = (const char* const*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pVkDeviceCreateInfo->ppEnabledLayerNames);')
772 pid_enum.append(' for (i = 0; i < pVkDeviceCreateInfo->layerCount; i++) {')
773 pid_enum.append(' char** ppTmp = (char**)&pVkDeviceCreateInfo->ppEnabledLayerNames[i];')
774 pid_enum.append(' *ppTmp = (char*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pVkDeviceCreateInfo->ppEnabledLayerNames[i]);')
775 pid_enum.append(' }')
776 pid_enum.append(' }')
777 pid_enum.append(' if (pVkDeviceCreateInfo->extensionCount > 0)')
778 pid_enum.append(' {')
779 pid_enum.append(' pVkDeviceCreateInfo->ppEnabledExtensionNames = (const char* const*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pVkDeviceCreateInfo->ppEnabledExtensionNames);')
780 pid_enum.append(' for (i = 0; i < pVkDeviceCreateInfo->extensionCount; i++) {')
781 pid_enum.append(' char** ppTmp = (char**)&pVkDeviceCreateInfo->ppEnabledExtensionNames[i];')
782 pid_enum.append(' *ppTmp = (char*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pVkDeviceCreateInfo->ppEnabledExtensionNames[i]);')
783 pid_enum.append(' }')
784 pid_enum.append(' }')
785 pid_enum.append(' pVkDeviceCreateInfo->pEnabledFeatures = (const VkPhysicalDeviceFeatures*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pVkDeviceCreateInfo->pEnabledFeatures);\n')
786 pid_enum.append(' }\n')
787 pid_enum.append(' return pVkDeviceCreateInfo;')
788 pid_enum.append('}\n')
789 pid_enum.append('%s' % lineinfo.get())
790 pid_enum.append('static void interpret_VkPipelineShaderStageCreateInfo(glv_trace_packet_header* pHeader, VkPipelineShaderStageCreateInfo* pShader)')
791 pid_enum.append('{')
792 pid_enum.append(' if (pShader != NULL)')
793 pid_enum.append(' {')
794 pid_enum.append(' // specialization info')
795 pid_enum.append(' pShader->pSpecializationInfo = (const VkSpecializationInfo*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pShader->pSpecializationInfo);')
796 pid_enum.append(' if (pShader->pSpecializationInfo != NULL)')
797 pid_enum.append(' {')
798 pid_enum.append(' VkSpecializationInfo* pInfo = (VkSpecializationInfo*)pShader->pSpecializationInfo;')
799 pid_enum.append(' pInfo->pMap = (const VkSpecializationMapEntry*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pShader->pSpecializationInfo->pMap);')
800 pid_enum.append(' pInfo->pData = (const void*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pShader->pSpecializationInfo->pData);')
801 pid_enum.append(' }')
802 pid_enum.append(' }')
803 pid_enum.append('}\n')
804 pid_enum.append('//=============================================================================')
805 return "\n".join(pid_enum)
806
807 # Interpret functions used on replay to read in packets and interpret their contents
Mark Lobodzinskif39d70c2015-08-14 14:24:50 -0600808 # This code gets generated into vktrace_vk_vk_packets.h file
Jon Ashburn4d9cfd22015-08-04 13:35:25 -0600809 def _generate_interp_funcs(self):
810 # Custom txt for given function and parameter. First check if param is NULL, then insert txt if not
811 # First some common code used by both CmdWaitEvents & CmdPipelineBarrier
812 mem_barrier_interp = ['uint32_t i = 0;\n',
813 'for (i = 0; i < pPacket->memBarrierCount; i++) {\n',
814 ' void** ppMB = (void**)&(pPacket->ppMemBarriers[i]);\n',
815 ' *ppMB = glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->ppMemBarriers[i]);\n',
816 ' //VkMemoryBarrier* pBarr = (VkMemoryBarrier*)pPacket->ppMemBarriers[i];\n',
817 ' // TODO : Could fix up the pNext ptrs here if they were finalized and if we cared by switching on Barrier type and remapping\n',
818 '}']
819 create_rp_interp = ['VkRenderPassCreateInfo* pInfo = (VkRenderPassCreateInfo*)pPacket->pCreateInfo;\n',
820 'uint32_t i = 0;\n',
821 'VkAttachmentDescription **ppAD = (VkAttachmentDescription **)&(pInfo->pAttachments);\n',
822 '*ppAD = (VkAttachmentDescription*) glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pInfo->pAttachments);\n',
823 'VkSubpassDescription** ppSP = (VkSubpassDescription**)&(pInfo->pSubpasses);\n',
824 '*ppSP = (VkSubpassDescription*) glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pInfo->pSubpasses);\n',
825 'for (i=0; i<pInfo->subpassCount; i++) {\n',
Jon Ashburn9e8755b2015-08-10 08:53:44 -0600826 ' VkAttachmentReference** pAR = (VkAttachmentReference**)&(pInfo->pSubpasses[i].pInputAttachments);\n',
827 ' *pAR = (VkAttachmentReference*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pInfo->pSubpasses[i].pInputAttachments);\n',
828 ' pAR = (VkAttachmentReference**)&(pInfo->pSubpasses[i].pColorAttachments);\n',
829 ' *pAR = (VkAttachmentReference*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pInfo->pSubpasses[i].pColorAttachments);\n',
830 ' pAR = (VkAttachmentReference**)&(pInfo->pSubpasses[i].pResolveAttachments);\n',
831 ' *pAR = (VkAttachmentReference*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pInfo->pSubpasses[i].pResolveAttachments);\n',
832 ' pAR = (VkAttachmentReference**)&(pInfo->pSubpasses[i].pPreserveAttachments);\n',
833 ' *pAR = (VkAttachmentReference*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pInfo->pSubpasses[i].pPreserveAttachments);\n',
Jon Ashburn4d9cfd22015-08-04 13:35:25 -0600834 '}\n',
835 'VkSubpassDependency** ppSD = (VkSubpassDependency**)&(pInfo->pDependencies);\n',
836 '*ppSD = (VkSubpassDependency*) glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pInfo->pDependencies);\n']
837 create_gfx_pipe = ['uint32_t i;\n',
838 'uint32_t j;\n',
839 'for (i=0; i<pPacket->count; i++) {\n',
840 'if (pPacket->pCreateInfos[i].sType == VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO) {\n',
841 '// need to make a non-const pointer to the pointer so that we can properly change the original pointer to the interpretted one\n',
842 'VkGraphicsPipelineCreateInfo* pNonConst = (VkGraphicsPipelineCreateInfo*)&(pPacket->pCreateInfos[i]);\n',
843 '// shader stages array\n',
844 'pNonConst->pStages = (VkPipelineShaderStageCreateInfo*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfos[i].pStages);\n',
845 'for (j = 0; j < pPacket->pCreateInfos[i].stageCount; j++)\n',
846 '{\n',
847 ' interpret_VkPipelineShaderStageCreateInfo(pHeader, (VkPipelineShaderStageCreateInfo*)&pPacket->pCreateInfos[i].pStages[j]);\n',
848 '}\n',
849 '// Vertex Input State\n',
850 'pNonConst->pVertexInputState = (VkPipelineVertexInputStateCreateInfo*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfos[i].pVertexInputState);\n',
851 'VkPipelineVertexInputStateCreateInfo* pNonConstVIState = (VkPipelineVertexInputStateCreateInfo*)pNonConst->pVertexInputState;\n',
852 'if (pNonConstVIState) {\n',
853 ' pNonConstVIState->pVertexBindingDescriptions = (const VkVertexInputBindingDescription*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfos[i].pVertexInputState->pVertexBindingDescriptions);\n',
854 ' pNonConstVIState->pVertexAttributeDescriptions = (const VkVertexInputAttributeDescription*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfos[i].pVertexInputState->pVertexAttributeDescriptions);\n',
855 '}\n',
856 '// Input Assembly State\n',
857 'pNonConst->pInputAssemblyState = (const VkPipelineInputAssemblyStateCreateInfo*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfos[i].pInputAssemblyState);\n',
858 '// Tesselation State\n',
859 'pNonConst->pTessellationState = (const VkPipelineTessellationStateCreateInfo*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfos[i].pTessellationState);\n',
860 '// Viewport State\n',
861 'pNonConst->pViewportState = (const VkPipelineViewportStateCreateInfo*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfos[i].pViewportState);\n',
862 '// Raster State\n',
863 'pNonConst->pRasterState = (const VkPipelineRasterStateCreateInfo*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfos[i].pRasterState);\n',
864 '// MultiSample State\n',
865 'pNonConst->pMultisampleState = (const VkPipelineMultisampleStateCreateInfo*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfos[i].pMultisampleState);\n',
866 '// DepthStencil State\n',
867 'pNonConst->pDepthStencilState = (const VkPipelineDepthStencilStateCreateInfo*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfos[i].pDepthStencilState);\n',
868 '// ColorBuffer State\n',
869 'pNonConst->pColorBlendState = (const VkPipelineColorBlendStateCreateInfo*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfos[i].pColorBlendState);\n',
870 'VkPipelineColorBlendStateCreateInfo* pNonConstCbState = (VkPipelineColorBlendStateCreateInfo*)pNonConst->pColorBlendState;\n',
871 'if (pNonConstCbState)\n',
872 ' pNonConstCbState->pAttachments = (const VkPipelineColorBlendAttachmentState*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfos[i].pColorBlendState->pAttachments);\n',
873 '} else {\n',
874 ' // This is unexpected.\n',
875 ' glv_LogError("CreateGraphicsPipelines must have CreateInfo stype of VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO.");\n',
876 ' pPacket->header = NULL;\n',
877 '}\n',
878 '}\n']
879 # 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
880 # 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
881 custom_case_dict = { #'CreateShader' : {'param': 'pCreateInfo', 'txt': ['VkShaderCreateInfo* pInfo = (VkShaderCreateInfo*)pPacket->pCreateInfo;\n',
882 # 'pInfo->pCode = glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfo->pCode);']},
883 'CreateDynamicViewportState' : {'param': 'pCreateInfo', 'txt': ['VkDynamicViewportStateCreateInfo* pInfo = (VkDynamicViewportStateCreateInfo*)pPacket->pCreateInfo;\n',
884 'pInfo->pViewports = (VkViewport*) glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfo->pViewports);\n',
885 'pInfo->pScissors = (VkRect2D*) glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfo->pScissors);']},
886 #'CreateFramebuffer' : {'param': 'pCreateInfo', 'txt': ['VkFramebufferCreateInfo* pInfo = (VkFramebufferCreateInfo*)pPacket->pCreateInfo;\n',
887 # 'pInfo->pColorAttachments = (VkColorAttachmentBindInfo*) glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfo->pColorAttachments);\n',
888 # 'pInfo->pDepthStencilAttachment = (VkDepthStencilBindInfo*) glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfo->pDepthStencilAttachment);\n']},
889 'CreateRenderPass' : {'param': 'pCreateInfo', 'txt': create_rp_interp},
890 'CreatePipelineLayout' : {'param': 'pCreateInfo', 'txt': ['VkPipelineLayoutCreateInfo* pInfo = (VkPipelineLayoutCreateInfo*)pPacket->pCreateInfo;\n',
891 'pInfo->pSetLayouts = (VkDescriptorSetLayout*) glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfo->pSetLayouts);\n']},
892 'CreateDescriptorPool' : {'param': 'pCreateInfo', 'txt': ['VkDescriptorPoolCreateInfo* pInfo = (VkDescriptorPoolCreateInfo*)pPacket->pCreateInfo;\n',
893 'pInfo->pTypeCount = (VkDescriptorTypeCount*) glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfo->pTypeCount);\n']},
894 'CmdWaitEvents' : {'param': 'ppMemBarriers', 'txt': mem_barrier_interp},
895 'CmdPipelineBarrier' : {'param': 'ppMemBarriers', 'txt': mem_barrier_interp},
896 'CreateDescriptorSetLayout' : {'param': 'pCreateInfo', 'txt': ['if (pPacket->pCreateInfo->sType == VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO) {\n',
897 ' VkDescriptorSetLayoutCreateInfo* pNext = (VkDescriptorSetLayoutCreateInfo*)pPacket->pCreateInfo;\n',
898 ' do\n',' {\n',
899 ' // need to make a non-const pointer to the pointer so that we can properly change the original pointer to the interpretted one\n',
900 ' void** ppNextVoidPtr = (void**)&(pNext->pNext);\n',
901 ' *ppNextVoidPtr = (void*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pNext->pNext);\n',
902 ' switch(pNext->sType)\n', ' {\n',
903 ' case VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO:\n',
904 ' {\n' ,
905 ' unsigned int i = 0;\n',
906 ' pNext->pBinding = (VkDescriptorSetLayoutBinding*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pNext->pBinding);\n',
907 ' for (i = 0; i < pNext->count; i++)\n',' {\n',
908 ' VkSampler** ppSamplers = (VkSampler**)&(pNext->pBinding[i].pImmutableSamplers);\n',
909 ' *ppSamplers = (VkSampler*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pNext->pBinding[i].pImmutableSamplers);\n',
910 ' }\n',
911 ' break;\n',
912 ' }\n',
913 ' default:\n',
914 ' {\n',
915 ' glv_LogError("Encountered an unexpected type in descriptor set layout create list.");\n',
916 ' pPacket->header = NULL;\n',
917 ' pNext->pNext = NULL;\n',
918 ' }\n',
919 ' }\n',
920 ' pNext = (VkDescriptorSetLayoutCreateInfo*)pNext->pNext;\n',
921 ' } while (NULL != pNext);\n',
922 '} else {\n',
923 ' // This is unexpected.\n',
924 ' glv_LogError("CreateDescriptorSetLayout must have pCreateInfo->stype of VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO.");\n',
925 ' pPacket->header = NULL;\n',
926 '}']},
927# 'BeginCommandBuffer' : {'param': 'pBeginInfo', 'txt': ['if (pPacket->pBeginInfo->sType == VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO) {\n',
928# ' // need to make a non-const pointer to the pointer so that we can properly change the original pointer to the interpretted one\n',
929# ' VkCmdBufferGraphicsBeginInfo** ppNext = (VkCmdBufferGraphicsBeginInfo**)&(pPacket->pBeginInfo->pNext);\n',
930# ' *ppNext = (VkCmdBufferGraphicsBeginInfo*) glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pBeginInfo->pNext);\n',
931# ' VkCmdBufferGraphicsBeginInfo* pNext = *ppNext;\n',
932# ' while (NULL != pNext)\n', ' {\n',
933# ' switch(pNext->sType)\n', ' {\n',
934# ' case VK_STRUCTURE_TYPE_CMD_BUFFER_GRAPHICS_BEGIN_INFO:\n',
935# ' {\n',
936# ' ppNext = (VkCmdBufferGraphicsBeginInfo**) &pNext->pNext;\n',
937# ' *ppNext = (VkCmdBufferGraphicsBeginInfo*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pNext->pNext);\n',
938# ' break;\n',
939# ' }\n',
940# ' default:\n',
941# ' {\n',
942# ' glv_LogError("Encountered an unexpected type in begin command buffer list.");\n',
943# ' pPacket->header = NULL;\n',
944# ' pNext->pNext = NULL;\n',
945# ' }\n',
946# ' }\n',
947# ' pNext = (VkCmdBufferGraphicsBeginInfo*)pNext->pNext;\n',
948# ' }\n',
949# '} else {\n',
950# ' // This is unexpected.\n',
951# ' glv_LogError("BeginCommandBuffer must have BeginInfo stype of VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO.");\n',
952# ' pPacket->header = NULL;\n',
953# '}']},
954 'AllocMemory' : {'param': 'pAllocInfo', 'txt': ['if (pPacket->pAllocInfo->sType == VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO) {\n',
955 ' VkMemoryAllocInfo** ppNext = (VkMemoryAllocInfo**) &(pPacket->pAllocInfo->pNext);\n',
956 ' *ppNext = (VkMemoryAllocInfo*) glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pAllocInfo->pNext);\n',
957 ' VkMemoryAllocInfo* pNext = (VkMemoryAllocInfo*) *ppNext;\n',
958 ' while (NULL != pNext)\n', ' {\n',
959 ' switch(pNext->sType)\n', ' {\n',
960 ' default:\n',
961 ' {\n',
962 ' glv_LogError("Encountered an unexpected type alloc memory list.");\n',
963 ' pPacket->header = NULL;\n',
964 ' pNext->pNext = NULL;\n',
965 ' }\n',
966 ' }\n',
967 ' pNext = (VkMemoryAllocInfo*)pNext->pNext;\n',
968 ' }\n',
969 '} else {\n',
970 ' // This is unexpected.\n',
971 ' glv_LogError("AllocMemory must have AllocInfo stype of VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO.");\n',
972 ' pPacket->header = NULL;\n',
973 '}']},
974 'UpdateDescriptorSets' : {'param': 'pDescriptorWrites', 'txt':
975 [ 'uint32_t i;\n',
976 'for (i = 0; i < pPacket->writeCount; i++) {\n',
977 ' VkDescriptorInfo** ppDescriptors = (VkDescriptorInfo**)&pPacket->pDescriptorWrites[i].pDescriptors;\n',
978 ' *ppDescriptors = (VkDescriptorInfo*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pDescriptorWrites[i].pDescriptors);\n',
979 '}'
980 ]},
981 'CreateGraphicsPipelines' : {'param': 'pCreateInfos', 'txt': create_gfx_pipe},
982 'CreateComputePipeline' : {'param': 'pCreateInfo', 'txt': ['interpret_VkPipelineShaderStageCreateInfo(pHeader, (VkPipelineShaderStageCreateInfo*)(&pPacket->pCreateInfo->cs));']},
Jon Ashburn9e8755b2015-08-10 08:53:44 -0600983 'CreateFramebuffer' : {'param': 'pCreateInfo', 'txt': ['VkAttachmentView** ppAV = (VkAttachmentView**)&(pPacket->pCreateInfo->pAttachments);\n',
984 '*ppAV = (VkAttachmentView*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)(pPacket->pCreateInfo->pAttachments));']},
985 'CmdBeginRenderPass' : {'param': 'pRenderPassBegin', 'txt': ['VkClearValue** ppCV = (VkClearValue**)&(pPacket->pRenderPassBegin->pClearValues);\n',
986 '*ppCV = (VkClearValue*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)(pPacket->pRenderPassBegin->pClearValues));']},
Jon Ashburn4d9cfd22015-08-04 13:35:25 -0600987 'CreateShaderModule' : {'param': 'pCreateInfo', 'txt': ['void** ppCode = (void**)&(pPacket->pCreateInfo->pCode);\n',
988 '*ppCode = (void*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfo->pCode);']},
989 'CreateShader' : {'param': 'pCreateInfo', 'txt': ['void** ppName = (void**)&(pPacket->pCreateInfo->pName);\n',
990 '*ppName = (void*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfo->pName);']},
991 'FlushMappedMemoryRanges' : {'param': 'ppData', 'txt': ['uint32_t i = 0;\n',
992 'for (i = 0; i < pPacket->memRangeCount; i++)\n',
993 '{\n',
994 ' pPacket->ppData[i] = (void*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->ppData[i]);\n',
995 '}']}}
996 if_body = []
997 if_body.append('typedef struct packet_vkApiVersion {')
998 if_body.append(' glv_trace_packet_header* header;')
999 if_body.append(' uint32_t version;')
1000 if_body.append('} packet_vkApiVersion;\n')
1001 if_body.append('static packet_vkApiVersion* interpret_body_as_vkApiVersion(glv_trace_packet_header* pHeader)')
1002 if_body.append('{')
1003 if_body.append(' packet_vkApiVersion* pPacket = (packet_vkApiVersion*)pHeader->pBody;')
1004 if_body.append(' pPacket->header = pHeader;')
1005 if_body.append(' return pPacket;')
1006 if_body.append('}\n')
1007 for proto in self.protos:
1008 if 'WSI' not in proto.name and 'Dbg' not in proto.name:
1009 if 'UnmapMemory' == proto.name:
1010 proto.params.append(vulkan.Param("void*", "pData"))
1011 elif 'FlushMappedMemoryRanges' == proto.name:
1012 proto.params.append(vulkan.Param("void**", "ppData"))
1013 if_body.append('%s' % self.lineinfo.get())
1014 if_body.append('typedef struct packet_vk%s {' % proto.name)
1015 if_body.append(' glv_trace_packet_header* header;')
1016 for p in proto.params:
1017 if_body.append(' %s %s;' % (p.ty, p.name))
1018 if 'void' != proto.ret:
1019 if_body.append(' %s result;' % proto.ret)
1020 if_body.append('} packet_vk%s;\n' % proto.name)
1021 if_body.append('static packet_vk%s* interpret_body_as_vk%s(glv_trace_packet_header* pHeader)' % (proto.name, proto.name))
1022 if_body.append('{')
1023 if_body.append(' packet_vk%s* pPacket = (packet_vk%s*)pHeader->pBody;' % (proto.name, proto.name))
1024 if_body.append(' pPacket->header = pHeader;')
1025 for p in proto.params:
1026 if '*' in p.ty:
1027 if 'DeviceCreateInfo' in p.ty:
1028 if_body.append(' pPacket->%s = interpret_VkDeviceCreateInfo(pHeader, (intptr_t)pPacket->%s);' % (p.name, p.name))
1029 elif 'InstanceCreateInfo' in p.ty:
1030 if_body.append(' pPacket->%s = interpret_VkInstanceCreateInfo(pHeader, (intptr_t)pPacket->%s);' % (p.name, p.name))
1031 else:
1032 if_body.append(' pPacket->%s = (%s)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->%s);' % (p.name, p.ty, p.name))
1033 # TODO : Generalize this custom code to kill dict data struct above.
1034 # Really the point of this block is to catch params w/ embedded ptrs to structs and chains of structs
1035 if proto.name in custom_case_dict and p.name == custom_case_dict[proto.name]['param']:
1036 if_body.append(' if (pPacket->%s != NULL)' % custom_case_dict[proto.name]['param'])
1037 if_body.append(' {')
1038 if_body.append(' %s' % " ".join(custom_case_dict[proto.name]['txt']))
1039 if_body.append(' }')
1040 if_body.append(' return pPacket;')
1041 if_body.append('}\n')
1042 return "\n".join(if_body)
1043
1044 def _generate_interp_funcs_ext(self, extName):
1045 if_body = []
1046 custom_case_dict = { 'QueuePresentWSI' : {'param': 'pPresentInfo', 'txt': ['pPacket->pPresentInfo->swapChains = (VkSwapChainWSI*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)(pPacket->pPresentInfo->swapChains));\n',
1047 'pPacket->pPresentInfo->imageIndices = (uint32_t*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)(pPacket->pPresentInfo->imageIndices));']},
Jon Ashburnc51afc72015-08-11 16:01:35 -06001048 'CreateSwapChainWSI' : {'param': 'pCreateInfo', 'txt': ['VkSurfaceDescriptionWSI **ppSurfDescp = (VkSurfaceDescriptionWSI**)&pPacket->pCreateInfo->pSurfaceDescription;\n',
1049 'uint32_t **ppQFI = (uint32_t**)&pPacket->pCreateInfo->pQueueFamilyIndices;\n',
1050 '(*ppSurfDescp) = (VkSurfaceDescriptionWSI*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)(pPacket->pCreateInfo->pSurfaceDescription));\n',
1051 '(*ppQFI) = (uint32_t*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)(pPacket->pCreateInfo->pQueueFamilyIndices));']},
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001052 }
Jon Ashburncb622a12015-08-06 17:22:53 -06001053 for ext in vulkan.extensions_all:
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001054 if ext.name.lower() == extName.lower():
1055 for proto in ext.protos:
1056 if_body.append('typedef struct packet_vk%s {' % proto.name)
1057 if_body.append(' glv_trace_packet_header* pHeader;')
1058 for p in proto.params:
1059 if_body.append(' %s %s;' % (p.ty, p.name))
1060 if 'void' != proto.ret:
1061 if_body.append(' %s result;' % proto.ret)
1062 if_body.append('} packet_vk%s;\n' % proto.name)
1063 if_body.append('static packet_vk%s* interpret_body_as_vk%s(glv_trace_packet_header* pHeader)' % (proto.name, proto.name))
1064 if_body.append('{')
1065 if_body.append(' packet_vk%s* pPacket = (packet_vk%s*)pHeader->pBody;' % (proto.name, proto.name))
1066 if_body.append(' pPacket->pHeader = pHeader;')
1067 for p in proto.params:
1068 if '*' in p.ty:
1069 if_body.append(' pPacket->%s = (%s)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->%s);' % (p.name, p.ty, p.name))
1070 # TODO : Generalize this custom code to kill dict data struct above.
1071 # Really the point of this block is to catch params w/ embedded ptrs to structs and chains of structs
1072 if proto.name in custom_case_dict and p.name == custom_case_dict[proto.name]['param']:
1073 if_body.append(' if (pPacket->%s != NULL)' % custom_case_dict[proto.name]['param'])
1074 if_body.append(' {')
1075 if_body.append(' %s' % " ".join(custom_case_dict[proto.name]['txt']))
1076 if_body.append(' }')
1077 if_body.append(' return pPacket;')
1078 if_body.append('}\n')
1079 return "\n".join(if_body)
1080
1081 def _generate_replay_func_ptrs(self):
1082 xf_body = []
1083 xf_body.append('struct vkFuncs {')
1084 xf_body.append(' void init_funcs(void * libHandle);')
1085 xf_body.append(' void *m_libHandle;\n')
1086 for proto in self.protos:
1087 xf_body.append(' typedef %s( VKAPI * type_vk%s)(' % (proto.ret, proto.name))
1088 for p in proto.params:
1089 xf_body.append(' %s %s,' % (p.ty, p.name))
1090 xf_body[-1] = xf_body[-1].replace(',', ');')
1091 xf_body.append(' type_vk%s real_vk%s;' % (proto.name, proto.name))
1092 xf_body.append('};')
1093 return "\n".join(xf_body)
1094
1095 def _map_decl(self, type1, type2, name):
1096 return ' std::map<%s, %s> %s;' % (type1, type2, name)
1097
1098 def _add_to_map_decl(self, type1, type2, name):
1099 txt = ' void add_to_%s_map(%s pTraceVal, %s pReplayVal)\n {\n' % (name[2:], type1, type2)
1100 #TODO138 : These checks need to vary between disp & non-disp objects
1101 #txt += ' assert(pTraceVal != 0);\n'
1102 #txt += ' assert(pReplayVal != 0);\n'
1103 txt += ' %s[pTraceVal] = pReplayVal;\n }\n' % name
1104 return txt
1105
1106 def _rm_from_map_decl(self, ty, name):
1107 txt = ' void rm_from_%s_map(const %s& key)\n {\n' % (name[2:], ty)
1108 txt += ' %s.erase(key);\n }\n' % name
1109 return txt
1110
1111 def _remap_decl(self, ty, name):
1112 txt = ' %s remap_%s(const %s& value)\n {\n' % (ty, name[2:], ty)
1113 txt += ' if (value == 0) { return 0; }\n'
1114 txt += ' std::map<%s, %s>::const_iterator q = %s.find(value);\n' % (ty, ty, name)
Cody Northropdc3fb192015-08-12 11:30:30 -06001115 txt += ' if (q == %s.end()) { glv_LogError("Failed to remap %s."); return value; }\n' % (name, ty)
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001116 txt += ' return q->second;\n }\n'
1117 return txt
1118
1119 def _generate_replay_objMemory_funcs(self):
1120 rof_body = []
1121 # Custom code for memory mapping functions for app writes into mapped memory
1122 rof_body.append('// memory mapping functions for app writes into mapped memory')
1123 rof_body.append(' bool isPendingAlloc()')
1124 rof_body.append(' {')
1125 rof_body.append(' return m_pendingAlloc;')
1126 rof_body.append(' }')
1127 rof_body.append('')
1128 rof_body.append(' void setAllocInfo(const VkMemoryAllocInfo *info, const bool pending)')
1129 rof_body.append(' {')
1130 rof_body.append(' m_pendingAlloc = pending;')
1131 rof_body.append(' m_allocInfo = *info;')
1132 rof_body.append(' }')
1133 rof_body.append('')
1134 rof_body.append(' void setMemoryDataAddr(void *pBuf)')
1135 rof_body.append(' {')
1136 rof_body.append(' if (m_mapRange.empty())')
1137 rof_body.append(' {')
1138 rof_body.append(' glv_LogError("gpuMemory::setMemoryDataAddr() m_mapRange is empty.");')
1139 rof_body.append(' return;')
1140 rof_body.append(' }')
1141 rof_body.append(' MapRange mr = m_mapRange.back();')
1142 rof_body.append(' if (mr.pData != NULL)')
1143 rof_body.append(' glv_LogWarning("gpuMemory::setMemoryDataAddr() data already mapped overwrite old mapping.");')
1144 rof_body.append(' else if (pBuf == NULL)')
1145 rof_body.append(' glv_LogWarning("gpuMemory::setMemoryDataAddr() adding NULL pointer.");')
1146 rof_body.append(' mr.pData = (uint8_t *) pBuf;')
1147 rof_body.append(' }')
1148 rof_body.append('')
1149 rof_body.append(' void setMemoryMapRange(void *pBuf, const size_t size, const size_t offset, const bool pending)')
1150 rof_body.append(' {')
1151 rof_body.append(' MapRange mr;')
1152 rof_body.append(' mr.pData = (uint8_t *) pBuf;')
1153 rof_body.append(' if (size == 0)')
1154 rof_body.append(' mr.size = m_allocInfo.allocationSize - offset;')
1155 rof_body.append(' else')
1156 rof_body.append(' mr.size = size;')
1157 rof_body.append(' mr.offset = offset;')
1158 rof_body.append(' mr.pending = pending;')
1159 rof_body.append(' m_mapRange.push_back(mr);')
1160 rof_body.append(' assert(m_allocInfo.allocationSize >= (size + offset));')
1161 rof_body.append(' }')
1162 rof_body.append('')
1163 rof_body.append(' void copyMappingData(const void* pSrcData, bool entire_map, size_t size, size_t offset)')
1164 rof_body.append(' {')
1165 rof_body.append(' if (m_mapRange.empty())')
1166 rof_body.append(' {')
1167 rof_body.append(' glv_LogError("gpuMemory::copyMappingData() m_mapRange is empty.");')
1168 rof_body.append(' return;')
1169 rof_body.append(' }')
1170 rof_body.append(' MapRange mr = m_mapRange.back();')
1171 rof_body.append(' if (!pSrcData || !mr.pData)')
1172 rof_body.append(' {')
1173 rof_body.append(' if (!pSrcData)')
1174 rof_body.append(' glv_LogError("gpuMemory::copyMappingData() null src pointer.");')
1175 rof_body.append(' else')
1176 rof_body.append(' glv_LogError("gpuMemory::copyMappingData() null dest pointer totalSize=%u.", m_allocInfo.allocationSize);')
1177 rof_body.append(' m_mapRange.pop_back();')
1178 rof_body.append(' return;')
1179 rof_body.append(' }')
1180 rof_body.append(' if (entire_map)')
1181 rof_body.append(' {')
1182 rof_body.append(' size = mr.size;')
1183 rof_body.append(' offset = mr.offset;')
1184 rof_body.append(' }')
1185 rof_body.append(' else')
1186 rof_body.append(' {')
1187 rof_body.append(' assert(offset >= mr.offset);')
1188 rof_body.append(' assert(size <= mr.size && (size + offset) <= mr.size);')
1189 rof_body.append(' }')
1190 rof_body.append(' memcpy(mr.pData + offset, pSrcData, size);')
1191 rof_body.append(' if (!mr.pending && entire_map)')
1192 rof_body.append(' m_mapRange.pop_back();')
1193 rof_body.append(' }')
1194 rof_body.append('')
1195 rof_body.append(' size_t getMemoryMapSize()')
1196 rof_body.append(' {')
1197 rof_body.append(' return (!m_mapRange.empty()) ? m_mapRange.back().size : 0;')
1198 rof_body.append(' }\n')
1199 return "\n".join(rof_body)
1200
1201 def _generate_replay_objmapper_class(self):
1202 # Create dict mapping member var names to VK type (i.e. 'm_imageViews' : 'VkImage_VIEW')
1203 obj_map_dict = {}
1204 for obj in vulkan.object_type_list:
Jon Ashburncb622a12015-08-06 17:22:53 -06001205 if (obj.startswith('Vk')):
1206 mem_var = obj.replace('Vk', '').lower()
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001207 mem_var_list = mem_var.split('_')
1208 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 -06001209 obj_map_dict[mem_var] = obj
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001210 rc_body = []
1211 rc_body.append('#define GLV_VK_OBJECT_TYPE_UNKNOWN (VkObjectType)-1')
1212 rc_body.append('')
1213 rc_body.append('typedef struct _VKAllocInfo {')
1214 rc_body.append(' VkDeviceSize size;')
1215 rc_body.append(' uint8_t *pData;')
1216 rc_body.append(' bool rangeUpdated;')
1217 rc_body.append('} VKAllocInfo;')
1218 rc_body.append('')
1219 rc_body.append('class objMemory {')
1220 rc_body.append('public:')
1221 rc_body.append(' objMemory() : m_numAllocations(0), m_pMemReqs(NULL) {}')
1222 rc_body.append(' ~objMemory() { free(m_pMemReqs);}')
1223 rc_body.append(' void setCount(const uint32_t num)')
1224 rc_body.append(' {')
1225 rc_body.append(' m_numAllocations = num;')
1226 rc_body.append(' }\n')
1227 rc_body.append(' void setReqs(const VkMemoryRequirements *pReqs, const uint32_t num)')
1228 rc_body.append(' {')
1229 rc_body.append(' if (m_numAllocations != num && m_numAllocations != 0)')
1230 rc_body.append(' glv_LogError("objMemory::setReqs, internal mismatch on number of allocations.");')
1231 rc_body.append(' if (m_pMemReqs == NULL && pReqs != NULL)')
1232 rc_body.append(' {')
1233 rc_body.append(' m_pMemReqs = (VkMemoryRequirements *) glv_malloc(num * sizeof(VkMemoryRequirements));')
1234 rc_body.append(' if (m_pMemReqs == NULL)')
1235 rc_body.append(' {')
1236 rc_body.append(' glv_LogError("objMemory::setReqs out of memory.");')
1237 rc_body.append(' return;')
1238 rc_body.append(' }')
1239 rc_body.append(' memcpy(m_pMemReqs, pReqs, num * sizeof(VkMemoryRequirements));')
1240 rc_body.append(' }')
1241 rc_body.append(' }\n')
1242 rc_body.append('private:')
1243 rc_body.append(' uint32_t m_numAllocations;')
1244 rc_body.append(' VkMemoryRequirements *m_pMemReqs;')
1245 rc_body.append('};')
1246 rc_body.append('')
1247 rc_body.append('class gpuMemory {')
1248 rc_body.append('public:')
1249 rc_body.append(' gpuMemory() : m_pendingAlloc(false) {m_allocInfo.allocationSize = 0;}')
1250 rc_body.append(' ~gpuMemory() {}')
1251 rc_body.append(self._generate_replay_objMemory_funcs())
1252 rc_body.append('private:')
1253 rc_body.append(' bool m_pendingAlloc;')
1254 rc_body.append(' struct MapRange {')
1255 rc_body.append(' bool pending;')
1256 rc_body.append(' size_t size;')
1257 rc_body.append(' size_t offset;')
1258 rc_body.append(' uint8_t* pData;')
1259 rc_body.append(' };')
1260 rc_body.append(' std::vector<MapRange> m_mapRange;')
1261 rc_body.append(' VkMemoryAllocInfo m_allocInfo;')
1262 rc_body.append('};')
1263 rc_body.append('')
1264 rc_body.append('typedef struct _imageObj {')
1265 rc_body.append(' objMemory imageMem;')
1266 rc_body.append(' VkImage replayImage;')
1267 rc_body.append(' } imageObj;')
1268 rc_body.append('')
1269 rc_body.append('typedef struct _bufferObj {')
1270 rc_body.append(' objMemory bufferMem;')
1271 rc_body.append(' VkBuffer replayBuffer;')
1272 rc_body.append(' } bufferObj;')
1273 rc_body.append('')
1274 rc_body.append('typedef struct _gpuMemObj {')
1275 rc_body.append(' gpuMemory *pGpuMem;')
1276 rc_body.append(' VkDeviceMemory replayGpuMem;')
1277 rc_body.append(' } gpuMemObj;')
1278 rc_body.append('')
1279 rc_body.append('')
1280 rc_body.append('class vkReplayObjMapper {')
1281 rc_body.append('public:')
1282 rc_body.append(' vkReplayObjMapper() {}')
1283 rc_body.append(' ~vkReplayObjMapper() {}')
1284 rc_body.append('')
1285 rc_body.append(' bool m_adjustForGPU; // true if replay adjusts behavior based on GPU')
1286 # Code for memory objects for handling replay GPU != trace GPU object memory requirements
1287 rc_body.append('void init_objMemCount(const uint64_t handle, const VkDbgObjectType objectType, const uint32_t &num)\n {')
1288 rc_body.append(' switch (objectType) {')
1289 rc_body.append(' case VK_OBJECT_TYPE_BUFFER:')
1290 rc_body.append(' {')
1291 rc_body.append(' std::map<uint64_t, bufferObj>::iterator it = m_buffers.find(handle);')
1292 rc_body.append(' if (it != m_buffers.end()) {')
1293 rc_body.append(' objMemory obj = it->second.bufferMem;')
1294 rc_body.append(' obj.setCount(num);')
1295 rc_body.append(' return;')
1296 rc_body.append(' }')
1297 rc_body.append(' break;')
1298 rc_body.append(' }')
1299 rc_body.append(' case VK_OBJECT_TYPE_IMAGE:')
1300 rc_body.append(' {')
1301 rc_body.append(' std::map<uint64_t, imageObj>::iterator it = m_images.find(handle);')
1302 rc_body.append(' if (it != m_images.end()) {')
1303 rc_body.append(' objMemory obj = it->second.imageMem;')
1304 rc_body.append(' obj.setCount(num);')
1305 rc_body.append(' return;')
1306 rc_body.append(' }')
1307 rc_body.append(' break;')
1308 rc_body.append(' }')
1309 rc_body.append(' default:')
1310 rc_body.append(' break;')
1311 rc_body.append(' }')
1312 rc_body.append(' return;')
1313 rc_body.append('}\n')
1314 rc_body.append('void init_objMemReqs(const uint64_t handle, const VkDbgObjectType objectType, const VkMemoryRequirements *pMemReqs, const unsigned int num)\n {')
1315 rc_body.append(' switch (objectType) {')
1316 rc_body.append(' case VK_OBJECT_TYPE_BUFFER:')
1317 rc_body.append(' {')
1318 rc_body.append(' std::map<uint64_t, bufferObj>::iterator it = m_buffers.find(handle);')
1319 rc_body.append(' if (it != m_buffers.end()) {')
1320 rc_body.append(' objMemory obj = it->second.bufferMem;')
1321 rc_body.append(' obj.setReqs(pMemReqs, num);')
1322 rc_body.append(' return;')
1323 rc_body.append(' }')
1324 rc_body.append(' break;')
1325 rc_body.append(' }')
1326 rc_body.append(' case VK_OBJECT_TYPE_IMAGE:')
1327 rc_body.append(' {')
1328 rc_body.append(' std::map<uint64_t, imageObj>::iterator it = m_images.find(handle);')
1329 rc_body.append(' if (it != m_images.end()) {')
1330 rc_body.append(' objMemory obj = it->second.imageMem;')
1331 rc_body.append(' obj.setReqs(pMemReqs, num);')
1332 rc_body.append(' return;')
1333 rc_body.append(' }')
1334 rc_body.append(' break;')
1335 rc_body.append(' }')
1336 rc_body.append(' default:')
1337 rc_body.append(' break;')
1338 rc_body.append(' }')
1339 rc_body.append(' return;')
1340 rc_body.append(' }')
1341 rc_body.append('')
1342 rc_body.append(' void clear_all_map_handles()\n {')
1343 for var in sorted(obj_map_dict):
1344 rc_body.append(' %s.clear();' % var)
1345 rc_body.append(' }\n')
Jon Ashburncb622a12015-08-06 17:22:53 -06001346 disp_obj_types = [obj for obj in vulkan.object_dispatch_list]
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001347 for var in sorted(obj_map_dict):
1348 # Disp objs are pts so the obj can be map key, for non-disp objs, use uint64_t handle as map key
1349 if obj_map_dict[var] in disp_obj_types:
1350 rc_body.append(self._map_decl(obj_map_dict[var], obj_map_dict[var], var))
1351 rc_body.append(self._add_to_map_decl(obj_map_dict[var], obj_map_dict[var], var))
1352 rc_body.append(self._rm_from_map_decl(obj_map_dict[var], var))
1353 rc_body.append(self._remap_decl(obj_map_dict[var], var))
1354 elif obj_map_dict[var] == 'VkImage':
1355 rc_body.append(self._map_decl('uint64_t', 'imageObj', var))
1356 rc_body.append(self._add_to_map_decl('uint64_t', 'imageObj', var))
1357 rc_body.append(self._rm_from_map_decl('uint64_t', var))
1358 rc_body.append(' uint64_t remap_images(const uint64_t& value)')
1359 rc_body.append(' {')
1360 rc_body.append(' if (value == 0) { return 0; }')
1361 rc_body.append('')
1362 rc_body.append(' std::map<uint64_t, imageObj>::const_iterator q = m_images.find(value);')
Cody Northropdc3fb192015-08-12 11:30:30 -06001363 rc_body.append(' if (q == m_images.end()) { glv_LogError("Failed to remap VkImage."); return value; }\n')
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001364 rc_body.append(' return q->second.replayImage.handle;')
1365 rc_body.append(' }\n')
1366 elif obj_map_dict[var] == 'VkBuffer':
1367 rc_body.append(self._map_decl('uint64_t', 'bufferObj', var))
1368 rc_body.append(self._add_to_map_decl('uint64_t', 'bufferObj', var))
1369 rc_body.append(self._rm_from_map_decl('uint64_t', var))
1370 rc_body.append(' uint64_t remap_buffers(const uint64_t& value)')
1371 rc_body.append(' {')
1372 rc_body.append(' if (value == 0) { return 0; }')
1373 rc_body.append('')
1374 rc_body.append(' std::map<uint64_t, bufferObj>::const_iterator q = m_buffers.find(value);')
Cody Northropdc3fb192015-08-12 11:30:30 -06001375 rc_body.append(' if (q == m_buffers.end()) { glv_LogError("Failed to remap VkBuffer."); return value; }\n')
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001376 rc_body.append(' return q->second.replayBuffer.handle;')
1377 rc_body.append(' }\n')
1378 elif obj_map_dict[var] == 'VkDeviceMemory':
1379 rc_body.append(self._map_decl('uint64_t', 'gpuMemObj', var))
1380 rc_body.append(self._add_to_map_decl('uint64_t', 'gpuMemObj', var))
1381 rc_body.append(self._rm_from_map_decl('uint64_t', var))
1382 rc_body.append(' uint64_t remap_devicememorys(const uint64_t& value)')
1383 rc_body.append(' {')
1384 rc_body.append(' if (value == 0) { return 0; }')
1385 rc_body.append('')
1386 rc_body.append(' std::map<uint64_t, gpuMemObj>::const_iterator q = m_devicememorys.find(value);')
Cody Northropdc3fb192015-08-12 11:30:30 -06001387 rc_body.append(' if (q == m_devicememorys.end()) { glv_LogError("Failed to remap VkDeviceMemory."); return value; }')
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001388 rc_body.append(' return q->second.replayGpuMem.handle;')
1389 rc_body.append(' }\n')
1390 else:
1391 rc_body.append(self._map_decl('uint64_t', 'uint64_t', var))
1392 rc_body.append(self._add_to_map_decl('uint64_t', 'uint64_t', var))
1393 rc_body.append(self._rm_from_map_decl('uint64_t', var))
1394 rc_body.append(self._remap_decl('uint64_t', var))
1395 # VkDynamicStateObject code
1396# TODO138 : Each dynamic state object is now unique so need to make sure their re-mapping is being handled correctly
1397# state_obj_remap_types = vulkan.object_dynamic_state_list
1398# state_obj_bindings = vulkan.object_dynamic_state_bind_point_list
1399# rc_body.append(' VkDynamicStateObject remap(const VkDynamicStateObject& state, const VkStateBindPoint& bindPoint)\n {')
1400# rc_body.append(' VkDynamicStateObject obj;')
1401# index = 0
1402# while index < len(state_obj_remap_types):
1403# obj = state_obj_remap_types[index]
1404# type = state_obj_bindings[index]
1405# rc_body.append(' if (bindPoint == %s) {' % type)
1406# rc_body.append(' if ((obj = remap(static_cast <%s> (state))) != VK_NULL_HANDLE)' % obj.type)
1407# rc_body.append(' return obj;')
1408# rc_body.append(' }')
1409# index += 1
1410# for obj in state_obj_remap_types:
1411# rc_body.append('// if ((obj = remap(static_cast <%s> (state))) != VK_NULL_HANDLE)' % obj.type)
1412# rc_body.append('// return obj;')
1413# rc_body.append(' glv_LogWarning("Failed to remap VkDynamicStateObject.");')
1414# rc_body.append(' return VK_NULL_HANDLE;\n }')
1415# rc_body.append(' void rm_from_map(const VkDynamicStateObject& state)\n {')
1416# for obj in state_obj_remap_types:
1417# rc_body.append(' rm_from_map(static_cast <%s> (state));' % obj.type)
1418# rc_body.append(' }')
1419# rc_body.append('')
1420 # OBJECT code
1421# TODO138 : VkObject construct is now dead, and I believe this code can die with it
1422# rc_body.append(' VkObject remap(const VkObject& object, VkObjectType objectType)\n {')
1423# rc_body.append(' VkObject obj = VK_NULL_HANDLE;')
1424# obj_remap_types = vulkan.object_type_list
1425# rc_body.append(' switch ((unsigned int)objectType) {')
1426# for obj in obj_remap_types:
1427# if obj.type not in vulkan.object_parent_list:
1428# rc_body.append(' case %s:' % obj.enum)
1429# rc_body.append(' obj = remap(static_cast <%s> (object));' % obj.type)
1430# rc_body.append(' break;')
1431# rc_body.append(' case GLV_VK_OBJECT_TYPE_UNKNOWN:')
1432# rc_body.append(' default:')
1433# rc_body.append(' obj = VK_NULL_HANDLE;')
1434# rc_body.append(' break;')
1435# rc_body.append(' }\n')
1436# rc_body.append(' if (obj == VK_NULL_HANDLE)')
1437# rc_body.append(' {')
1438# for obj in obj_remap_types:
1439# if obj.type not in vulkan.object_parent_list:
1440# rc_body.append(' if ((obj = remap(static_cast <%s> (object))) != VK_NULL_HANDLE) return obj;' % obj.type)
1441# rc_body.append(' glv_LogError("Failed to remap VkObject.");')
1442# rc_body.append(' }')
1443# rc_body.append(' return obj;')
1444# rc_body.append(' }')
1445# rc_body.append('')
1446# rc_body.append(' void rm_from_map(const VkObject& objKey, VkObjectType objectType)\n {')
1447# rc_body.append(' switch ((unsigned int)objectType) {')
1448# for obj in obj_remap_types:
1449# if obj.type not in vulkan.object_parent_list:
1450# rc_body.append(' case %s:' % obj.enum)
1451# rc_body.append(' rm_from_map(static_cast <%s> (objKey));' % (obj.type))
1452# rc_body.append(' break;')
1453# rc_body.append(' default:')
1454# rc_body.append(' assert(!"Unhandled or invalid VkObjectType passed into rm_from_map(..)");')
1455# rc_body.append(' break;')
1456# rc_body.append(' }')
1457# rc_body.append(' }')
1458 rc_body.append('};')
1459 return "\n".join(rc_body)
1460
1461 def _generate_replay_init_funcs(self):
1462 rif_body = []
1463 rif_body.append('void vkFuncs::init_funcs(void * handle)\n{\n m_libHandle = handle;')
1464 for proto in self.protos:
1465 if 'WSI' not in proto.name and 'Dbg' not in proto.name:
1466 rif_body.append(' real_vk%s = (type_vk%s)(glv_platform_get_library_entrypoint(handle, "vk%s"));' % (proto.name, proto.name, proto.name))
1467 else: # These func ptrs get assigned at GetProcAddr time
1468 rif_body.append(' real_vk%s = (type_vk%s)NULL;' % (proto.name, proto.name))
1469 rif_body.append('}')
1470 return "\n".join(rif_body)
1471
1472 def _remap_packet_param(self, funcName, paramType, paramName):
1473 remap_list = vulkan.object_type_list
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001474 param_exclude_list = ['pDescriptorSets', 'pFences']
1475 cleanParamType = paramType.strip('*').replace('const ', '')
Jon Ashburncb622a12015-08-06 17:22:53 -06001476 VulkNonDispObjects = [o for o in vulkan.object_non_dispatch_list]
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001477 for obj in remap_list:
Jon Ashburncb622a12015-08-06 17:22:53 -06001478 if obj == cleanParamType and paramName not in param_exclude_list:
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001479 objectTypeRemapParam = ''
1480 if 'VkDynamicStateObject' == cleanParamType:
1481 objectTypeRemapParam = ', pPacket->stateBindPoint'
1482 elif 'object' == paramName:
1483 if 'DbgSetObjectTag' == funcName:
1484 objectTypeRemapParam = ', GLV_VK_OBJECT_TYPE_UNKNOWN'
1485 else:
1486 objectTypeRemapParam = ', pPacket->objType'
1487 elif 'srcObject' == paramName and 'Callback' in funcName:
1488 objectTypeRemapParam = ', pPacket->objType'
1489 if '*' in paramType:
1490 if 'const ' not in paramType:
1491 result = ' %s remapped%s = m_objMapper.remap_%ss(*pPacket->%s%s);\n' % (cleanParamType, paramName, paramName.lower(), paramName, objectTypeRemapParam)
1492 result += ' if (pPacket->%s != VK_NULL_HANDLE && remapped%s == VK_NULL_HANDLE)\n' % (paramName, paramName)
1493 result += ' {\n'
1494 result += ' return glv_replay::GLV_REPLAY_ERROR;\n'
1495 result += ' }\n'
1496 return result
1497 else: # TODO : Don't remap array ptrs?
1498 return ' // pPacket->%s should have been remapped with special case code' % (paramName)
1499 if paramType in VulkNonDispObjects:
1500 result = ' %s remapped%s;\n' % (paramType, paramName)
1501 result += ' remapped%s.handle = m_objMapper.remap_%ss(pPacket->%s%s.handle);\n' % (paramName, cleanParamType.lower()[2:], paramName, objectTypeRemapParam)
1502 result += '%s\n' % self.lineinfo.get()
1503 result += ' if (pPacket->%s.handle != 0 && remapped%s.handle == 0)\n' % (paramName, paramName)
1504 result += ' {\n'
1505 result += ' return glv_replay::GLV_REPLAY_ERROR;\n'
1506 result += ' }\n'
1507 else:
1508 result = ' %s remapped%s = m_objMapper.remap_%ss(pPacket->%s%s);\n' % (paramType, paramName, cleanParamType.lower()[2:], paramName, objectTypeRemapParam)
1509 result += '%s\n' % self.lineinfo.get()
1510 result += ' if (pPacket->%s != VK_NULL_HANDLE && remapped%s == VK_NULL_HANDLE)\n' % (paramName, paramName)
1511 result += ' {\n'
1512 result += ' return glv_replay::GLV_REPLAY_ERROR;\n'
1513 result += ' }\n'
1514 return result
1515 return ' // No need to remap %s' % (paramName)
1516
1517 def _get_packet_param(self, funcName, paramType, paramName):
1518 # list of types that require remapping
1519 remap_list = vulkan.object_type_list
1520 param_exclude_list = ['pDescriptorSets', 'pFences']
1521 cleanParamType = paramType.strip('*').replace('const ', '')
1522 for obj in remap_list:
Jon Ashburncb622a12015-08-06 17:22:53 -06001523 if obj == cleanParamType and paramName not in param_exclude_list:
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001524 objectTypeRemapParam = ''
1525 if 'object' == paramName:
1526 if 'DbgSetObjectTag' == funcName:
1527 objectTypeRemapParam = ', GLV_VK_OBJECT_TYPE_UNKNOWN'
1528 else:
1529 objectTypeRemapParam = ', pPacket->objType'
1530 if '*' in paramType:
1531 if 'const ' not in paramType:
1532 return 'remapped%s' % (paramName)
1533 else: # TODO : Don't remap array ptrs?
1534 return 'pPacket->%s' % (paramName)
1535 return 'remapped%s' % (paramName)
1536 return 'pPacket->%s' % (paramName)
1537
1538 def _gen_replay_create_image(self):
1539 ci_body = []
1540 ci_body.append(' imageObj local_imageObj;')
1541 ci_body.append(' VkDevice remappedDevice = m_objMapper.remap_devices(pPacket->device);')
1542 ci_body.append(' if (remappedDevice == VK_NULL_HANDLE)')
1543 ci_body.append(' {')
1544 ci_body.append(' return glv_replay::GLV_REPLAY_ERROR;')
1545 ci_body.append(' }')
1546 ci_body.append(' replayResult = m_vkFuncs.real_vkCreateImage(remappedDevice, pPacket->pCreateInfo, &local_imageObj.replayImage);')
1547 ci_body.append(' if (replayResult == VK_SUCCESS)')
1548 ci_body.append(' {')
1549 ci_body.append(' m_objMapper.add_to_images_map(pPacket->pImage->handle, local_imageObj);')
1550 ci_body.append(' }')
1551 return "\n".join(ci_body)
1552
1553 def _gen_replay_create_buffer(self):
1554 cb_body = []
1555 cb_body.append(' bufferObj local_bufferObj;')
1556 cb_body.append(' VkDevice remappedDevice = m_objMapper.remap_devices(pPacket->device);')
1557 cb_body.append(' if (remappedDevice == VK_NULL_HANDLE)')
1558 cb_body.append(' {')
1559 cb_body.append(' return glv_replay::GLV_REPLAY_ERROR;')
1560 cb_body.append(' }')
1561 cb_body.append(' replayResult = m_vkFuncs.real_vkCreateBuffer(remappedDevice, pPacket->pCreateInfo, &local_bufferObj.replayBuffer);')
1562 cb_body.append(' if (replayResult == VK_SUCCESS)')
1563 cb_body.append(' {')
1564 cb_body.append(' m_objMapper.add_to_buffers_map(pPacket->pBuffer->handle, local_bufferObj);')
1565 cb_body.append(' }')
1566 return "\n".join(cb_body)
1567
1568 # Generate main replay case statements where actual replay API call is dispatched based on input packet data
1569 def _generate_replay(self):
1570 manually_replay_funcs = ['AllocMemory',
1571 'BeginCommandBuffer',
1572 'CreateDescriptorSetLayout',
1573 'CreateDevice',
1574 'CreateFramebuffer',
1575 'CreateGraphicsPipelines',
1576 'CreateInstance',
1577 'CreatePipelineLayout',
1578 'CreateRenderPass',
1579 'CreateShader',
1580 'CmdBeginRenderPass',
1581 'CmdBindDescriptorSets',
1582 'CmdBindVertexBuffers',
1583 'CmdPipelineBarrier',
1584 'QueuePresentWSI',
1585 'CmdWaitEvents',
1586 #'DestroyObject',
1587 'EnumeratePhysicalDevices',
1588 'FreeMemory',
1589 'FreeDescriptorSets',
1590 'FlushMappedMemoryRanges',
1591 #'GetGlobalExtensionInfo',
1592 #'GetImageSubresourceInfo',
1593 #'GetObjectInfo',
1594 #'GetPhysicalDeviceExtensionInfo',
1595 'GetPhysicalDeviceSurfaceSupportWSI',
Ian Elliott1d44f4e2015-08-10 15:23:43 -06001596 'GetSurfacePropertiesWSI',
1597 'GetSurfaceFormatsWSI',
1598 'GetSurfacePresentModesWSI',
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001599 'CreateSwapChainWSI',
Ian Elliott1d44f4e2015-08-10 15:23:43 -06001600 'GetSwapChainImagesWSI',
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001601 #'GetPhysicalDeviceInfo',
1602 'MapMemory',
1603 #'QueuePresentWSI',
1604 'QueueSubmit',
1605 #'StorePipeline',
1606 'UnmapMemory',
1607 'UpdateDescriptorSets',
1608 'WaitForFences',
Jon Ashburncaae0492015-08-13 16:49:08 -06001609 'DbgCreateMsgCallback',
1610 'DbgDestroyMsgCallback',
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001611 'CreateCommandBuffer',
1612 ]
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001613
1614 # validate the manually_replay_funcs list
1615 protoFuncs = [proto.name for proto in self.protos]
1616 for func in manually_replay_funcs:
1617 if func not in protoFuncs:
1618 sys.exit("Entry '%s' in manually_replay_funcs list is not in the vulkan function prototypes" % func)
1619
1620 # map protos to custom functions if body is fully custom
1621 custom_body_dict = {'CreateImage': self._gen_replay_create_image,
1622 'CreateBuffer': self._gen_replay_create_buffer }
1623 # multi-gpu Open funcs w/ list of local params to create
1624 custom_open_params = {'OpenSharedMemory': (-1,),
1625 'OpenSharedSemaphore': (-1,),
1626 'OpenPeerMemory': (-1,),
1627 'OpenPeerImage': (-1, -2,)}
1628 # Functions that create views are unique from other create functions
1629 create_view_list = ['CreateBufferView', 'CreateImageView', 'CreateAttachmentView', 'CreateComputePipeline']
1630 # Functions to treat as "Create' that don't have 'Create' in the name
1631 special_create_list = ['LoadPipeline', 'LoadPipelineDerivative', 'AllocMemory', 'GetDeviceQueue', 'PinSystemMemory', 'AllocDescriptorSets']
1632 # A couple funcs use do while loops
1633 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'}
1634 rbody = []
1635 rbody.append('%s' % self.lineinfo.get())
1636 rbody.append('glv_replay::GLV_REPLAY_RESULT vkReplay::replay(glv_trace_packet_header *packet)')
1637 rbody.append('{')
1638 rbody.append(' glv_replay::GLV_REPLAY_RESULT returnValue = glv_replay::GLV_REPLAY_SUCCESS;')
1639 rbody.append(' VkResult replayResult = VK_ERROR_UNKNOWN;')
1640 rbody.append(' switch (packet->packet_id)')
1641 rbody.append(' {')
1642 rbody.append(' case GLV_TPI_VK_vkApiVersion:')
1643 rbody.append(' {')
1644 rbody.append(' packet_vkApiVersion* pPacket = (packet_vkApiVersion*)(packet->pBody);')
1645 rbody.append(' if (pPacket->version != VK_API_VERSION)')
1646 rbody.append(' {')
1647 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));')
1648 rbody.append(' returnValue = glv_replay::GLV_REPLAY_ERROR;')
1649 rbody.append(' }')
1650 rbody.append(' break;')
1651 rbody.append(' }')
1652 for proto in self.protos:
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001653 ret_value = False
1654 create_view = False
1655 create_func = False
1656 # TODO : How to handle void* return of GetProcAddr?
1657 if ('void' not in proto.ret.lower()) and ('size_t' not in proto.ret) and (proto.name not in custom_body_dict):
1658 ret_value = True
1659 if proto.name in create_view_list:
1660 create_view = True
1661 elif 'Create' in proto.name or proto.name in special_create_list:
1662 create_func = True
1663 rbody.append(' case GLV_TPI_VK_vk%s:' % proto.name)
1664 rbody.append(' {')
1665 rbody.append(' packet_vk%s* pPacket = (packet_vk%s*)(packet->pBody);' % (proto.name, proto.name))
1666 if proto.name in manually_replay_funcs:
1667 if ret_value == True:
1668 rbody.append(' replayResult = manually_replay_vk%s(pPacket);' % proto.name)
1669 else:
1670 rbody.append(' manually_replay_vk%s(pPacket);' % proto.name)
1671 elif proto.name in custom_body_dict:
1672 rbody.append(custom_body_dict[proto.name]())
1673 else:
1674 if proto.name in custom_open_params:
1675 for pidx in custom_open_params[proto.name]:
1676 rbody.append(' %s local_%s;' % (proto.params[pidx].ty.replace('const ', '').strip('*'), proto.params[pidx].name))
1677 elif create_view:
1678 rbody.append(' %s createInfo;' % (proto.params[1].ty.strip('*').replace('const ', '')))
1679 rbody.append(' memcpy(&createInfo, pPacket->pCreateInfo, sizeof(%s));' % (proto.params[1].ty.strip('*').replace('const ', '')))
1680 if 'CreateComputePipeline' == proto.name:
1681 rbody.append(' createInfo.cs.shader.handle = m_objMapper.remap_shaders(pPacket->pCreateInfo->cs.shader.handle);')
1682 elif 'CreateBufferView' == proto.name:
1683 rbody.append(' createInfo.buffer.handle = m_objMapper.remap_buffers(pPacket->pCreateInfo->buffer.handle);')
1684 else:
1685 rbody.append(' createInfo.image.handle = m_objMapper.remap_images(pPacket->pCreateInfo->image.handle);')
1686 rbody.append(' %s local_%s;' % (proto.params[-1].ty.strip('*').replace('const ', ''), proto.params[-1].name))
1687 elif create_func: # Declare local var to store created handle into
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001688 if 'AllocDescriptorSets' == proto.name:
Jon Ashburn9e8755b2015-08-10 08:53:44 -06001689 p_ty = proto.params[-1].ty.strip('*').replace('const ', '')
1690 rbody.append(' %s* local_%s = (%s*)malloc(pPacket->count * sizeof(%s));' % (p_ty, proto.params[-1].name, p_ty, p_ty))
1691 rbody.append(' VkDescriptorSetLayout* local_pSetLayouts = (VkDescriptorSetLayout*)malloc(pPacket->count * sizeof(VkDescriptorSetLayout));')
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001692 rbody.append(' for (uint32_t i = 0; i < pPacket->count; i++)')
1693 rbody.append(' {')
Jon Ashburn9e8755b2015-08-10 08:53:44 -06001694 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 -06001695 rbody.append(' }')
Jon Ashburn9e8755b2015-08-10 08:53:44 -06001696 else:
1697 rbody.append(' %s local_%s;' % (proto.params[-1].ty.strip('*').replace('const ', ''), proto.params[-1].name))
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001698 elif proto.name == 'ResetFences':
1699 rbody.append(' VkFence* fences = GLV_NEW_ARRAY(VkFence, pPacket->fenceCount);')
1700 rbody.append(' for (uint32_t i = 0; i < pPacket->fenceCount; i++)')
1701 rbody.append(' {')
1702 rbody.append(' fences[i].handle = m_objMapper.remap_fences(pPacket->%s[i].handle);' % (proto.params[-1].name))
1703 rbody.append(' }')
1704 elif proto.name in do_while_dict:
1705 rbody.append(' do {')
1706
1707 for p in proto.params:
1708 if create_func or create_view:
1709 if p.name != proto.params[-1].name:
1710 rbody.append(self._remap_packet_param(proto.name, p.ty, p.name))
1711 else:
1712 rbody.append(self._remap_packet_param(proto.name, p.ty, p.name))
1713
1714 if proto.name == 'DestroyInstance':
1715 rbody.append(' if (m_vkFuncs.real_vkDbgDestroyMsgCallback != NULL)')
1716 rbody.append(' {')
1717 rbody.append(' m_vkFuncs.real_vkDbgDestroyMsgCallback(remappedinstance, m_dbgMsgCallbackObj);')
1718 rbody.append(' }')
1719 # TODO: need a better way to indicate which extensions should be mapped to which Get*ProcAddr
1720 elif proto.name == 'GetInstanceProcAddr':
1721 for iProto in self.protos:
1722 if 'Dbg' in iProto.name or 'GetPhysicalDeviceSurfaceSupportWSI' in iProto.name:
1723 rbody.append(' if (strcmp(pPacket->pName, "vk%s") == 0) {' % (iProto.name))
1724 rbody.append(' m_vkFuncs.real_vk%s = (PFN_vk%s)vk%s(remappedinstance, pPacket->pName);' % (iProto.name, iProto.name, proto.name))
1725 rbody.append(' }')
1726 elif proto.name == 'GetDeviceProcAddr':
1727 for dProto in self.protos:
1728 if 'WSI' in dProto.name:
1729 rbody.append(' if (strcmp(pPacket->pName, "vk%s") == 0) {' % (dProto.name))
1730 rbody.append(' m_vkFuncs.real_vk%s = (PFN_vk%s)vk%s(remappeddevice, pPacket->pName);' % (dProto.name, dProto.name, proto.name))
1731 rbody.append(' }')
1732
1733 # build the call to the "real_" entrypoint
1734 rr_string = ' '
1735 if ret_value:
1736 rr_string = ' replayResult = '
1737 rr_string += 'm_vkFuncs.real_vk%s(' % proto.name
1738 for p in proto.params:
1739 # For last param of Create funcs, pass address of param
1740 if create_func:
Jon Ashburn9e8755b2015-08-10 08:53:44 -06001741 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 -06001742 rr_string += 'local_%s, ' % p.name
Jon Ashburn9e8755b2015-08-10 08:53:44 -06001743 elif p.name == proto.params[-1].name:
1744 rr_string += '&local_%s, ' % p.name
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001745 else:
1746 rr_string += '%s, ' % self._get_packet_param(proto.name, p.ty, p.name)
1747 else:
1748 rr_string += '%s, ' % self._get_packet_param(proto.name, p.ty, p.name)
1749 rr_string = '%s);' % rr_string[:-2]
1750 if proto.name in custom_open_params:
1751 rr_list = rr_string.split(', ')
1752 for pidx in custom_open_params[proto.name]:
1753 rr_list[pidx] = '&local_%s' % proto.params[pidx].name
1754 rr_string = ', '.join(rr_list)
1755 rr_string += ');'
1756 elif create_view:
1757 rr_list = rr_string.split(', ')
1758 rr_list[-2] = '&createInfo'
1759 rr_list[-1] = '&local_%s);' % proto.params[-1].name
1760 rr_string = ', '.join(rr_list)
1761 # this is a sneaky shortcut to use generic create code below to add_to_map
1762 create_func = True
1763 elif proto.name == 'AllocDescriptorSets':
1764 rr_string = rr_string.replace('pPacket->pSetLayouts', 'pLocalDescSetLayouts')
1765 elif proto.name == 'ResetFences':
1766 rr_string = rr_string.replace('pPacket->pFences', 'fences')
1767
1768 # insert the real_*(..) call
1769 rbody.append(rr_string)
1770
1771 # handle return values or anything that needs to happen after the real_*(..) call
1772 if 'DestroyDevice' in proto.name:
1773 rbody.append(' if (replayResult == VK_SUCCESS)')
1774 rbody.append(' {')
1775 rbody.append(' m_pCBDump = NULL;')
1776 rbody.append(' m_pDSDump = NULL;')
1777 #TODO138 : disabling snapshot
1778 #rbody.append(' m_pGlvSnapshotPrint = NULL;')
1779 rbody.append(' m_objMapper.rm_from_devices_map(pPacket->device);')
1780 rbody.append(' m_display->m_initedVK = false;')
1781 rbody.append(' }')
1782 elif 'DestroySwapChainWSI' in proto.name:
1783 rbody.append(' if (replayResult == VK_SUCCESS)')
1784 rbody.append(' {')
1785 rbody.append(' m_objMapper.rm_from_swapchainwsis_map(pPacket->swapChain.handle);')
1786 rbody.append(' }')
1787 elif 'DestroyInstance' in proto.name:
1788 rbody.append(' if (replayResult == VK_SUCCESS)')
1789 rbody.append(' {')
1790 rbody.append(' // TODO need to handle multiple instances and only clearing maps within an instance.')
1791 rbody.append(' // TODO this only works with a single instance used at any given time.')
1792 rbody.append(' m_objMapper.clear_all_map_handles();')
1793 rbody.append(' }')
1794 elif 'AllocDescriptorSets' in proto.name:
1795 rbody.append(' if (replayResult == VK_SUCCESS)')
1796 rbody.append(' {')
Jon Ashburn9e8755b2015-08-10 08:53:44 -06001797 rbody.append(' for (uint32_t i = 0; i < pPacket->count; i++) {')
1798 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 -06001799 rbody.append(' }')
1800 rbody.append(' }')
Jon Ashburn9e8755b2015-08-10 08:53:44 -06001801 rbody.append(' free(local_pSetLayouts);')
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001802 rbody.append(' free(local_pDescriptorSets);')
1803 elif proto.name == 'ResetFences':
1804 rbody.append(' GLV_DELETE(fences);')
1805 elif create_func: # save handle mapping if create successful
1806 rbody.append(' if (replayResult == VK_SUCCESS)')
1807 rbody.append(' {')
1808 clean_type = proto.params[-1].ty.strip('*').replace('const ', '')
Jon Ashburncb622a12015-08-06 17:22:53 -06001809 VkNonDispObjType = [o for o in vulkan.object_non_dispatch_list]
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001810 if clean_type in VkNonDispObjType:
1811 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))
1812 else:
1813 rbody.append(' m_objMapper.add_to_%ss_map(*(pPacket->%s), local_%s);' % (clean_type.lower()[2:], proto.params[-1].name, proto.params[-1].name))
1814 if 'AllocMemory' == proto.name:
1815 rbody.append(' m_objMapper.add_entry_to_mapData(local_%s, pPacket->pAllocInfo->allocationSize);' % (proto.params[-1].name))
1816 rbody.append(' }')
1817 elif proto.name in do_while_dict:
1818 rbody[-1] = ' %s' % rbody[-1]
1819 rbody.append(' } while (%s);' % do_while_dict[proto.name])
1820 rbody.append(' if (pPacket->result != VK_NOT_READY || replayResult != VK_SUCCESS)')
1821 if ret_value:
1822 rbody.append(' CHECK_RETURN_VALUE(vk%s);' % proto.name)
1823 rbody.append(' break;')
1824 rbody.append(' }')
1825 rbody.append(' default:')
1826 rbody.append(' glv_LogWarning("Unrecognized packet_id %u, skipping.", packet->packet_id);')
1827 rbody.append(' returnValue = glv_replay::GLV_REPLAY_INVALID_ID;')
1828 rbody.append(' break;')
1829 rbody.append(' }')
1830 rbody.append(' return returnValue;')
1831 rbody.append('}')
1832 return "\n".join(rbody)
1833
1834class GlaveTraceHeader(Subcommand):
1835 def generate_header(self, extName):
1836 header_txt = []
Mark Lobodzinskif39d70c2015-08-14 14:24:50 -06001837 header_txt.append('#include "vktrace_vk_vk_packets.h"')
1838 header_txt.append('#include "vktrace_vk_packet_id.h"\n')
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001839 header_txt.append('void AttachHooks();')
1840 header_txt.append('void DetachHooks();')
1841 header_txt.append('void InitTracer(void);\n')
1842 return "\n".join(header_txt)
1843
1844 def generate_body(self):
1845 body = [self._generate_trace_func_ptrs(),
1846 self._generate_trace_func_protos(),
1847 self._generate_trace_real_func_ptr_protos()]
1848
1849 return "\n".join(body)
1850
1851class GlaveTraceC(Subcommand):
1852 def generate_header(self, extName):
1853 header_txt = []
Mark Lobodzinskif39d70c2015-08-14 14:24:50 -06001854 header_txt.append('#include "vktrace_platform.h"')
1855 header_txt.append('#include "vktrace_common.h"')
1856 header_txt.append('#include "vktrace_lib_helpers.h"')
1857 header_txt.append('#include "vktrace_vk_vk.h"')
1858 header_txt.append('#include "vktrace_vk_vk_debug_report_lunarg.h"')
1859 header_txt.append('#include "vktrace_vk_vk_wsi_swapchain.h"')
1860 header_txt.append('#include "vktrace_vk_vk_wsi_device_swapchain.h"')
1861 header_txt.append('#include "vktrace_interconnect.h"')
1862 header_txt.append('#include "vktrace_filelike.h"')
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001863 header_txt.append('#include "vk_struct_size_helper.h"')
1864 header_txt.append('#ifdef WIN32')
1865 header_txt.append('#include "mhook/mhook-lib/mhook.h"')
1866 header_txt.append('#else')
1867 header_txt.append('#include <pthread.h>\n')
1868 header_txt.append('#endif')
Mark Lobodzinskif39d70c2015-08-14 14:24:50 -06001869 header_txt.append('#include "vktrace_trace_packet_utils.h"')
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001870 header_txt.append('#include <stdio.h>')
1871 return "\n".join(header_txt)
1872
1873 def generate_body(self):
1874 body = [self._generate_func_ptr_assignments(),
1875 self._generate_attach_hooks(),
1876 self._generate_detach_hooks(),
1877 self._generate_init_funcs(),
1878 self._generate_trace_funcs(self.extName)]
1879
1880 return "\n".join(body)
1881
1882class GlavePacketID(Subcommand):
1883 def generate_header(self, extName):
1884 header_txt = []
1885 header_txt.append('#pragma once\n')
Mark Lobodzinskif39d70c2015-08-14 14:24:50 -06001886 header_txt.append('#include "vktrace_trace_packet_utils.h"')
1887 header_txt.append('#include "vktrace_trace_packet_identifiers.h"')
1888 header_txt.append('#include "vktrace_interconnect.h"')
1889 header_txt.append('#include "vktrace_vk_vk_packets.h"')
1890 header_txt.append('#include "vktrace_vk_vk_debug_report_lunarg_packets.h"')
1891 #header_txt.append('#include "vktrace_vk_vk_wsi_lunarg_packets.h"')
1892 header_txt.append('#include "vktrace_vk_vk_wsi_swapchain_packets.h"')
1893 header_txt.append('#include "vktrace_vk_vk_wsi_device_swapchain_packets.h"')
Jon Ashburncb622a12015-08-06 17:22:53 -06001894 #header_txt.append('#include "vk_enum_string_helper.h"')
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001895 header_txt.append('#ifndef _WIN32')
1896 header_txt.append(' #pragma GCC diagnostic ignored "-Wwrite-strings"')
1897 header_txt.append('#endif')
Jon Ashburncb622a12015-08-06 17:22:53 -06001898 #header_txt.append('#include "vk_struct_string_helper.h"')
1899 #header_txt.append('#include "vk_wsi_swapchain_struct_string_helper.h"')
1900 #header_txt.append('#include "vk_wsi_device_swapchain_struct_string_helper.h"')
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001901 header_txt.append('#ifndef _WIN32')
1902 header_txt.append(' #pragma GCC diagnostic warning "-Wwrite-strings"')
1903 header_txt.append('#endif')
Jon Ashburncb622a12015-08-06 17:22:53 -06001904 #header_txt.append('#include "vk_wsi_swapchain_enum_string_helper.h"')
1905 #header_txt.append('#include "vk_wsi_device_swapchain_enum_string_helper.h"')
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001906 header_txt.append('#if defined(WIN32)')
1907 header_txt.append('#define snprintf _snprintf')
1908 header_txt.append('#endif')
1909 header_txt.append('#define SEND_ENTRYPOINT_ID(entrypoint) ;')
1910 header_txt.append('//#define SEND_ENTRYPOINT_ID(entrypoint) glv_TraceInfo(#entrypoint);\n')
1911 header_txt.append('#define SEND_ENTRYPOINT_PARAMS(entrypoint, ...) ;')
1912 header_txt.append('//#define SEND_ENTRYPOINT_PARAMS(entrypoint, ...) glv_TraceInfo(entrypoint, __VA_ARGS__);\n')
1913 header_txt.append('#define CREATE_TRACE_PACKET(entrypoint, buffer_bytes_needed) \\')
1914 header_txt.append(' pHeader = glv_create_trace_packet(GLV_TID_VULKAN, GLV_TPI_VK_##entrypoint, sizeof(packet_##entrypoint), buffer_bytes_needed);\n')
1915 header_txt.append('#define FINISH_TRACE_PACKET() \\')
1916 header_txt.append(' glv_finalize_trace_packet(pHeader); \\')
1917 header_txt.append(' glv_write_trace_packet(pHeader, glv_trace_get_trace_file()); \\')
1918 header_txt.append(' glv_delete_trace_packet(&pHeader);')
1919 return "\n".join(header_txt)
1920
1921 def generate_body(self):
1922 body = [self._generate_packet_id_enum(),
1923 self._generate_packet_id_name_func(),
Jon Ashburncb622a12015-08-06 17:22:53 -06001924# self._generate_stringify_func(),
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001925 self._generate_interp_func()]
1926
1927 return "\n".join(body)
1928
1929class GlaveCoreTracePackets(Subcommand):
1930 def generate_header(self, extName):
1931 header_txt = []
1932 header_txt.append('#pragma once\n')
1933 header_txt.append('#include "vulkan.h"')
Mark Lobodzinskif39d70c2015-08-14 14:24:50 -06001934 header_txt.append('#include "vktrace_trace_packet_utils.h"\n')
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001935 return "\n".join(header_txt)
1936
1937 def generate_body(self):
1938 body = [self._generate_struct_util_funcs(),
1939 self._generate_interp_funcs()]
1940
1941 return "\n".join(body)
1942
1943class GlaveExtTraceHeader(Subcommand):
1944 def generate_header(self, extName):
1945 header_txt = []
1946 header_txt.append('#pragma once\n')
1947 header_txt.append('#include "vulkan.h"')
1948 header_txt.append('#include "%s.h"' % extName.lower())
1949 return "\n".join(header_txt)
1950
1951 def generate_body(self):
1952 body = [self._generate_trace_func_ptrs_ext(self.extName),
1953 self._generate_trace_func_protos_ext(self.extName)]
1954
1955 return "\n".join(body)
1956
1957class GlaveExtTraceC(Subcommand):
1958 def generate_header(self, extName):
1959 header_txt = []
Mark Lobodzinskif39d70c2015-08-14 14:24:50 -06001960 header_txt.append('#include "vktrace_platform.h"')
1961 header_txt.append('#include "vktrace_common.h"')
Jon Ashburncb622a12015-08-06 17:22:53 -06001962 if extName == "vk_wsi_device_swapchain":
1963 header_txt.append('#include "vk_wsi_swapchain.h"')
Mark Lobodzinskif39d70c2015-08-14 14:24:50 -06001964 header_txt.append('#include "vktrace_vk_%s.h"' % extName.lower())
1965 header_txt.append('#include "vktrace_vk_%s_packets.h"' % extName.lower())
1966 header_txt.append('#include "vktrace_vk_packet_id.h"')
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001967 header_txt.append('#include "vk_struct_size_helper.h"')
1968 header_txt.append('#include "%s_struct_size_helper.h"' % extName.lower())
1969 header_txt.append('#ifdef WIN32')
1970 header_txt.append('#include "mhook/mhook-lib/mhook.h"')
1971 header_txt.append('#endif')
1972 return "\n".join(header_txt)
1973
1974 def generate_body(self):
1975 body = [self._generate_func_ptr_assignments_ext(self.extName),
1976 self._generate_trace_funcs(self.extName)]
1977
1978 return "\n".join(body)
1979
1980class GlaveExtTracePackets(Subcommand):
1981 def generate_header(self, extName):
1982 header_txt = []
1983 header_txt.append('#pragma once\n')
1984 header_txt.append('#include "%s.h"' % extName.lower())
Mark Lobodzinskif39d70c2015-08-14 14:24:50 -06001985 header_txt.append('#include "vktrace_trace_packet_utils.h"\n')
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06001986 return "\n".join(header_txt)
1987
1988 def generate_body(self):
1989 body = [self._generate_interp_funcs_ext(self.extName)]
1990
1991 return "\n".join(body)
1992
1993class GlaveReplayVkFuncPtrs(Subcommand):
1994 def generate_header(self, extName):
1995 header_txt = []
1996 header_txt.append('#pragma once\n')
1997 header_txt.append('#if defined(PLATFORM_LINUX) || defined(XCB_NVIDIA)')
1998 header_txt.append('#include <xcb/xcb.h>\n')
1999 header_txt.append('#endif')
2000 header_txt.append('#include "vulkan.h"')
2001 header_txt.append('#include "vk_debug_report_lunarg.h"')
2002 header_txt.append('#include "vk_wsi_swapchain.h"')
2003 header_txt.append('#include "vk_wsi_device_swapchain.h"')
2004
2005 def generate_body(self):
2006 body = [self._generate_replay_func_ptrs()]
2007 return "\n".join(body)
2008
2009class GlaveReplayObjMapperHeader(Subcommand):
2010 def generate_header(self, extName):
2011 header_txt = []
2012 header_txt.append('#pragma once\n')
2013 header_txt.append('#include <set>')
2014 header_txt.append('#include <map>')
2015 header_txt.append('#include <vector>')
2016 header_txt.append('#include <string>')
2017 header_txt.append('#include "vulkan.h"')
2018 header_txt.append('#include "vk_debug_report_lunarg.h"')
2019 header_txt.append('#include "vk_wsi_swapchain.h"')
2020 header_txt.append('#include "vk_wsi_device_swapchain.h"')
2021 return "\n".join(header_txt)
2022
2023 def generate_body(self):
2024 body = [self._generate_replay_objmapper_class()]
2025 return "\n".join(body)
2026
2027class GlaveReplayC(Subcommand):
2028 def generate_header(self, extName):
2029 header_txt = []
Mark Lobodzinskif39d70c2015-08-14 14:24:50 -06002030 header_txt.append('#include "vkreplay_vkreplay.h"\n')
2031 header_txt.append('#include "vkreplay.h"\n')
2032 header_txt.append('#include "vkreplay_main.h"\n')
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06002033 header_txt.append('#include <algorithm>')
2034 header_txt.append('#include <queue>')
2035 header_txt.append('\n')
2036 header_txt.append('extern "C" {')
Mark Lobodzinskif39d70c2015-08-14 14:24:50 -06002037 header_txt.append('#include "vktrace_vk_vk_packets.h"')
2038 header_txt.append('#include "vktrace_vk_vk_debug_report_lunarg_packets.h"')
2039 #header_txt.append('#include "vktrace_vk_vk_wsi_lunarg_packets.h"')
2040 header_txt.append('#include "vktrace_vk_vk_wsi_swapchain_packets.h"')
2041 header_txt.append('#include "vktrace_vk_vk_wsi_device_swapchain_packets.h"')
2042 header_txt.append('#include "vktrace_vk_packet_id.h"')
Jon Ashburncb622a12015-08-06 17:22:53 -06002043 #header_txt.append('#include "vk_enum_string_helper.h"\n}\n')
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06002044
2045 return "\n".join(header_txt)
2046
2047 def generate_body(self):
2048 body = [self._generate_replay_init_funcs(),
2049 self._generate_replay()]
Jon Ashburncb622a12015-08-06 17:22:53 -06002050 body.append("}")
Jon Ashburn4d9cfd22015-08-04 13:35:25 -06002051 return "\n".join(body)
2052
2053def main():
2054 subcommands = {
2055 "glave-trace-h" : GlaveTraceHeader,
2056 "glave-trace-c" : GlaveTraceC,
2057 "glave-packet-id" : GlavePacketID,
2058 "glave-core-trace-packets" : GlaveCoreTracePackets,
2059 "glave-ext-trace-h" : GlaveExtTraceHeader,
2060 "glave-ext-trace-c" : GlaveExtTraceC,
2061 "glave-ext-trace-packets" : GlaveExtTracePackets,
2062 "glave-replay-vk-funcs" : GlaveReplayVkFuncPtrs,
2063 "glave-replay-obj-mapper-h" : GlaveReplayObjMapperHeader,
2064 "glave-replay-c" : GlaveReplayC,
2065 }
2066
2067 if len(sys.argv) < 2 or sys.argv[1] not in subcommands:
2068 print("Usage: %s <subcommand> [options]" % sys.argv[0])
2069 print
2070 print("Available subcommands are: %s" % " ".join(subcommands))
2071 exit(1)
2072
2073 subcmd = subcommands[sys.argv[1]](sys.argv[2])
2074 subcmd.run()
2075
2076if __name__ == "__main__":
2077 main()