layers: Make dispatch table thread safe
diff --git a/layers/shader_checker.cpp b/layers/shader_checker.cpp
index d31d7f6..57aab4f 100644
--- a/layers/shader_checker.cpp
+++ b/layers/shader_checker.cpp
@@ -33,6 +33,7 @@
 #include "vkLayer.h"
 #include "layers_config.h"
 #include "layers_msg.h"
+#include "layers_table.h"
 #include "vk_enum_string_helper.h"
 #include "shader_checker.h"
 // The following is #included again to catch certain OS-specific functions
@@ -42,9 +43,6 @@
 #include "spirv/spirv.h"
 
 
-static std::unordered_map<void *, VkLayerDispatchTable *> tableMap;
-static VkBaseLayerObject *pCurObj;
-static std::unordered_map<void *, VkLayerInstanceDispatchTable *> tableInstanceMap;
 static LOADER_PLATFORM_THREAD_ONCE_DECLARATION(g_initOnce);
 // TODO : This can be much smarter, using separate locks for separate global data
 static int globalLockInitialized = 0;
@@ -144,47 +142,6 @@
     }
 }
 
-
-static VkLayerDispatchTable * initLayerTable(const VkBaseLayerObject *devw)
-{
-    VkLayerDispatchTable *pTable;
-
-    assert(devw);
-    std::unordered_map<void *, VkLayerDispatchTable *>::const_iterator it = tableMap.find((void *) devw->baseObject);
-    if (it == tableMap.end())
-    {
-        pTable =  new VkLayerDispatchTable;
-        tableMap[(void *) devw->baseObject] = pTable;
-    } else
-    {
-        return it->second;
-    }
-
-    layer_initialize_dispatch_table(pTable, devw);
-
-    return pTable;
-}
-
-static VkLayerInstanceDispatchTable * initLayerInstanceTable(const VkBaseLayerObject *instw)
-{
-    VkLayerInstanceDispatchTable *pTable;
-
-    assert(instw);
-    std::unordered_map<void *, VkLayerInstanceDispatchTable *>::const_iterator it = tableInstanceMap.find((void *) instw->baseObject);
-    if (it == tableInstanceMap.end())
-    {
-        pTable =  new VkLayerInstanceDispatchTable;
-        tableInstanceMap[(void *) instw->baseObject] = pTable;
-    } else
-    {
-        return it->second;
-    }
-
-    layer_init_instance_dispatch_table(pTable, instw);
-
-    return pTable;
-}
-
 #define SHADER_CHECKER_LAYER_EXT_ARRAY_SIZE 2
 static const VkExtensionProperties shaderCheckerExts[SHADER_CHECKER_LAYER_EXT_ARRAY_SIZE] = {
     {
@@ -474,8 +431,7 @@
                                                    VkShader *pShader)
 {
     loader_platform_thread_lock_mutex(&globalLock);
-    VkLayerDispatchTable* pTable = tableMap[(VkBaseLayerObject *)device];
-    VkResult res = pTable->CreateShader(device, pCreateInfo, pShader);
+    VkResult res = device_dispatch_table(device)->CreateShader(device, pCreateInfo, pShader);
 
     shader_map[(VkBaseLayerObject *) *pShader] = new shader_source(pCreateInfo);
     loader_platform_thread_unlock_mutex(&globalLock);
@@ -900,8 +856,7 @@
         /* The driver is allowed to crash if passed junk. Only actually create the
          * pipeline if we didn't run into any showstoppers above.
          */
-        VkLayerDispatchTable *pTable = tableMap[(VkBaseLayerObject *)device];
-        return pTable->CreateGraphicsPipeline(device, pCreateInfo, pPipeline);
+        return device_dispatch_table(device)->CreateGraphicsPipeline(device, pCreateInfo, pPipeline);
     }
     else {
         return VK_ERROR_UNKNOWN;
@@ -921,8 +876,7 @@
         /* The driver is allowed to crash if passed junk. Only actually create the
          * pipeline if we didn't run into any showstoppers above.
          */
-        VkLayerDispatchTable *pTable = tableMap[(VkBaseLayerObject *)device];
-        return pTable->CreateGraphicsPipelineDerivative(device, pCreateInfo, basePipeline, pPipeline);
+        return device_dispatch_table(device)->CreateGraphicsPipelineDerivative(device, pCreateInfo, basePipeline, pPipeline);
     }
     else {
         return VK_ERROR_UNKNOWN;
@@ -933,9 +887,9 @@
 /* hook DextroyDevice to remove tableMap entry */
 VK_LAYER_EXPORT VkResult VKAPI vkDestroyDevice(VkDevice device)
 {
-    VkLayerDispatchTable *pTable = tableMap[(VkBaseLayerObject *)device];
-    VkResult res = pTable->DestroyDevice(device);
-    tableMap.erase(device);
+    VkLayerDispatchTable *pDisp =  *(VkLayerDispatchTable **) device;
+    VkResult res = device_dispatch_table(device)->DestroyDevice(device);
+    tableMap.erase(pDisp);
     return res;
 }
 
@@ -949,7 +903,7 @@
      * For layers, the pInstance has already been filled out
      * by the loader so that dispatch table is available.
      */
-    VkLayerInstanceDispatchTable *pTable = initLayerInstanceTable((const VkBaseLayerObject *) (*pInstance));
+    VkLayerInstanceDispatchTable *pTable = initInstanceTable((const VkBaseLayerObject *) (*pInstance));
 
     VkResult result = pTable->CreateInstance(pCreateInfo, pInstance);
 
@@ -967,9 +921,9 @@
 /* hook DestroyInstance to remove tableInstanceMap entry */
 VK_LAYER_EXPORT VkResult VKAPI vkDestroyInstance(VkInstance instance)
 {
-    VkLayerInstanceDispatchTable *pTable = tableInstanceMap[(VkBaseLayerObject *)instance];
-    VkResult res = pTable->DestroyInstance(instance);
-    tableInstanceMap.erase(instance);
+    VkLayerInstanceDispatchTable *pDisp = *(VkLayerInstanceDispatchTable **) instance;
+    VkResult res = instance_dispatch_table(instance)->DestroyInstance(instance);
+    tableInstanceMap.erase(pDisp);
     return res;
 }
 
@@ -1001,7 +955,7 @@
 
     /* loader uses this to force layer initialization; device object is wrapped */
     if (!strcmp("vkGetDeviceProcAddr", pName)) {
-        initLayerTable((const VkBaseLayerObject *) device);
+        initDeviceTable((const VkBaseLayerObject *) device);
         return (void *) vkGetDeviceProcAddr;
     }
 
@@ -1014,7 +968,7 @@
     ADD_HOOK(vkCreateGraphicsPipeline);
     ADD_HOOK(vkCreateGraphicsPipelineDerivative);
 #undef ADD_HOOK
-    VkLayerDispatchTable* pTable = tableMap[(VkBaseLayerObject *)device];
+    VkLayerDispatchTable* pTable = device_dispatch_table(device);
     if (pTable->GetDeviceProcAddr == NULL)
         return NULL;
     return pTable->GetDeviceProcAddr(device, pName);
@@ -1030,7 +984,7 @@
     loader_platform_thread_once(&g_initOnce, initLayer);
 
     if (!strcmp("vkGetInstanceProcAddr", pName)) {
-        initLayerInstanceTable((const VkBaseLayerObject *) inst);
+        initInstanceTable((const VkBaseLayerObject *) inst);
         return (void *) vkGetInstanceProcAddr;
     }
 #define ADD_HOOK(fn)    \
@@ -1046,7 +1000,7 @@
     if (fptr)
         return fptr;
 
-    VkLayerInstanceDispatchTable* pTable = tableInstanceMap[(VkBaseLayerObject *) inst];
+    VkLayerInstanceDispatchTable* pTable = instance_dispatch_table(inst);
     if (pTable->GetInstanceProcAddr == NULL)
         return NULL;
     return pTable->GetInstanceProcAddr(inst, pName);