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