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