diff options
| author | Tobin Ehlis <tobin@lunarg.com> | 2015-06-12 12:49:01 -0600 |
|---|---|---|
| committer | Tobin Ehlis <tobin@lunarg.com> | 2015-06-19 14:02:16 -0600 |
| commit | 68e5c5d4ff322b52ebc08bd7fc644eb01bf2112e (patch) | |
| tree | 3c1e55944566952d1bd0823d1be9d4b2584fef67 | |
| parent | 790ac70cc96699b4244957a00f6a3bb1d27f2c8e (diff) | |
| download | usermoji-68e5c5d4ff322b52ebc08bd7fc644eb01bf2112e.tar.xz | |
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.
| -rwxr-xr-x | source_line_info.py | 40 | ||||
| -rwxr-xr-x | vk-layer-generate.py | 68 | ||||
| -rwxr-xr-x | vk_helper.py | 57 |
3 files changed, 139 insertions, 26 deletions
diff --git a/source_line_info.py b/source_line_info.py new file mode 100755 index 00000000..0d6f07ec --- /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 39158be5..3431d897 100755 --- a/vk-layer-generate.py +++ b/vk-layer-generate.py @@ -31,6 +31,7 @@ import re 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 @@ class Subcommand(object): self.protos = vulkan.protos self.no_addr = False self.layer_name = "" + self.lineinfo = sourcelineinfo() def run(self): print(self.generate()) @@ -159,6 +161,7 @@ class Subcommand(object): 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 @@ class Subcommand(object): 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 @@ class Subcommand(object): 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 @@ class Subcommand(object): 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 @@ class Subcommand(object): 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 @@ class Subcommand(object): # 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 @@ class Subcommand(object): 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 @@ class Subcommand(object): 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 @@ class Subcommand(object): 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 @@ class Subcommand(object): ' 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 @@ class Subcommand(object): 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 @@ class Subcommand(object): 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 @@ class GenericLayerSubcommand(Subcommand): 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 GenericLayerSubcommand(Subcommand): 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 @@ class APIDumpSubcommand(Subcommand): 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 @@ class APIDumpSubcommand(Subcommand): 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 @@ class APIDumpSubcommand(Subcommand): 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 @@ class APIDumpSubcommand(Subcommand): 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 @@ class APIDumpSubcommand(Subcommand): 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 @@ class APIDumpSubcommand(Subcommand): 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 @@ class APIDumpSubcommand(Subcommand): 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 @@ class APIDumpSubcommand(Subcommand): 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 @@ class APIDumpSubcommand(Subcommand): 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 APIDumpSubcommand(Subcommand): 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 @@ class ObjectTrackerSubcommand(Subcommand): 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 @@ class ObjectTrackerSubcommand(Subcommand): 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 @@ class ObjectTrackerSubcommand(Subcommand): 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 @@ class ObjectTrackerSubcommand(Subcommand): 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 @@ class ObjectTrackerSubcommand(Subcommand): 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 @@ class ObjectTrackerSubcommand(Subcommand): 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 @@ class ObjectTrackerSubcommand(Subcommand): 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 @@ class ObjectTrackerSubcommand(Subcommand): 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 @@ class ObjectTrackerSubcommand(Subcommand): 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 @@ class ObjectTrackerSubcommand(Subcommand): 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 @@ class ObjectTrackerSubcommand(Subcommand): 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 @@ class ObjectTrackerSubcommand(Subcommand): 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 @@ class ObjectTrackerSubcommand(Subcommand): 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 @@ class ObjectTrackerSubcommand(Subcommand): 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 @@ class ObjectTrackerSubcommand(Subcommand): 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 ObjectTrackerSubcommand(Subcommand): 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 @@ class ThreadingSubcommand(Subcommand): 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 @@ class ThreadingSubcommand(Subcommand): 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 @@ class ThreadingSubcommand(Subcommand): 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 @@ class ThreadingSubcommand(Subcommand): 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 @@ class ThreadingSubcommand(Subcommand): 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 4a7dce51..46daad5f 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 @@ class StructWrapperGen: 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 @@ class StructWrapperGen: 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 @@ class StructWrapperGen: 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 @@ class StructWrapperGen: 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 @@ class StructWrapperGen: 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 @@ class StructWrapperGen: 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 @@ class StructWrapperGen: 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 @@ class StructWrapperGen: 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 @@ class StructWrapperGen: 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) |
