layers: Addition of source_line_info.py script to simplify codegen debugging
vk-layer-generate.py and vk_helper.py now use added source_line_info.py script to insert comments throughout generated code indicating where the code was generated from.
diff --git a/source_line_info.py b/source_line_info.py
new file mode 100755
index 0000000..0d6f07e
--- /dev/null
+++ b/source_line_info.py
@@ -0,0 +1,40 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2015 LunarG, Inc.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+
+from inspect import currentframe, getframeinfo
+
+# This is a wrapper class for inspect module that returns a formatted line
+# with details of the source file and line number of python code who called
+# into this class. The result can them be added to codegen to simplify
+# debug as it shows where code was generated from.
+class sourcelineinfo():
+ def __init__(self):
+ self.general_prefix = "// CODEGEN : "
+ self.file_prefix = "file "
+ self.line_prefix = "line #"
+ self.enabled = True
+
+ def get(self):
+ if self.enabled:
+ frameinfo = getframeinfo(currentframe().f_back)
+ return "%s%s%s %s%s" % (self.general_prefix, self.file_prefix, frameinfo.filename, self.line_prefix, frameinfo.lineno)
+ return ""
diff --git a/vk-layer-generate.py b/vk-layer-generate.py
index 39158be..3431d89 100755
--- a/vk-layer-generate.py
+++ b/vk-layer-generate.py
@@ -31,6 +31,7 @@
import vulkan
import vk_helper
+from source_line_info import sourcelineinfo
def proto_is_global(proto):
if proto.params[0].ty == "VkInstance" or proto.params[0].ty == "VkPhysicalDevice" or proto.name == "CreateInstance" or proto.name == "GetGlobalExtensionInfo" or proto.name == "GetPhysicalDeviceExtensionInfo":
@@ -53,6 +54,7 @@
self.protos = vulkan.protos
self.no_addr = False
self.layer_name = ""
+ self.lineinfo = sourcelineinfo()
def run(self):
print(self.generate())
@@ -159,6 +161,7 @@
def _gen_create_msg_callback(self):
r_body = []
+ r_body.append('%s' % self.lineinfo.get())
r_body.append('VK_LAYER_EXPORT VkResult VKAPI vkDbgCreateMsgCallback(VkInstance instance, VkFlags msgFlags, const PFN_vkDbgMsgCallback pfnMsgCallback, void* pUserData, VkDbgMsgCallback* pMsgCallback)')
r_body.append('{')
r_body.append(' return layer_create_msg_callback(instance, instance_dispatch_table(instance), msgFlags, pfnMsgCallback, pUserData, pMsgCallback);')
@@ -167,6 +170,7 @@
def _gen_destroy_msg_callback(self):
r_body = []
+ r_body.append('%s' % self.lineinfo.get())
r_body.append('VK_LAYER_EXPORT VkResult VKAPI vkDbgDestroyMsgCallback(VkInstance instance, VkDbgMsgCallback msgCallback)')
r_body.append('{')
r_body.append(' return layer_destroy_msg_callback(instance, instance_dispatch_table(instance), msgCallback);')
@@ -176,6 +180,7 @@
def _gen_layer_get_global_extension_info(self, layer="Generic"):
ggei_body = []
if layer == 'APIDump' or layer == 'Generic':
+ ggei_body.append('%s' % self.lineinfo.get())
ggei_body.append('#define LAYER_EXT_ARRAY_SIZE 1')
ggei_body.append('static const VkExtensionProperties layerExts[LAYER_EXT_ARRAY_SIZE] = {')
ggei_body.append(' {')
@@ -186,6 +191,7 @@
ggei_body.append(' }')
ggei_body.append('};')
else:
+ ggei_body.append('%s' % self.lineinfo.get())
ggei_body.append('#define LAYER_EXT_ARRAY_SIZE 2')
ggei_body.append('static const VkExtensionProperties layerExts[LAYER_EXT_ARRAY_SIZE] = {')
ggei_body.append(' {')
@@ -202,6 +208,7 @@
ggei_body.append(' }')
ggei_body.append('};')
ggei_body.append('')
+ ggei_body.append('%s' % self.lineinfo.get())
ggei_body.append('VK_LAYER_EXPORT VkResult VKAPI vkGetGlobalExtensionInfo(VkExtensionInfoType infoType, uint32_t extensionIndex, size_t* pDataSize, void* pData)')
ggei_body.append('{')
ggei_body.append(' uint32_t *count;')
@@ -356,6 +363,7 @@
# add customized layer_intercept_proc
body = []
+ body.append('%s' % self.lineinfo.get())
body.append("static inline void* layer_intercept_proc(const char *name)")
body.append("{")
body.append(generate_get_proc_addr_check("name"))
@@ -394,6 +402,7 @@
exts = []
exts.append(self._gen_create_msg_callback())
exts.append(self._gen_destroy_msg_callback())
+ exts.append('%s' % self.lineinfo.get())
exts.append('uint64_t objTrackGetObjectsCount(VkObjectType type)')
exts.append('{')
exts.append(' return numTotalObjs;')
@@ -423,6 +432,7 @@
exts.append(' }')
exts.append(' return VK_SUCCESS;')
exts.append('}')
+ exts.append('%s' % self.lineinfo.get())
exts.append('uint64_t objTrackGetObjectsOfTypeCount(VkObjectType type)')
exts.append('{')
exts.append(' return numObjs[type];')
@@ -457,6 +467,7 @@
def _generate_layer_gpa_function(self, extensions=[], instance_extensions=[]):
func_body = []
+ func_body.append('%s' % self.lineinfo.get())
func_body.append("VK_LAYER_EXPORT void* VKAPI vkGetDeviceProcAddr(VkDevice device, const char* funcName)\n"
"{\n"
" void* addr;\n"
@@ -489,6 +500,7 @@
' return %s%s%s;' % (extra_space, ext_name, cpp_prefix, ext_name, cpp_postfix))
if 0 != len(ext_enable):
func_body.append(' }')
+ func_body.append('%s' % self.lineinfo.get())
func_body.append(" {\n"
" if (pDisp->GetDeviceProcAddr == NULL)\n"
" return NULL;\n"
@@ -527,9 +539,11 @@
def _generate_layer_initialization(self, init_opts=False, prefix='vk', lockname=None, condname=None):
func_body = ["#include \"vk_dispatch_table_helper.h\""]
+ func_body.append('%s' % self.lineinfo.get())
func_body.append('static void init%s(void)\n'
'{\n' % self.layer_name)
if init_opts:
+ func_body.append('%s' % self.lineinfo.get())
func_body.append(' const char *strOpt;')
func_body.append(' // initialize %s options' % self.layer_name)
func_body.append(' getLayerOptionEnum("%sReportLevel", (uint32_t *) &g_reportFlags);' % self.layer_name)
@@ -546,8 +560,8 @@
func_body.append(' g_logFile = stdout;')
func_body.append(' }')
func_body.append('')
-
if lockname is not None:
+ func_body.append('%s' % self.lineinfo.get())
func_body.append(" if (!%sLockInitialized)" % lockname)
func_body.append(" {")
func_body.append(" // TODO/TBD: Need to delete this mutex sometime. How???")
@@ -620,6 +634,7 @@
table = ''
if proto_is_global(proto):
table = 'Instance'
+ funcs.append('%s' % self.lineinfo.get())
if proto.ret != "void":
ret_val = "%s result = " % proto.ret
stmt = " return result;\n"
@@ -691,6 +706,7 @@
class APIDumpSubcommand(Subcommand):
def generate_header(self):
header_txt = []
+ header_txt.append('%s' % self.lineinfo.get())
header_txt.append('#include <fstream>')
header_txt.append('#include <iostream>')
header_txt.append('#include <string>')
@@ -721,6 +737,7 @@
header_txt.append(' }')
header_txt.append('}')
header_txt.append('')
+ header_txt.append('%s' % self.lineinfo.get())
header_txt.append('#include "loader_platform.h"')
header_txt.append('#include "vkLayer.h"')
header_txt.append('#include "vk_struct_string_helper_cpp.h"')
@@ -738,6 +755,7 @@
header_txt.append('static int printLockInitialized = 0;')
header_txt.append('static loader_platform_thread_mutex printLock;')
header_txt.append('')
+ header_txt.append('%s' % self.lineinfo.get())
header_txt.append('#define MAX_TID 513')
header_txt.append('static loader_platform_thread_id tidMapping[MAX_TID] = {0};')
header_txt.append('static uint32_t maxTID = 0;')
@@ -777,6 +795,7 @@
def generate_init(self):
func_body = []
+ func_body.append('%s' % self.lineinfo.get())
func_body.append('#include "vk_dispatch_table_helper.h"')
func_body.append('#include "layers_config.h"')
func_body.append('')
@@ -811,6 +830,7 @@
func_body.append(' }')
func_body.append(' }')
func_body.append('')
+ func_body.append('%s' % self.lineinfo.get())
func_body.append(' char const*const noAddrStr = getLayerOption("APIDumpNoAddr");')
func_body.append(' if(noAddrStr != NULL)')
func_body.append(' {')
@@ -838,6 +858,7 @@
func_body.append(' }')
func_body.append(' }')
func_body.append('')
+ func_body.append('%s' % self.lineinfo.get())
func_body.append(' ConfigureOutputStream(writeToFile, flushAfterWrite);')
func_body.append('')
func_body.append(' if (!printLockInitialized)')
@@ -867,7 +888,8 @@
ret_val = "%s result = " % proto.ret
stmt = " return result;\n"
f_open = 'loader_platform_thread_lock_mutex(&printLock);\n '
- log_func = ' if (StreamControl::writeAddress == true) {'
+ log_func = '%s\n' % self.lineinfo.get()
+ log_func += ' if (StreamControl::writeAddress == true) {'
log_func += '\n (*outputStream) << "t{" << getTIDIndex() << "} vk%s(' % proto.name
log_func_no_addr = '\n (*outputStream) << "t{" << getTIDIndex() << "} vk%s(' % proto.name
f_close = '\n loader_platform_thread_unlock_mutex(&printLock);'
@@ -913,12 +935,14 @@
log_func += ';'
log_func_no_addr += ';'
log_func += '\n }\n else {%s;\n }' % log_func_no_addr;
+ log_func += '\n%s' % self.lineinfo.get()
#print("Proto %s has param_dict: %s" % (proto.name, sp_param_dict))
if len(sp_param_dict) > 0:
indent = ' '
log_func += '\n%sif (g_APIDumpDetailed) {' % indent
indent += ' '
i_decl = False
+ log_func += '\n%s' % self.lineinfo.get()
log_func += '\n%sstring tmp_str;' % indent
for sp_index in sp_param_dict:
#print("sp_index: %s" % str(sp_index))
@@ -927,6 +951,7 @@
local_name = proto.params[sp_index].name
if '*' not in proto.params[sp_index].ty:
local_name = '&%s' % proto.params[sp_index].name
+ log_func += '\n%s' % self.lineinfo.get()
log_func += '\n%sif (%s) {' % (indent, local_name)
indent += ' '
log_func += '\n%stmp_str = %s(%s, " ");' % (indent, cis_print_func, local_name)
@@ -949,6 +974,7 @@
i_decl = True
log_func += '\n%sif (%s) {' % (indent, proto.params[sp_index].name)
indent += ' '
+ log_func += '\n%s' % self.lineinfo.get()
log_func += '\n%sfor (i = 0; i < %s; i++) {' % (indent, sp_param_dict[sp_index])
indent += ' '
log_func += '\n%s%s' % (indent, cis_print_func)
@@ -1033,6 +1059,7 @@
class ObjectTrackerSubcommand(Subcommand):
def generate_header(self):
header_txt = []
+ header_txt.append('%s' % self.lineinfo.get())
header_txt.append('#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <inttypes.h>\n')
header_txt.append('#include "loader_platform.h"\n')
header_txt.append('#include "object_track.h"\n\n')
@@ -1053,6 +1080,7 @@
header_txt.append('// Objects stored in a global map w/ struct containing basic info')
header_txt.append('unordered_map<VkObject, OBJTRACK_NODE*> objMap;')
header_txt.append('')
+ header_txt.append('%s' % self.lineinfo.get())
header_txt.append('#define NUM_OBJECT_TYPES (VK_NUM_OBJECT_TYPE + (VK_OBJECT_TYPE_SWAP_CHAIN_WSI - VK_OBJECT_TYPE_DISPLAY_WSI))')
header_txt.append('')
header_txt.append('static uint64_t numObjs[NUM_OBJECT_TYPES] = {0};')
@@ -1076,7 +1104,7 @@
header_txt.append(' VkQueue queue;')
header_txt.append(' uint32_t refCount;')
header_txt.append('} OT_QUEUE_INFO;')
- header_txt.append('')
+ header_txt.append('%s' % self.lineinfo.get())
header_txt.append('// Global list of QueueInfo structures, one per queue')
header_txt.append('static OT_QUEUE_INFO *g_pQueueInfo = NULL;')
header_txt.append('')
@@ -1090,7 +1118,7 @@
header_txt.append(' }')
header_txt.append(' return index;')
header_txt.append('}')
- header_txt.append('')
+ header_txt.append('%s' % self.lineinfo.get())
header_txt.append('// Validate that object is in the object map')
header_txt.append('static void validate_object(const VkObject object)')
header_txt.append('{')
@@ -1118,7 +1146,7 @@
header_txt.append(' }')
header_txt.append(' }')
header_txt.append('}')
- header_txt.append('')
+ header_txt.append('%s' % self.lineinfo.get())
header_txt.append('// Add new queue to head of global queue list')
header_txt.append('static void addQueueInfo(uint32_t queueNodeIndex, VkQueue queue)')
header_txt.append('{')
@@ -1156,7 +1184,7 @@
header_txt.append(' }')
header_txt.append(' g_pQueueInfo = pQueueInfo;')
header_txt.append('}')
- header_txt.append('')
+ header_txt.append('%s' % self.lineinfo.get())
header_txt.append('static void create_obj(VkObject vkObj, VkObjectType objType) {')
header_txt.append(' char str[1024];')
header_txt.append(' sprintf(str, "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64 , object_track_index++, string_VkObjectType(objType), reinterpret_cast<VkUintPtrLeast64>(vkObj));')
@@ -1208,7 +1236,7 @@
header_txt.append(' }')
header_txt.append(' }')
header_txt.append('}')
- header_txt.append('')
+ header_txt.append('%s' % self.lineinfo.get())
header_txt.append('// Reset selected flag state for an object node')
header_txt.append('static void reset_status(VkObject vkObj, VkObjectType objType, ObjectStatusFlags status_flag) {')
header_txt.append(' if (objMap.find(vkObj) != objMap.end()) {')
@@ -1249,7 +1277,7 @@
header_txt.append(' }')
header_txt.append(' }')
header_txt.append('}')
- header_txt.append('')
+ header_txt.append('%s' % self.lineinfo.get())
header_txt.append('// Check object status for selected flag state')
header_txt.append('static bool32_t validate_status(VkObject vkObj, VkObjectType objType, ObjectStatusFlags status_mask, ObjectStatusFlags status_flag, VkFlags msg_flags, OBJECT_TRACK_ERROR error_code, const char* fail_msg) {')
header_txt.append(' if (objMap.find(vkObj) != objMap.end()) {')
@@ -1320,6 +1348,7 @@
mutex_unlock = False
if 'QueueSubmit' in proto.name:
using_line = ' loader_platform_thread_lock_mutex(&objLock);\n'
+ using_line += '%s\n' % self.lineinfo.get()
using_line += ' set_status(fence, VK_OBJECT_TYPE_FENCE, OBJSTATUS_FENCE_IS_SUBMITTED);\n'
using_line += ' // TODO: Fix for updated memory reference mechanism\n'
using_line += ' // validate_memory_mapping_status(pMemRefs, memRefCount);\n'
@@ -1327,23 +1356,28 @@
mutex_unlock = True
elif 'QueueBindSparse' in proto.name:
using_line = ' loader_platform_thread_lock_mutex(&objLock);\n'
+ using_line += '%s\n' % self.lineinfo.get()
using_line += ' validateQueueFlags(queue, "%s");\n' % (proto.name)
mutex_unlock = True
elif 'QueueBindObject' in proto.name:
using_line = ' loader_platform_thread_lock_mutex(&objLock);\n'
+ using_line += '%s\n' % self.lineinfo.get()
using_line += ' validateObjectType("vk%s", objType, object);\n' % (proto.name)
mutex_unlock = True
elif 'GetObjectInfo' in proto.name:
using_line = ' loader_platform_thread_lock_mutex(&objLock);\n'
+ using_line += '%s\n' % self.lineinfo.get()
using_line += ' validateObjectType("vk%s", objType, object);\n' % (proto.name)
mutex_unlock = True
elif 'GetFenceStatus' in proto.name:
using_line = ' loader_platform_thread_lock_mutex(&objLock);\n'
+ using_line += '%s\n' % self.lineinfo.get()
using_line += ' // Warn if submitted_flag is not set\n'
using_line += ' validate_status(fence, VK_OBJECT_TYPE_FENCE, OBJSTATUS_FENCE_IS_SUBMITTED, OBJSTATUS_FENCE_IS_SUBMITTED, VK_DBG_REPORT_ERROR_BIT, OBJTRACK_INVALID_FENCE, "Status Requested for Unsubmitted Fence");\n'
mutex_unlock = True
elif 'WaitForFences' in proto.name:
using_line = ' loader_platform_thread_lock_mutex(&objLock);\n'
+ using_line += '%s\n' % self.lineinfo.get()
using_line += ' // Warn if waiting on unsubmitted fence\n'
using_line += ' for (uint32_t i = 0; i < fenceCount; i++) {\n'
using_line += ' validate_status(pFences[i], VK_OBJECT_TYPE_FENCE, OBJSTATUS_FENCE_IS_SUBMITTED, OBJSTATUS_FENCE_IS_SUBMITTED, VK_DBG_REPORT_ERROR_BIT, OBJTRACK_INVALID_FENCE, "Waiting for Unsubmitted Fence");\n'
@@ -1351,14 +1385,17 @@
mutex_unlock = True
elif 'MapMemory' in proto.name:
using_line = ' loader_platform_thread_lock_mutex(&objLock);\n'
+ using_line += '%s\n' % self.lineinfo.get()
using_line += ' set_status(mem, VK_OBJECT_TYPE_DEVICE_MEMORY, OBJSTATUS_GPU_MEM_MAPPED);\n'
mutex_unlock = True
elif 'UnmapMemory' in proto.name:
using_line = ' loader_platform_thread_lock_mutex(&objLock);\n'
+ using_line += '%s\n' % self.lineinfo.get()
using_line += ' reset_status(mem, VK_OBJECT_TYPE_DEVICE_MEMORY, OBJSTATUS_GPU_MEM_MAPPED);\n'
mutex_unlock = True
elif 'AllocDescriptor' in proto.name: # Allocates array of DSs
create_line = ' loader_platform_thread_lock_mutex(&objLock);\n'
+ create_line += '%s\n' % self.lineinfo.get()
create_line += ' for (uint32_t i = 0; i < *pCount; i++) {\n'
create_line += ' create_obj(pDescriptorSets[i], VK_OBJECT_TYPE_DESCRIPTOR_SET);\n'
create_line += ' }\n'
@@ -1367,9 +1404,11 @@
create_line = ' loader_platform_thread_lock_mutex(&objLock);\n'
create_line += ' if (result == VK_SUCCESS) {\n'
if 'CreateDevice' in proto.name:
+ create_line += '%s\n' % self.lineinfo.get()
create_line += ' enable_debug_report(pCreateInfo->extensionCount, pCreateInfo->pEnabledExtensions);\n'
create_line += ' createDeviceRegisterExtensions(pCreateInfo, *pDevice);\n'
elif 'CreateInstance' in proto.name:
+ create_line += '%s\n' % self.lineinfo.get()
create_line += ' enable_debug_report(pCreateInfo->extensionCount, pCreateInfo->pEnabledExtensions);\n'
create_line += ' VkLayerInstanceDispatchTable *pTable = instance_dispatch_table(*pInstance);\n'
create_line += ' debug_report_init_instance_extension_dispatch_table(\n'
@@ -1382,10 +1421,12 @@
if 'GetDeviceQueue' in proto.name:
destroy_line = ' loader_platform_thread_lock_mutex(&objLock);\n'
+ destroy_line += '%s\n' % self.lineinfo.get()
destroy_line += ' addQueueInfo(queueNodeIndex, *pQueue);\n'
destroy_line += ' loader_platform_thread_unlock_mutex(&objLock);\n'
elif 'DestroyObject' in proto.name:
destroy_line = ' loader_platform_thread_lock_mutex(&objLock);\n'
+ destroy_line += '%s\n' % self.lineinfo.get()
destroy_line += ' validateObjectType("vk%s", objType, object);\n' % (proto.name)
destroy_line += ' destroy_obj(%s);\n' % (proto.params[2].name)
destroy_line += ' loader_platform_thread_unlock_mutex(&objLock);\n'
@@ -1394,6 +1435,7 @@
using_line += ' VkLayerDispatchTable *pDisp = device_dispatch_table(device);\n'
destroy_line = ' deviceExtMap.erase(pDisp);\n'
destroy_line += ' loader_platform_thread_lock_mutex(&objLock);\n'
+ destroy_line += '%s\n' % self.lineinfo.get()
destroy_line += ' destroy_obj(device);\n'
destroy_line += ' // Report any remaining objects\n'
destroy_line += ' for (auto it = objMap.begin(); it != objMap.end(); ++it) {\n'
@@ -1428,10 +1470,12 @@
destroy_line += ' destroy_instance_dispatch_table(key);\n'
elif 'Free' in proto.name:
destroy_line = ' loader_platform_thread_lock_mutex(&objLock);\n'
+ destroy_line += '%s\n' % self.lineinfo.get()
destroy_line += ' destroy_obj(%s);\n' % (proto.params[1].name)
destroy_line += ' loader_platform_thread_unlock_mutex(&objLock);\n'
elif 'Destroy' in proto.name:
destroy_line = ' loader_platform_thread_lock_mutex(&objLock);\n'
+ destroy_line += '%s\n' % self.lineinfo.get()
destroy_line += ' destroy_obj(%s);\n' % (param0_name)
destroy_line += ' loader_platform_thread_unlock_mutex(&objLock);\n'
if len(object_params) > 0:
@@ -1478,6 +1522,7 @@
table_type = "device"
if 'CreateInstance' in proto.name:
dispatch_param = '*' + proto.params[1].name
+ funcs.append('%s' % self.lineinfo.get())
funcs.append('%s%s\n'
'{\n'
'%s'
@@ -1505,6 +1550,7 @@
class ThreadingSubcommand(Subcommand):
def generate_header(self):
header_txt = []
+ header_txt.append('%s' % self.lineinfo.get())
header_txt.append('#include <stdio.h>')
header_txt.append('#include <stdlib.h>')
header_txt.append('#include <string.h>')
@@ -1531,7 +1577,7 @@
header_txt.append('static loader_platform_thread_cond threadingCond;')
header_txt.append('static int printLockInitialized = 0;')
header_txt.append('static loader_platform_thread_mutex printLock;\n')
- header_txt.append('')
+ header_txt.append('%s' % self.lineinfo.get())
header_txt.append('static void useObject(VkObject object, const char* type)')
header_txt.append('{')
header_txt.append(' loader_platform_thread_id tid = loader_platform_get_thread_id();')
@@ -1556,6 +1602,7 @@
header_txt.append(' }')
header_txt.append(' loader_platform_thread_unlock_mutex(&threadingLock);')
header_txt.append('}')
+ header_txt.append('%s' % self.lineinfo.get())
header_txt.append('static void finishUsingObject(VkObject object)')
header_txt.append('{')
header_txt.append(' // Object is no longer in use')
@@ -1614,6 +1661,7 @@
return None
# Initialize in early calls
if proto.params[0].ty == "VkPhysicalDevice":
+ funcs.append('%s' % self.lineinfo.get())
funcs.append('%s%s\n'
'{\n'
' %s%s_dispatch_table(%s)->%s;\n'
@@ -1622,6 +1670,7 @@
return "\n".join(funcs)
# Functions changing command buffers need thread safe use of first parameter
if proto.params[0].ty == "VkCmdBuffer":
+ funcs.append('%s' % self.lineinfo.get())
funcs.append('%s%s\n'
'{\n'
' useObject((VkObject) %s, "%s");\n'
@@ -1677,6 +1726,7 @@
if len(checked_params) == 0:
return None
# Surround call with useObject and finishUsingObject for each checked_param
+ funcs.append('%s' % self.lineinfo.get())
funcs.append('%s%s' % (qual, decl))
funcs.append('{')
for param in checked_params:
diff --git a/vk_helper.py b/vk_helper.py
index 4a7dce5..46daad5 100755
--- a/vk_helper.py
+++ b/vk_helper.py
@@ -24,15 +24,14 @@
import argparse
import os
import sys
+from source_line_info import sourcelineinfo
-# code_gen.py overview
-# This script generates code based on input headers
-# Initially it's intended to support Mantle and VK headers and
-# generate wrappers functions that can be used to display
+# vk_helper.py overview
+# This script generates code based on vulkan input header
+# It generate wrappers functions that can be used to display
# structs in a human-readable txt format, as well as utility functions
# to print enum values as strings
-
def handle_args():
parser = argparse.ArgumentParser(description='Perform analysis of vogl trace.')
parser.add_argument('input_file', help='The input header file from which code will be generated.')
@@ -756,9 +755,12 @@
sh_funcs = []
# First generate prototypes for every struct
# XXX - REMOVE this comment
+ lineinfo = sourcelineinfo()
+ sh_funcs.append('%s' % lineinfo.get())
for s in sorted(self.struct_dict):
sh_funcs.append('string %s(const %s* pStruct, const string prefix);' % (self._get_sh_func_name(s), typedef_fwd_dict[s]))
sh_funcs.append('\n')
+ sh_funcs.append('%s' % lineinfo.get())
for s in sorted(self.struct_dict):
num_non_enum_elems = [(is_type(self.struct_dict[s][elem]['type'], 'enum') and not self.struct_dict[s][elem]['ptr']) for elem in self.struct_dict[s]].count(False)
stp_list = [] # stp == "struct to print" a list of structs for this API call that should be printed as structs
@@ -766,7 +768,9 @@
for m in sorted(self.struct_dict[s]):
if 'pNext' == self.struct_dict[s][m]['name'] or is_type(self.struct_dict[s][m]['type'], 'struct') or self.struct_dict[s][m]['array']:
stp_list.append(self.struct_dict[s][m])
+ sh_funcs.append('%s' % lineinfo.get())
sh_funcs.append('string %s(const %s* pStruct, const string prefix)\n{' % (self._get_sh_func_name(s), typedef_fwd_dict[s]))
+ sh_funcs.append('%s' % lineinfo.get())
indent = ' '
sh_funcs.append('%susing namespace StreamControl;' % (indent))
sh_funcs.append('%sstring final_str;' % (indent))
@@ -784,16 +788,16 @@
if 1 < stp_list[index]['full_type'].count('*'):
addr_char = ''
if (stp_list[index]['array'] and 'char' not in stp_list[index]['type']):
- sh_funcs.append('/* A */');
+ sh_funcs.append('%s' % lineinfo.get())
if stp_list[index]['dyn_array']:
- sh_funcs.append('/* AA */');
+ sh_funcs.append('%s' % lineinfo.get())
array_count = 'pStruct->%s' % (stp_list[index]['array_size'])
else:
- sh_funcs.append('/* AB */');
+ sh_funcs.append('%s' % lineinfo.get())
array_count = '%s' % (stp_list[index]['array_size'])
+ sh_funcs.append('%s' % lineinfo.get())
sh_funcs.append('%sstp_strs[%u] = "";' % (indent, index))
if not idx_ss_decl:
- sh_funcs.append('/* AC */');
sh_funcs.append('%sstringstream index_ss;' % (indent))
idx_ss_decl = True
sh_funcs.append('%sif (pStruct->%s) {' % (indent, stp_list[index]['name']))
@@ -803,81 +807,94 @@
sh_funcs.append('%sindex_ss.str("");' % (indent))
sh_funcs.append('%sindex_ss << i;' % (indent))
if is_type(stp_list[index]['type'], 'enum'):
- #sh_funcs.append('/* AD */');
+ sh_funcs.append('%s' % lineinfo.get())
addr_char = ''
#value_print = 'string_%s(%spStruct->%s)' % (self.struct_dict[s][m]['type'], deref, self.struct_dict[s][m]['name'])
sh_funcs.append('%sss[%u] << string_%s(pStruct->%s[i]);' % (indent, index, stp_list[index]['type'], stp_list[index]['name']))
sh_funcs.append('%sstp_strs[%u] += " " + prefix + "%s[" + index_ss.str() + "] = " + ss[%u].str() + "\\n";' % (indent, index, stp_list[index]['name'], index))
elif is_type(stp_list[index]['type'], 'struct'):
- #sh_funcs.append('/* AD */');
+ sh_funcs.append('%s' % lineinfo.get())
sh_funcs.append('%sss[%u] << %spStruct->%s[i];' % (indent, index, addr_char, stp_list[index]['name']))
sh_funcs.append('%stmp_str = %s(%spStruct->%s[i], extra_indent);' % (indent, self._get_sh_func_name(stp_list[index]['type']), addr_char, stp_list[index]['name']))
if self.no_addr:
- sh_funcs.append('/* AEA */');
+ sh_funcs.append('%s' % lineinfo.get())
sh_funcs.append('%sstp_strs[%u] += " " + prefix + "%s[" + index_ss.str() + "] (addr)\\n" + tmp_str;' % (indent, index, stp_list[index]['name']))
else:
- sh_funcs.append('/* AEB */');
+ sh_funcs.append('%s' % lineinfo.get())
sh_funcs.append('%sstp_strs[%u] += " " + prefix + "%s[" + index_ss.str() + "] (" + ss[%u].str() + ")\\n" + tmp_str;' % (indent, index, stp_list[index]['name'], index))
else:
- #sh_funcs.append('/* AD */');
+ sh_funcs.append('%s' % lineinfo.get())
addr_char = ''
sh_funcs.append('%sss[%u] << %spStruct->%s[i];' % (indent, index, addr_char, stp_list[index]['name']))
sh_funcs.append('%sstp_strs[%u] += " " + prefix + "%s[" + index_ss.str() + "] = " + ss[%u].str() + "\\n";' % (indent, index, stp_list[index]['name'], index))
+ sh_funcs.append('%s' % lineinfo.get())
sh_funcs.append('%sss[%u].str("");' % (indent, index))
indent = indent[4:]
sh_funcs.append('%s}' % (indent))
indent = indent[4:]
sh_funcs.append('%s}' % (indent))
elif (stp_list[index]['ptr']):
- sh_funcs.append('/* B */');
+ sh_funcs.append('%s' % lineinfo.get())
sh_funcs.append(' if (pStruct->%s) {' % stp_list[index]['name'])
if 'pNext' == stp_list[index]['name']:
+ sh_funcs.append('%s' % lineinfo.get())
sh_funcs.append(' tmp_str = dynamic_display((void*)pStruct->pNext, prefix);')
else:
if stp_list[index]['name'] in ['pImageViews', 'pBufferViews']:
# TODO : This is a quick hack to handle these arrays of ptrs
+ sh_funcs.append('%s' % lineinfo.get())
sh_funcs.append(' tmp_str = %s(&pStruct->%s[0], extra_indent);' % (self._get_sh_func_name(stp_list[index]['type']), stp_list[index]['name']))
else:
+ sh_funcs.append('%s' % lineinfo.get())
sh_funcs.append(' tmp_str = %s(pStruct->%s, extra_indent);' % (self._get_sh_func_name(stp_list[index]['type']), stp_list[index]['name']))
sh_funcs.append(' ss[%u] << %spStruct->%s;' % (index, addr_char, stp_list[index]['name']))
if self.no_addr:
+ sh_funcs.append('%s' % lineinfo.get())
sh_funcs.append(' stp_strs[%u] = " " + prefix + "%s (addr)\\n" + tmp_str;' % (index, stp_list[index]['name']))
else:
+ sh_funcs.append('%s' % lineinfo.get())
sh_funcs.append(' stp_strs[%u] = " " + prefix + "%s (" + ss[%u].str() + ")\\n" + tmp_str;' % (index, stp_list[index]['name'], index))
sh_funcs.append(' ss[%u].str("");' % (index))
sh_funcs.append(' }')
sh_funcs.append(' else')
sh_funcs.append(' stp_strs[%u] = "";' % index)
else:
- #sh_funcs.append('/* C */');
+ sh_funcs.append('%s' % lineinfo.get())
sh_funcs.append(' tmp_str = %s(&pStruct->%s, extra_indent);' % (self._get_sh_func_name(stp_list[index]['type']), stp_list[index]['name']))
sh_funcs.append(' ss[%u] << %spStruct->%s;' % (index, addr_char, stp_list[index]['name']))
if self.no_addr:
sh_funcs.append(' stp_strs[%u] = " " + prefix + "%s (addr)\\n" + tmp_str;' % (index, stp_list[index]['name']))
+ sh_funcs.append('%s' % lineinfo.get())
else:
sh_funcs.append(' stp_strs[%u] = " " + prefix + "%s (" + ss[%u].str() + ")\\n" + tmp_str;' % (index, stp_list[index]['name'], index))
+ sh_funcs.append('%s' % lineinfo.get())
sh_funcs.append(' ss[%u].str("");' % index)
# Now print one-line info for all data members
index = 0
final_str = ''
for m in sorted(self.struct_dict[s]):
- deref = ''
if not is_type(self.struct_dict[s][m]['type'], 'enum'):
if is_type(self.struct_dict[s][m]['type'], 'struct') and not self.struct_dict[s][m]['ptr']:
if self.no_addr:
+ sh_funcs.append('%s' % lineinfo.get())
sh_funcs.append(' ss[%u].str("addr");' % (index))
else:
+ sh_funcs.append('%s' % lineinfo.get())
sh_funcs.append(' ss[%u] << &pStruct->%s;' % (index, self.struct_dict[s][m]['name']))
elif 'bool' in self.struct_dict[s][m]['type'].lower():
+ sh_funcs.append('%s' % lineinfo.get())
sh_funcs.append(' ss[%u].str(pStruct->%s ? "TRUE" : "FALSE");' % (index, self.struct_dict[s][m]['name']))
elif 'uint8' in self.struct_dict[s][m]['type'].lower():
+ sh_funcs.append('%s' % lineinfo.get())
sh_funcs.append(' ss[%u] << (uint32_t)pStruct->%s;' % (index, self.struct_dict[s][m]['name']))
elif 'void' in self.struct_dict[s][m]['type'].lower() and self.struct_dict[s][m]['ptr']:
+ sh_funcs.append('%s' % lineinfo.get())
sh_funcs.append(' if (StreamControl::writeAddress)')
sh_funcs.append(' ss[%u] << pStruct->%s;' % (index, self.struct_dict[s][m]['name']))
sh_funcs.append(' else')
sh_funcs.append(' ss[%u].str("address");' % (index))
else:
+ sh_funcs.append('%s' % lineinfo.get())
(po, pa) = self._get_struct_print_formatted(self.struct_dict[s][m])
if "addr" in po: # or self.struct_dict[s][m]['ptr']:
sh_funcs.append(' ss[%u].str("addr");' % (index))
@@ -888,6 +905,7 @@
else:
# For an non-empty array of enums just print address w/ note that array will be displayed below
if self.struct_dict[s][m]['ptr']:
+ sh_funcs.append('%s' % lineinfo.get())
sh_funcs.append(' if (pStruct->%s)' % (self.struct_dict[s][m]['name']))
sh_funcs.append(' ss[%u] << pStruct->%s << " (See individual array values below)";' % (index, self.struct_dict[s][m]['name']))
sh_funcs.append(' else')
@@ -901,9 +919,11 @@
final_str = final_str[3:] # strip off the initial ' + '
if 0 != num_stps: # Append data for any embedded structs
final_str += " + %s" % " + ".join(['stp_strs[%u]' % n for n in reversed(range(num_stps))])
+ sh_funcs.append('%s' % lineinfo.get())
sh_funcs.append(' final_str = %s;' % final_str)
sh_funcs.append(' return final_str;\n}')
# Add function to return a string value for input void*
+ sh_funcs.append('%s' % lineinfo.get())
sh_funcs.append("string string_convert_helper(const void* toString, const string prefix)\n{")
sh_funcs.append(" using namespace StreamControl;")
sh_funcs.append(" stringstream ss;")
@@ -911,6 +931,7 @@
sh_funcs.append(' string final_str = prefix + ss.str();')
sh_funcs.append(" return final_str;")
sh_funcs.append("}")
+ sh_funcs.append('%s' % lineinfo.get())
# Add function to return a string value for input uint32_t
sh_funcs.append("string string_convert_helper(const uint32_t toString, const string prefix)\n{")
sh_funcs.append(" using namespace StreamControl;")
@@ -919,6 +940,7 @@
sh_funcs.append(' string final_str = prefix + ss.str();')
sh_funcs.append(" return final_str;")
sh_funcs.append("}")
+ sh_funcs.append('%s' % lineinfo.get())
# Add function to dynamically print out unknown struct
sh_funcs.append("string dynamic_display(const void* pStruct, const string prefix)\n{")
sh_funcs.append(" // Cast to APP_INFO ptr initially just to pull sType off struct")
@@ -941,6 +963,7 @@
sh_funcs.append(' break;')
sh_funcs.append(" default:")
sh_funcs.append(" return NULL;")
+ sh_funcs.append('%s' % lineinfo.get())
sh_funcs.append(" }")
sh_funcs.append("}")
return "\n".join(sh_funcs)