layers: Make dispatch table thread safe
diff --git a/vk-layer-generate.py b/vk-layer-generate.py
index 99948c9..bc40f7a 100755
--- a/vk-layer-generate.py
+++ b/vk-layer-generate.py
@@ -428,8 +428,7 @@
func_body.append(' else if (!strcmp("%s", funcName))\n'
' return %s%s%s;' % (ext_name, cpp_prefix, ext_name, cpp_postfix))
func_body.append(" else {\n"
- " VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) device;\n"
- " VkLayerDispatchTable* pTable = tableMap[*ppDisp];\n"
+ " VkLayerDispatchTable* pTable = device_dispatch_table(device);\n"
" if (pTable->GetDeviceProcAddr == NULL)\n"
" return NULL;\n"
" return pTable->GetDeviceProcAddr(device, funcName);\n"
@@ -458,13 +457,10 @@
" fptr = %s(funcName);\n"
" if (fptr) return fptr;\n"
" }\n" % ext_name)
- func_body.append(" {\n"
- " VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) instance;\n"
- " VkLayerInstanceDispatchTable* pTable = tableInstanceMap[*ppDisp];\n"
- " if (pTable->GetInstanceProcAddr == NULL)\n"
- " return NULL;\n"
- " return pTable->GetInstanceProcAddr(instance, funcName);\n"
- " }\n"
+ func_body.append(" VkLayerInstanceDispatchTable* pTable = instance_dispatch_table(instance);\n"
+ " if (pTable->GetInstanceProcAddr == NULL)\n"
+ " return NULL;\n"
+ " return pTable->GetInstanceProcAddr(instance, funcName);\n"
"}\n")
return "\n".join(func_body)
@@ -501,49 +497,6 @@
func_body.append(" }")
func_body.append("}\n")
func_body.append('')
- func_body.append('static VkLayerDispatchTable * initDeviceTable(const VkBaseLayerObject *devw)')
- func_body.append(' {')
- func_body.append(' VkLayerDispatchTable *pTable;')
- func_body.append('')
- func_body.append(' assert(devw);')
- func_body.append(' VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) (devw->baseObject);')
- func_body.append('')
- func_body.append(' std::unordered_map<void *, VkLayerDispatchTable *>::const_iterator it = tableMap.find((void *) *ppDisp);')
- func_body.append(' if (it == tableMap.end())')
- func_body.append(' {')
- func_body.append(' pTable = new VkLayerDispatchTable;')
- func_body.append(' tableMap[(void *) *ppDisp] = pTable;')
- func_body.append(' } else')
- func_body.append(' {')
- func_body.append(' return it->second;')
- func_body.append(' }')
- func_body.append('')
- func_body.append(' layer_initialize_dispatch_table(pTable, devw);')
- func_body.append('')
- func_body.append(' return pTable;')
- func_body.append('}')
- func_body.append('')
- func_body.append('static VkLayerInstanceDispatchTable * initInstanceTable(const VkBaseLayerObject *instw)')
- func_body.append(' {')
- func_body.append(' VkLayerInstanceDispatchTable *pTable;')
- func_body.append(' assert(instw);')
- func_body.append(' VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) instw->baseObject;')
- func_body.append('')
- func_body.append(' std::unordered_map<void *, VkLayerInstanceDispatchTable *>::const_iterator it = tableInstanceMap.find((void *) *ppDisp);')
- func_body.append(' if (it == tableInstanceMap.end())')
- func_body.append(' {')
- func_body.append(' pTable = new VkLayerInstanceDispatchTable;')
- func_body.append(' tableInstanceMap[(void *) *ppDisp] = pTable;')
- func_body.append(' } else')
- func_body.append(' {')
- func_body.append(' return it->second;')
- func_body.append(' }')
- func_body.append('')
- func_body.append(' layer_init_instance_dispatch_table(pTable, instw);')
- func_body.append('')
- func_body.append(' return pTable;')
- func_body.append('}')
- func_body.append('')
return "\n".join(func_body)
class LayerFuncsSubcommand(Subcommand):
@@ -574,23 +527,10 @@
gen_header.append('#include "loader_platform.h"')
gen_header.append('#include "layers_config.h"')
gen_header.append('#include "layers_msg.h"')
- gen_header.append('')
- gen_header.append('static std::unordered_map<void *, VkLayerDispatchTable *> tableMap;')
- gen_header.append('static std::unordered_map<void *, VkLayerInstanceDispatchTable *> tableInstanceMap;')
+ gen_header.append('#include "layers_table.h"')
gen_header.append('')
gen_header.append('static LOADER_PLATFORM_THREAD_ONCE_DECLARATION(initOnce);')
gen_header.append('')
- gen_header.append(' static inline VkLayerDispatchTable *device_dispatch_table(VkObject object) {')
- gen_header.append(' VkLayerDispatchTable *pDisp = *(VkLayerDispatchTable **) object;')
- gen_header.append(' VkLayerDispatchTable *pTable = tableMap[pDisp];')
- gen_header.append(' return pTable;')
- gen_header.append('}')
- gen_header.append('')
- gen_header.append('static inline VkLayerInstanceDispatchTable *instance_dispatch_table(VkObject object) {')
- gen_header.append(' VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) object;')
- gen_header.append(' VkLayerInstanceDispatchTable *pInstanceTable = tableInstanceMap[*ppDisp];')
- gen_header.append(' return pInstanceTable;')
- gen_header.append('}')
return "\n".join(gen_header)
def generate_intercept(self, proto, qual):
if proto.name in [ 'GetGlobalExtensionInfo', 'GetPhysicalDeviceExtensionInfo' ]:
@@ -700,18 +640,15 @@
header_txt.append('#include "loader_platform.h"')
header_txt.append('#include "vkLayer.h"')
header_txt.append('#include "vk_struct_string_helper_cpp.h"')
+ header_txt.append('#include "layers_table.h"')
header_txt.append('#include <unordered_map>')
header_txt.append('')
header_txt.append('// The following is #included again to catch certain OS-specific functions being used:')
header_txt.append('#include "loader_platform.h"')
header_txt.append('')
- header_txt.append('static VkLayerDispatchTable nextTable;')
- header_txt.append('static VkLayerInstanceDispatchTable nextInstanceTable;')
header_txt.append('static VkBaseLayerObject *pCurObj;')
header_txt.append('static bool g_APIDumpDetailed = true;')
header_txt.append('')
- header_txt.append('static std::unordered_map<void *, VkLayerDispatchTable *> tableMap;')
- header_txt.append('static std::unordered_map<void *, VkLayerInstanceDispatchTable *> tableInstanceMap;')
header_txt.append('static LOADER_PLATFORM_THREAD_ONCE_DECLARATION(initOnce);')
header_txt.append('')
header_txt.append('static int printLockInitialized = 0;')
@@ -735,17 +672,6 @@
header_txt.append(' return retVal;')
header_txt.append('}')
header_txt.append('')
- header_txt.append('static inline VkLayerDispatchTable *device_dispatch_table(VkObject object) {')
- header_txt.append(' VkLayerDispatchTable *pDisp = *(VkLayerDispatchTable **) object;')
- header_txt.append(' VkLayerDispatchTable *pTable = tableMap[pDisp];')
- header_txt.append(' return pTable;')
- header_txt.append('}')
- header_txt.append('')
- header_txt.append('static inline VkLayerInstanceDispatchTable *instance_dispatch_table(VkObject object) {')
- header_txt.append(' VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) object;')
- header_txt.append(' VkLayerInstanceDispatchTable *pInstanceTable = tableInstanceMap[*ppDisp];')
- header_txt.append(' return pInstanceTable;')
- header_txt.append('}')
return "\n".join(header_txt)
def generate_init(self):
@@ -821,49 +747,6 @@
func_body.append(' }')
func_body.append('}')
func_body.append('')
- func_body.append('static VkLayerDispatchTable * initDeviceTable(const VkBaseLayerObject *devw)')
- func_body.append(' {')
- func_body.append(' VkLayerDispatchTable *pTable;')
- func_body.append('')
- func_body.append(' assert(devw);')
- func_body.append(' VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) (devw->baseObject);')
- func_body.append('')
- func_body.append(' std::unordered_map<void *, VkLayerDispatchTable *>::const_iterator it = tableMap.find((void *) *ppDisp);')
- func_body.append(' if (it == tableMap.end())')
- func_body.append(' {')
- func_body.append(' pTable = new VkLayerDispatchTable;')
- func_body.append(' tableMap[(void *) *ppDisp] = pTable;')
- func_body.append(' } else')
- func_body.append(' {')
- func_body.append(' return it->second;')
- func_body.append(' }')
- func_body.append('')
- func_body.append(' layer_initialize_dispatch_table(pTable, devw);')
- func_body.append('')
- func_body.append(' return pTable;')
- func_body.append('}')
- func_body.append('')
- func_body.append('static VkLayerInstanceDispatchTable * initInstanceTable(const VkBaseLayerObject *instw)')
- func_body.append(' {')
- func_body.append(' VkLayerInstanceDispatchTable *pTable;')
- func_body.append(' assert(instw);')
- func_body.append(' VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) instw->baseObject;')
- func_body.append('')
- func_body.append(' std::unordered_map<void *, VkLayerInstanceDispatchTable *>::const_iterator it = tableInstanceMap.find((void *) *ppDisp);')
- func_body.append(' if (it == tableInstanceMap.end())')
- func_body.append(' {')
- func_body.append(' pTable = new VkLayerInstanceDispatchTable;')
- func_body.append(' tableInstanceMap[(void *) *ppDisp] = pTable;')
- func_body.append(' } else')
- func_body.append(' {')
- func_body.append(' return it->second;')
- func_body.append(' }')
- func_body.append('')
- func_body.append(' layer_init_instance_dispatch_table(pTable, instw);')
- func_body.append('')
- func_body.append(' return pTable;')
- func_body.append('}')
- func_body.append('')
return "\n".join(func_body)
def generate_intercept(self, proto, qual):
@@ -1044,23 +927,10 @@
header_txt.append('#include "layers_config.h"')
header_txt.append('#include "layers_msg.h"')
header_txt.append('#include "vk_debug_report_lunarg.h"')
+ header_txt.append('#include "layers_table.h"')
header_txt.append('')
- header_txt.append('static std::unordered_map<void *, VkLayerDispatchTable *> tableMap;')
- header_txt.append('static std::unordered_map<void *, VkLayerInstanceDispatchTable *> tableInstanceMap;')
header_txt.append('static LOADER_PLATFORM_THREAD_ONCE_DECLARATION(initOnce);')
header_txt.append('')
- header_txt.append('static inline VkLayerDispatchTable *device_dispatch_table(VkObject object) {')
- header_txt.append(' VkLayerDispatchTable *pDisp = *(VkLayerDispatchTable **) object;')
- header_txt.append(' VkLayerDispatchTable *pTable = tableMap[pDisp];')
- header_txt.append(' return pTable;')
- header_txt.append('}')
- header_txt.append('')
- header_txt.append('static inline VkLayerInstanceDispatchTable *instance_dispatch_table(VkObject object) {')
- header_txt.append(' VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) object;')
- header_txt.append(' VkLayerInstanceDispatchTable *pInstanceTable = tableInstanceMap[*ppDisp];')
- header_txt.append(' return pInstanceTable;')
- header_txt.append('}')
- header_txt.append('')
header_txt.append('static long long unsigned int object_track_index = 0;')
header_txt.append('static int objLockInitialized = 0;')
header_txt.append('static loader_platform_thread_mutex objLock;')
@@ -1503,24 +1373,11 @@
header_txt.append('//The following is #included again to catch certain OS-specific functions being used:')
header_txt.append('#include "loader_platform.h"\n')
header_txt.append('#include "layers_msg.h"\n')
+ header_txt.append('#include "layers_table.h"\n')
header_txt.append('')
- header_txt.append('static std::unordered_map<void *, VkLayerDispatchTable *> tableMap;')
- header_txt.append('static std::unordered_map<void *, VkLayerInstanceDispatchTable *> tableInstanceMap;')
header_txt.append('')
header_txt.append('static LOADER_PLATFORM_THREAD_ONCE_DECLARATION(initOnce);')
header_txt.append('')
- header_txt.append('static inline VkLayerDispatchTable *device_dispatch_table(VkObject object) {')
- header_txt.append(' VkLayerDispatchTable *pDisp = *(VkLayerDispatchTable **) object;')
- header_txt.append(' VkLayerDispatchTable *pTable = tableMap[pDisp];')
- header_txt.append(' return pTable;')
- header_txt.append('}')
- header_txt.append('')
- header_txt.append('static inline VkLayerInstanceDispatchTable *instance_dispatch_table(VkObject object) {')
- header_txt.append(' VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) object;')
- header_txt.append(' VkLayerInstanceDispatchTable *pInstanceTable = tableInstanceMap[*ppDisp];')
- header_txt.append(' return pInstanceTable;')
- header_txt.append('}')
- header_txt.append('')
header_txt.append('using namespace std;')
header_txt.append('static unordered_map<int, void*> proxy_objectsInUse;\n')
header_txt.append('static unordered_map<VkObject, loader_platform_thread_id> objectsInUse;\n')