diff options
| author | Tobin Ehlis <tobine@google.com> | 2016-02-10 15:38:45 -0700 |
|---|---|---|
| committer | Tobin Ehlis <tobine@google.com> | 2016-02-11 16:31:56 -0700 |
| commit | c81d623d70f2ef929825335ebfc9a90153c5f8b1 (patch) | |
| tree | a9f2043aace7d5b94576f966a2da78556a12e983 | |
| parent | 5e29489f855a8c6fba84c1e608bfaa5dd58066d1 (diff) | |
| download | usermoji-c81d623d70f2ef929825335ebfc9a90153c5f8b1.tar.xz | |
layers: Update unique_objects to make use of safe_structs
Stop overwriting const* data in unique_objects.
Instead, declare local safe_struct copies of data, update that
data in place with unwrapped objects, and pass down the local
safe_struct copy, which spoofs the original struct layout.
This includes code to build the layer using vk_safe_struct.h/cpp files.
| -rw-r--r-- | buildAndroid/jni/Android.mk | 1 | ||||
| -rw-r--r-- | layers/CMakeLists.txt | 6 | ||||
| -rw-r--r-- | layers/unique_objects.h | 132 | ||||
| -rwxr-xr-x | vk-layer-generate.py | 90 |
4 files changed, 99 insertions, 130 deletions
diff --git a/buildAndroid/jni/Android.mk b/buildAndroid/jni/Android.mk index bccb6458..ca9294bd 100644 --- a/buildAndroid/jni/Android.mk +++ b/buildAndroid/jni/Android.mk @@ -119,6 +119,7 @@ include $(BUILD_SHARED_LIBRARY) include $(CLEAR_VARS)
LOCAL_MODULE := VkLayer_unique_objects
LOCAL_SRC_FILES += $(SRC_DIR)/buildAndroid/generated/unique_objects.cpp
+LOCAL_SRC_FILES += $(SRC_DIR)/buildAndroid/generated/vk_safe_struct.cpp
LOCAL_SRC_FILES += $(SRC_DIR)/layers/vk_layer_table.cpp
LOCAL_C_INCLUDES += $(SRC_DIR)/include \
$(SRC_DIR)/layers \
diff --git a/layers/CMakeLists.txt b/layers/CMakeLists.txt index 391ac295..7c26fb47 100644 --- a/layers/CMakeLists.txt +++ b/layers/CMakeLists.txt @@ -126,6 +126,8 @@ run_vk_helper(gen_struct_wrappers vk_struct_size_helper.c vk_struct_wrappers.h vk_struct_wrappers.cpp + vk_safe_struct.h + vk_safe_struct.cpp ) add_custom_target(generate_vk_layer_helpers DEPENDS @@ -139,6 +141,8 @@ add_custom_target(generate_vk_layer_helpers DEPENDS vk_struct_size_helper.c vk_struct_wrappers.h vk_struct_wrappers.cpp + vk_safe_struct.h + vk_safe_struct.cpp ) run_vk_layer_generate(object_tracker object_tracker.cpp) @@ -163,4 +167,4 @@ add_vk_layer(swapchain swapchain.cpp vk_layer_table.cpp) # generated add_vk_layer(object_tracker object_tracker.cpp vk_layer_table.cpp) add_vk_layer(threading threading.cpp thread_check.h vk_layer_table.cpp) -add_vk_layer(unique_objects unique_objects.cpp vk_layer_table.cpp) +add_vk_layer(unique_objects unique_objects.cpp vk_layer_table.cpp vk_safe_struct.cpp) diff --git a/layers/unique_objects.h b/layers/unique_objects.h index 0c65d709..3ce6ddae 100644 --- a/layers/unique_objects.h +++ b/layers/unique_objects.h @@ -42,6 +42,7 @@ #include "vk_layer_data.h" #include "vk_layer_logging.h" #include "vk_layer_extension_utils.h" +#include "vk_safe_struct.h" struct layer_data { bool wsi_enabled; @@ -424,50 +425,31 @@ VkResult explicit_QueueBindSparse(VkQueue queue, uint32_t bindInfoCount, const V VkResult explicit_CreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkComputePipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines) { -// UNWRAP USES: -// 0 : pipelineCache,VkPipelineCache, pCreateInfos[createInfoCount]->stage[0]->module,VkShaderModule, pCreateInfos[createInfoCount]->layout,VkPipelineLayout, pCreateInfos[createInfoCount]->basePipelineHandle,VkPipeline - if (VK_NULL_HANDLE != pipelineCache) { - pipelineCache = (VkPipelineCache)((VkUniqueObject*)pipelineCache)->actualObject; - } - std::vector<VkShaderModule> original_module = {}; - std::vector<VkPipelineLayout> original_layout = {}; - std::vector<VkPipeline> original_basePipelineHandle = {}; +// STRUCT USES:{'pipelineCache': 'VkPipelineCache', 'pCreateInfos[createInfoCount]': {'stage': {'module': 'VkShaderModule'}, 'layout': 'VkPipelineLayout', 'basePipelineHandle': 'VkPipeline'}} +//LOCAL DECLS:{'pCreateInfos': 'VkComputePipelineCreateInfo*'} + safe_VkComputePipelineCreateInfo* local_pCreateInfos = NULL; if (pCreateInfos) { - for (uint32_t index0=0; index0<createInfoCount; ++index0) { - if (pCreateInfos[index0].stage.module) { - VkShaderModule* pShaderModule = (VkShaderModule*)&(pCreateInfos[index0].stage.module); - original_module.push_back(pCreateInfos[index0].stage.module); - *(pShaderModule) = (VkShaderModule)((VkUniqueObject*)pCreateInfos[index0].stage.module)->actualObject; + local_pCreateInfos = new safe_VkComputePipelineCreateInfo[createInfoCount]; + for (uint32_t idx0=0; idx0<createInfoCount; ++idx0) { + local_pCreateInfos[idx0].initialize(&pCreateInfos[idx0]); + if (pCreateInfos[idx0].basePipelineHandle) { + local_pCreateInfos[idx0].basePipelineHandle = (VkPipeline)((VkUniqueObject*)pCreateInfos[idx0].basePipelineHandle)->actualObject; } - if (pCreateInfos[index0].layout) { - VkPipelineLayout* pPipelineLayout = (VkPipelineLayout*)&(pCreateInfos[index0].layout); - original_layout.push_back(pCreateInfos[index0].layout); - *(pPipelineLayout) = (VkPipelineLayout)((VkUniqueObject*)pCreateInfos[index0].layout)->actualObject; + if (pCreateInfos[idx0].layout) { + local_pCreateInfos[idx0].layout = (VkPipelineLayout)((VkUniqueObject*)pCreateInfos[idx0].layout)->actualObject; } - if (pCreateInfos[index0].basePipelineHandle) { - VkPipeline* pPipeline = (VkPipeline*)&(pCreateInfos[index0].basePipelineHandle); - original_basePipelineHandle.push_back(pCreateInfos[index0].basePipelineHandle); - *(pPipeline) = (VkPipeline)((VkUniqueObject*)pCreateInfos[index0].basePipelineHandle)->actualObject; + if (pCreateInfos[idx0].stage.module) { + local_pCreateInfos[idx0].stage.module = (VkShaderModule)((VkUniqueObject*)pCreateInfos[idx0].stage.module)->actualObject; } } } - VkResult result = get_dispatch_table(unique_objects_device_table_map, device)->CreateComputePipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines); - if (pCreateInfos) { - for (uint32_t index0=0; index0<createInfoCount; ++index0) { - if (pCreateInfos[index0].stage.module) { - VkShaderModule* pShaderModule = (VkShaderModule*)&(pCreateInfos[index0].stage.module); - *(pShaderModule) = original_module[index0]; - } - if (pCreateInfos[index0].layout) { - VkPipelineLayout* pPipelineLayout = (VkPipelineLayout*)&(pCreateInfos[index0].layout); - *(pPipelineLayout) = original_layout[index0]; - } - if (pCreateInfos[index0].basePipelineHandle) { - VkPipeline* pPipeline = (VkPipeline*)&(pCreateInfos[index0].basePipelineHandle); - *(pPipeline) = original_basePipelineHandle[index0]; - } - } + if (pipelineCache) { + pipelineCache = (VkPipelineCache)((VkUniqueObject*)pipelineCache)->actualObject; } +// CODEGEN : file /usr/local/google/home/tobine/vulkan_work/LoaderAndTools/vk-layer-generate.py line #1671 + VkResult result = get_dispatch_table(unique_objects_device_table_map, device)->CreateComputePipelines(device, pipelineCache, createInfoCount, (const VkComputePipelineCreateInfo*)local_pCreateInfos, pAllocator, pPipelines); + if (local_pCreateInfos) + delete[] local_pCreateInfos; if (VK_SUCCESS == result) { VkUniqueObject* pUO = NULL; for (uint32_t i=0; i<createInfoCount; ++i) { @@ -481,68 +463,38 @@ VkResult explicit_CreateComputePipelines(VkDevice device, VkPipelineCache pipeli VkResult explicit_CreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkGraphicsPipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines) { -// UNWRAP USES: -// 0 : pipelineCache,VkPipelineCache, pCreateInfos[createInfoCount]->pStages[stageCount]->module,VkShaderModule, pCreateInfos[createInfoCount]->layout,VkPipelineLayout, pCreateInfos[createInfoCount]->renderPass,VkRenderPass, pCreateInfos[createInfoCount]->basePipelineHandle,VkPipeline - if (VK_NULL_HANDLE != pipelineCache) { - pipelineCache = (VkPipelineCache)((VkUniqueObject*)pipelineCache)->actualObject; - } - std::vector<VkShaderModule> original_module = {}; - std::vector<VkPipelineLayout> original_layout = {}; - std::vector<VkRenderPass> original_renderPass = {}; - std::vector<VkPipeline> original_basePipelineHandle = {}; +// STRUCT USES:{'pipelineCache': 'VkPipelineCache', 'pCreateInfos[createInfoCount]': {'layout': 'VkPipelineLayout', 'pStages[stageCount]': {'module': 'VkShaderModule'}, 'renderPass': 'VkRenderPass', 'basePipelineHandle': 'VkPipeline'}} +//LOCAL DECLS:{'pCreateInfos': 'VkGraphicsPipelineCreateInfo*'} + safe_VkGraphicsPipelineCreateInfo* local_pCreateInfos = NULL; if (pCreateInfos) { - for (uint32_t index0=0; index0<createInfoCount; ++index0) { - if (pCreateInfos[index0].pStages) { - for (uint32_t index1=0; index1<pCreateInfos[index0].stageCount; ++index1) { - if (pCreateInfos[index0].pStages[index1].module) { - VkShaderModule* pShaderModule = (VkShaderModule*)&(pCreateInfos[index0].pStages[index1].module); - original_module.push_back(pCreateInfos[index0].pStages[index1].module); - *(pShaderModule) = (VkShaderModule)((VkUniqueObject*)pCreateInfos[index0].pStages[index1].module)->actualObject; - } - } - } - if (pCreateInfos[index0].layout) { - VkPipelineLayout* pPipelineLayout = (VkPipelineLayout*)&(pCreateInfos[index0].layout); - original_layout.push_back(pCreateInfos[index0].layout); - *(pPipelineLayout) = (VkPipelineLayout)((VkUniqueObject*)pCreateInfos[index0].layout)->actualObject; + local_pCreateInfos = new safe_VkGraphicsPipelineCreateInfo[createInfoCount]; + for (uint32_t idx0=0; idx0<createInfoCount; ++idx0) { + local_pCreateInfos[idx0].initialize(&pCreateInfos[idx0]); + if (pCreateInfos[idx0].basePipelineHandle) { + local_pCreateInfos[idx0].basePipelineHandle = (VkPipeline)((VkUniqueObject*)pCreateInfos[idx0].basePipelineHandle)->actualObject; } - if (pCreateInfos[index0].renderPass) { - VkRenderPass* pRenderPass = (VkRenderPass*)&(pCreateInfos[index0].renderPass); - original_renderPass.push_back(pCreateInfos[index0].renderPass); - *(pRenderPass) = (VkRenderPass)((VkUniqueObject*)pCreateInfos[index0].renderPass)->actualObject; + if (pCreateInfos[idx0].layout) { + local_pCreateInfos[idx0].layout = (VkPipelineLayout)((VkUniqueObject*)pCreateInfos[idx0].layout)->actualObject; } - if (pCreateInfos[index0].basePipelineHandle) { - VkPipeline* pPipeline = (VkPipeline*)&(pCreateInfos[index0].basePipelineHandle); - original_basePipelineHandle.push_back(pCreateInfos[index0].basePipelineHandle); - *(pPipeline) = (VkPipeline)((VkUniqueObject*)pCreateInfos[index0].basePipelineHandle)->actualObject; - } - } - } - VkResult result = get_dispatch_table(unique_objects_device_table_map, device)->CreateGraphicsPipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines); - if (pCreateInfos) { - for (uint32_t index0=0; index0<createInfoCount; ++index0) { - if (pCreateInfos[index0].pStages) { - for (uint32_t index1=0; index1<pCreateInfos[index0].stageCount; ++index1) { - if (pCreateInfos[index0].pStages[index1].module) { - VkShaderModule* pShaderModule = (VkShaderModule*)&(pCreateInfos[index0].pStages[index1].module); - *(pShaderModule) = original_module[index1]; + if (pCreateInfos[idx0].pStages) { + for (uint32_t idx1=0; idx1<pCreateInfos[idx0].stageCount; ++idx1) { + if (pCreateInfos[idx0].pStages[idx1].module) { + local_pCreateInfos[idx0].pStages[idx1].module = (VkShaderModule)((VkUniqueObject*)pCreateInfos[idx0].pStages[idx1].module)->actualObject; } } } - if (pCreateInfos[index0].layout) { - VkPipelineLayout* pPipelineLayout = (VkPipelineLayout*)&(pCreateInfos[index0].layout); - *(pPipelineLayout) = original_layout[index0]; - } - if (pCreateInfos[index0].renderPass) { - VkRenderPass* pRenderPass = (VkRenderPass*)&(pCreateInfos[index0].renderPass); - *(pRenderPass) = original_renderPass[index0]; - } - if (pCreateInfos[index0].basePipelineHandle) { - VkPipeline* pPipeline = (VkPipeline*)&(pCreateInfos[index0].basePipelineHandle); - *(pPipeline) = original_basePipelineHandle[index0]; + if (pCreateInfos[idx0].renderPass) { + local_pCreateInfos[idx0].renderPass = (VkRenderPass)((VkUniqueObject*)pCreateInfos[idx0].renderPass)->actualObject; } } } + if (pipelineCache) { + pipelineCache = (VkPipelineCache)((VkUniqueObject*)pipelineCache)->actualObject; + } +// CODEGEN : file /usr/local/google/home/tobine/vulkan_work/LoaderAndTools/vk-layer-generate.py line #1671 + VkResult result = get_dispatch_table(unique_objects_device_table_map, device)->CreateGraphicsPipelines(device, pipelineCache, createInfoCount, (const VkGraphicsPipelineCreateInfo*)local_pCreateInfos, pAllocator, pPipelines); + if (local_pCreateInfos) + delete[] local_pCreateInfos; if (VK_SUCCESS == result) { VkUniqueObject* pUO = NULL; for (uint32_t i=0; i<createInfoCount; ++i) { diff --git a/vk-layer-generate.py b/vk-layer-generate.py index 5fed8791..ebeddd13 100755 --- a/vk-layer-generate.py +++ b/vk-layer-generate.py @@ -137,6 +137,7 @@ def gather_object_uses_in_struct(obj_list, struct_type): # TODO : This analysis could be done up-front at vk_helper time def get_object_uses(obj_list, params): obj_uses = {} + local_decls = {} param_count = 'NONE' # track params that give array sizes for p in params: base_type = p.ty.replace('const ', '').strip('*') @@ -144,11 +145,15 @@ def get_object_uses(obj_list, params): is_ptr = False if 'count' in p.name.lower(): param_count = p.name + ptr_txt = '' if '*' in p.ty: is_ptr = True + ptr_txt = '*' if base_type in obj_list: if is_ptr and 'const' in p.ty and param_count != 'NONE': array_len = "[%s]" % param_count + # Non-arrays we can overwrite in place, but need local decl for arrays + local_decls[p.name] = '%s%s' % (base_type, ptr_txt) #if array_len not in obj_uses: # obj_uses[array_len] = {} # obj_uses[array_len][p.name] = base_type @@ -160,7 +165,9 @@ def get_object_uses(obj_list, params): struct_uses = gather_object_uses_in_struct(obj_list, base_type) if len(struct_uses) > 0: obj_uses[struct_name] = struct_uses - return obj_uses + # This is a top-level struct w/ uses below it, so need local decl + local_decls['%s' % (p.name)] = '%s%s' % (base_type, ptr_txt) + return (obj_uses, local_decls) class Subcommand(object): def __init__(self, argv): @@ -1286,7 +1293,7 @@ class ObjectTrackerSubcommand(Subcommand): if True in [create_txt in proto.name for create_txt in ['Create', 'Allocate']]: create_func = True last_param_index = -1 # For create funcs don't validate last object - struct_uses = get_object_uses(vulkan.object_type_list, proto.params[:last_param_index]) + (struct_uses, local_decls) = get_object_uses(vulkan.object_type_list, proto.params[:last_param_index]) funcs = [] mutex_unlock = False funcs.append('%s\n' % self.lineinfo.get()) @@ -1426,7 +1433,7 @@ class UniqueObjectsSubcommand(Subcommand): # vector_name_set is used to make sure we don't replicate vector names # first_level_param indicates if elements are passed directly into the function else they're below a ptr/struct # TODO : Comment this code - def _gen_obj_code(self, struct_uses, indent, prefix, array_index, vector_name_set, first_level_param): + def _gen_obj_code(self, struct_uses, param_type, indent, prefix, array_index, vector_name_set, first_level_param): decls = '' pre_code = '' post_code = '' @@ -1444,85 +1451,77 @@ class UniqueObjectsSubcommand(Subcommand): name = '%s%s' % (prefix, name) if ptr_type: pre_code += '%sif (%s) {\n' % (indent, name) - post_code += '%sif (%s) {\n' % (indent, name) indent += ' ' if array != '': idx = 'idx%s' % str(array_index) array_index += 1 + if first_level_param and name in param_type: + pre_code += '%slocal_%s = new safe_%s[%s];\n' % (indent, name, param_type[name].strip('*'), array) + post_code += ' if (local_%s)\n' % (name) + post_code += ' delete[] local_%s;\n' % (name) pre_code += '%sfor (uint32_t %s=0; %s<%s%s; ++%s) {\n' % (indent, idx, idx, prefix, array, idx) - post_code += '%sfor (uint32_t %s=0; %s<%s%s; ++%s) {\n' % (indent, idx, idx, prefix, array, idx) indent += ' ' + if first_level_param: + pre_code += '%slocal_%s[%s].initialize(&%s[%s]);\n' % (indent, name, idx, name, idx) local_prefix = '%s[%s].' % (name, idx) elif ptr_type: + if first_level_param and name in param_type: + pre_code += '%slocal_%s = new safe_%s(%s);\n' % (indent, name, param_type[name].strip('*'), name) + post_code += ' if (local_%s)\n' % (name) + post_code += ' delete local_%s;\n' % (name) local_prefix = '%s->' % (name) else: local_prefix = '%s.' % (name) assert isinstance(decls, object) - (tmp_decl, tmp_pre, tmp_post) = self._gen_obj_code(struct_uses[obj], indent, local_prefix, array_index, vector_name_set, False) + (tmp_decl, tmp_pre, tmp_post) = self._gen_obj_code(struct_uses[obj], param_type, indent, local_prefix, array_index, vector_name_set, False) decls += tmp_decl pre_code += tmp_pre post_code += tmp_post if array != '': indent = indent[4:] pre_code += '%s}\n' % (indent) - post_code += '%s}\n' % (indent) if ptr_type: indent = indent[4:] pre_code += '%s}\n' % (indent) - post_code += '%s}\n' % (indent) else: if (array_index > 0) or array != '': # TODO : This is not ideal, really want to know if we're anywhere under an array + if first_level_param: + pre_code += '%s%s* local_%s = NULL;\n' % (indent, struct_uses[obj], name) pre_code += '%sif (%s%s) {\n' %(indent, prefix, name) - post_code += '%sif (%s%s) {\n' %(indent, prefix, name) indent += ' ' - # Append unique_count to make sure name is unique (some aliasing for "buffer" and "image" names - vec_name = 'original_%s' % (name) if array != '': idx = 'idx%s' % str(array_index) array_index += 1 + if first_level_param: + pre_code += '%slocal_%s = new %s[%s];\n' % (indent, name, struct_uses[obj], array) + post_code += ' if (local_%s)\n' % (name) + post_code += ' delete[] local_%s;\n' % (name) pre_code += '%sfor (uint32_t %s=0; %s<%s%s; ++%s) {\n' % (indent, idx, idx, prefix, array, idx) - post_code += '%sfor (uint32_t %s=0; %s<%s%s; ++%s) {\n' % (indent, idx, idx, prefix, array, idx) indent += ' ' name = '%s[%s]' % (name, idx) pName = 'p%s' % (struct_uses[obj][2:]) - pre_code += '%s%s* %s = (%s*)&(%s%s);\n' % (indent, struct_uses[obj], pName, struct_uses[obj], prefix, name) - post_code += '%s%s* %s = (%s*)&(%s%s);\n' % (indent, struct_uses[obj], pName, struct_uses[obj], prefix, name) if name not in vector_name_set: vector_name_set.add(name) - decls += ' std::vector<%s> %s = {};\n' % (struct_uses[obj], vec_name) - pre_code += '%s%s.push_back(%s%s);\n' % (indent, vec_name, prefix, name) - pre_code += '%s*(%s) = (%s)((VkUniqueObject*)%s%s)->actualObject;\n' % (indent, pName, struct_uses[obj], prefix, name) - post_code += '%s*(%s) = %s.front();\n' % (indent, pName, vec_name) - post_code += '%s%s.erase(%s.begin());\n' % (indent, vec_name, vec_name) + pre_code += '%slocal_%s%s = (%s)((VkUniqueObject*)%s%s)->actualObject;\n' % (indent, prefix, name, struct_uses[obj], prefix, name) if array != '': indent = indent[4:] pre_code += '%s}\n' % (indent) - post_code += '%s}\n' % (indent) indent = indent[4:] pre_code += '%s}\n' % (indent) - post_code += '%s}\n' % (indent) else: + pre_code += '%s\n' % (self.lineinfo.get()) pre_code += '%sif (%s%s) {\n' %(indent, prefix, name) indent += ' ' deref_txt = '&' if ptr_type: deref_txt = '' - pre_code += '%s%s* p%s = (%s*)%s%s%s;\n' % (indent, struct_uses[obj], name, struct_uses[obj], deref_txt, prefix, name) - pre_code += '%s*p%s = (%s)((VkUniqueObject*)%s%s)->actualObject;\n' % (indent, name, struct_uses[obj], prefix, name) + if '->' in prefix: # need to update local struct + pre_code += '%slocal_%s%s = (%s)((VkUniqueObject*)%s%s)->actualObject;\n' % (indent, prefix, name, struct_uses[obj], prefix, name) + else: + pre_code += '%s%s* p%s = (%s*)%s%s%s;\n' % (indent, struct_uses[obj], name, struct_uses[obj], deref_txt, prefix, name) + pre_code += '%s*p%s = (%s)((VkUniqueObject*)%s%s)->actualObject;\n' % (indent, name, struct_uses[obj], prefix, name) indent = indent[4:] pre_code += '%s}\n' % (indent) - if not first_level_param: # embedded in a ptr/struct so need to undo the update - if '->' in prefix: - # Since this variable is embedded under a ptr, need to decl up front, but wait - # to assign it inside of the "if" block(s) for surrounding ptr(s) - decls += ' %s local_%s = VK_NULL_HANDLE;\n' % (struct_uses[obj], name) - pre_code = '%slocal_%s = %s%s;\n%s' % (indent, name, prefix, name, pre_code) - else: - decls += ' %s local_%s = %s%s;\n' % (struct_uses[obj], name, prefix, name) - post_code += '%sif (%s%s) {\n' %(indent, prefix, name) - post_code += '%s %s* p%s = (%s*)%s%s%s;\n' % (indent, struct_uses[obj], name, struct_uses[obj], deref_txt, prefix, name) - post_code += '%s *p%s = local_%s;\n' % (indent, name, name) - post_code += '%s}\n' % (indent) return decls, pre_code, post_code def generate_intercept(self, proto, qual): @@ -1540,7 +1539,8 @@ class UniqueObjectsSubcommand(Subcommand): 'CreateInstance', 'CreateDevice', 'CreateComputePipelines', - 'CreateGraphicsPipelines'] + 'CreateGraphicsPipelines' + ] # TODO : This is hacky, need to make this a more general-purpose solution for all layers ifdef_dict = {'CreateXcbSurfaceKHR': 'VK_USE_PLATFORM_XCB_KHR'} # Give special treatment to create functions that return multiple new objects @@ -1561,16 +1561,25 @@ class UniqueObjectsSubcommand(Subcommand): destroy_func = True # First thing we need to do is gather uses of non-dispatchable-objects (ndos) - struct_uses = get_object_uses(vulkan.object_non_dispatch_list, proto.params[1:last_param_index]) + (struct_uses, local_decls) = get_object_uses(vulkan.object_non_dispatch_list, proto.params[1:last_param_index]) if len(struct_uses) > 0: pre_call_txt += '// STRUCT USES:%s\n' % struct_uses + if len(local_decls) > 0: + pre_call_txt += '//LOCAL DECLS:%s\n' % local_decls if destroy_func: # only one object for del_obj in struct_uses: pre_call_txt += '%s%s local_%s = %s;\n' % (indent, struct_uses[del_obj], del_obj, del_obj) - (pre_decl, pre_code, post_code) = self._gen_obj_code(struct_uses, ' ', '', 0, set(), True) + (pre_decl, pre_code, post_code) = self._gen_obj_code(struct_uses, local_decls, ' ', '', 0, set(), True) + # This is a bit hacky but works for now. Need to decl local versions of top-level structs + for ld in local_decls: + init_null_txt = 'NULL'; + if '*' not in local_decls[ld]: + init_null_txt = '{}'; + if local_decls[ld].strip('*') not in vulkan.object_non_dispatch_list: + pre_decl += ' safe_%s local_%s = %s;\n' % (local_decls[ld], ld, init_null_txt) pre_call_txt += '%s%s' % (pre_decl, pre_code) - post_call_txt += post_code + post_call_txt += '%s' % (post_code) elif create_func: base_type = proto.params[-1].ty.replace('const ', '').strip('*') if base_type not in vulkan.object_non_dispatch_list: @@ -1626,6 +1635,9 @@ class UniqueObjectsSubcommand(Subcommand): post_call_txt = '%sdelete (VkUniqueObject*)local_%s;\n' % (indent, proto.params[-2].name) call_sig = proto.c_call() + # Replace default params with any custom local params + for ld in local_decls: + call_sig = call_sig.replace(ld, '(const %s)local_%s' % (local_decls[ld], ld)) if proto_is_global(proto): table_type = "instance" else: |
