aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTobin Ehlis <tobine@google.com>2016-02-10 15:38:45 -0700
committerTobin Ehlis <tobine@google.com>2016-02-11 16:31:56 -0700
commitc81d623d70f2ef929825335ebfc9a90153c5f8b1 (patch)
treea9f2043aace7d5b94576f966a2da78556a12e983
parent5e29489f855a8c6fba84c1e608bfaa5dd58066d1 (diff)
downloadusermoji-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.mk1
-rw-r--r--layers/CMakeLists.txt6
-rw-r--r--layers/unique_objects.h132
-rwxr-xr-xvk-layer-generate.py90
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: