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')