layers: Add GetInstanceProcAddr() to all layers

Loader will use this for constructing instance layer instance chains.
Layer instance dispatch table is not yet added.
diff --git a/layers/basic.cpp b/layers/basic.cpp
index 260f7c3..e889e31 100644
--- a/layers/basic.cpp
+++ b/layers/basic.cpp
@@ -49,7 +49,7 @@
         return it->second;
     }
 
-    layer_initialize_dispatch_table(pTable, gpuw->pGPA, (VkPhysicalDevice) gpuw->nextObject);
+    layer_initialize_dispatch_table(pTable, (PFN_vkGetProcAddr) gpuw->pGPA, (VkPhysicalDevice) gpuw->nextObject);
 
     return pTable;
 }
@@ -173,20 +173,47 @@
 
     initLayerTable((const VkBaseLayerObject *) gpu);
 
-    if (!strncmp("vkGetProcAddr", pName, sizeof("vkGetProcAddr")))
+    if (!strcmp("vkGetProcAddr", pName))
         return (void *) vkGetProcAddr;
-    else if (!strncmp("vkCreateDevice", pName, sizeof ("vkCreateDevice")))
+    if (!strcmp("vkCreateDevice", pName))
         return (void *) vkCreateDevice;
-    else if (!strncmp("vkEnumerateLayers", pName, sizeof ("vkEnumerateLayers")))
+    if (!strcmp("GetGlobalExtensionInfo", pName))
+        return (void*) vkGetGlobalExtensionInfo;
+    if (!strcmp("vkEnumerateLayers", pName))
         return (void *) vkEnumerateLayers;
-    else if (!strncmp("vkGetFormatInfo", pName, sizeof ("vkGetFormatInfo")))
+    if (!strcmp("vkGetFormatInfo", pName))
         return (void *) vkGetFormatInfo;
-    else if (!strncmp("vkLayerExtension1", pName, sizeof("vkLayerExtension1")))
+    if (!strcmp("vkLayerExtension1", pName))
         return (void *) vkLayerExtension1;
     else {
         VkBaseLayerObject* gpuw = (VkBaseLayerObject *) gpu;
         if (gpuw->pGPA == NULL)
             return NULL;
-        return gpuw->pGPA((VkPhysicalDevice) gpuw->nextObject, pName);
+        return gpuw->pGPA((VkObject) gpuw->nextObject, pName);
+    }
+}
+
+VK_LAYER_EXPORT void * VKAPI vkGetInstanceProcAddr(VkInstance instance, const char* pName)
+{
+    if (instance == NULL)
+        return NULL;
+
+    // TODO initInstanceLayerTable((const VkBaseLayerObject *) instance);
+
+    if (!strcmp("vkGetInstanceProcAddr", pName))
+        return (void *) vkGetInstanceProcAddr;
+    if (!strcmp("vkGetProcAddr", pName))
+        return (void *) vkGetProcAddr;
+    if (!strcmp("GetGlobalExtensionInfo", pName))
+        return (void*) vkGetGlobalExtensionInfo;
+    if (!strcmp("vkCreateDevice", pName))
+        return (void *) vkCreateDevice;
+    if (!strcmp("vkEnumerateLayers", pName))
+        return (void *) vkEnumerateLayers;
+    else {
+        VkBaseLayerObject* instancew = (VkBaseLayerObject *) instance;
+        if (instancew->pGPA == NULL)
+            return NULL;
+        return instancew->pGPA((VkObject) instancew->nextObject, pName);
     }
 }
diff --git a/layers/draw_state.cpp b/layers/draw_state.cpp
index 024df63..95fa1f5 100755
--- a/layers/draw_state.cpp
+++ b/layers/draw_state.cpp
@@ -1458,7 +1458,7 @@
     // initialize Layer dispatch table
     // TODO handle multiple GPUs
     PFN_vkGetProcAddr fpNextGPA;
-    fpNextGPA = pCurObj->pGPA;
+    fpNextGPA = (PFN_vkGetProcAddr) pCurObj->pGPA;
     assert(fpNextGPA);
 
     layer_initialize_dispatch_table(&nextTable, fpNextGPA, (VkPhysicalDevice) pCurObj->nextObject);
@@ -2872,6 +2872,35 @@
     else {
         if (gpuw->pGPA == NULL)
             return NULL;
-        return gpuw->pGPA((VkPhysicalDevice)gpuw->nextObject, funcName);
+        return gpuw->pGPA((VkObject)gpuw->nextObject, funcName);
+    }
+}
+
+VK_LAYER_EXPORT void * VKAPI vkGetInstanceProcAddr(VkInstance instance, const char* funcName)
+{
+    VkBaseLayerObject* instw = (VkBaseLayerObject *) instance;
+    if (instance == NULL)
+        return NULL;
+
+    //TODO
+    //pCurObj = gpuw;
+    //loader_platform_thread_once(&g_initInstanceOnce, initInstanceDrawState);
+
+    if (!strcmp(funcName, "vkGetInstanceProcAddr"))
+        return (void *) vkGetInstanceProcAddr;
+    if (!strcmp(funcName, "vkGetProcAddr"))
+        return (void *) vkGetProcAddr;
+    if (!strcmp(funcName, "vkCreateDevice"))
+        return (void*) vkCreateDevice;
+    if (!strcmp(funcName, "vkEnumerateLayers"))
+        return (void*) vkEnumerateLayers;
+    if (!strcmp(funcName, "vkDbgRegisterMsgCallback"))
+        return (void*) vkDbgRegisterMsgCallback;
+    if (!strcmp(funcName, "vkDbgUnregisterMsgCallback"))
+        return (void*) vkDbgUnregisterMsgCallback;
+    else {
+        if (instw->pGPA == NULL)
+            return NULL;
+        return instw->pGPA((VkObject) instw->nextObject, funcName);
     }
 }
diff --git a/layers/mem_tracker.cpp b/layers/mem_tracker.cpp
index 0a2d61d..2e9307d 100644
--- a/layers/mem_tracker.cpp
+++ b/layers/mem_tracker.cpp
@@ -793,7 +793,7 @@
     // initialize Layer dispatch table
     // TODO handle multiple GPUs
     PFN_vkGetProcAddr fpNextGPA;
-    fpNextGPA = pCurObj->pGPA;
+    fpNextGPA = (PFN_vkGetProcAddr) pCurObj->pGPA;
     assert(fpNextGPA);
 
     layer_initialize_dispatch_table(&nextTable, fpNextGPA, (VkPhysicalDevice) pCurObj->nextObject);
@@ -2156,6 +2156,8 @@
         return (void*) vkCreateDevice;
     if (!strcmp(funcName, "vkDestroyDevice"))
         return (void*) vkDestroyDevice;
+    if (!strcmp(funcName, "GetGlobalExtensionInfo"))
+        return (void*) vkGetGlobalExtensionInfo;
     if (!strcmp(funcName, "vkEnumerateLayers"))
         return (void*) vkEnumerateLayers;
     if (!strcmp(funcName, "vkQueueSubmit"))
@@ -2296,6 +2298,41 @@
         if (gpuw->pGPA == NULL) {
             return NULL;
         }
-        return gpuw->pGPA((VkPhysicalDevice)gpuw->nextObject, funcName);
+        return gpuw->pGPA((VkObject)gpuw->nextObject, funcName);
+    }
+}
+
+VK_LAYER_EXPORT void* VKAPI vkGetInstanceProcAddr(
+    VkInstance       instance,
+    const char       *funcName)
+{
+    VkBaseLayerObject* instw = (VkBaseLayerObject *) instance;
+
+    if (instance == NULL) {
+        return NULL;
+    }
+    //TODO
+    //pCurObj = instw;
+    //loader_platform_thread_once(&g_initInstanceOnce, initInstanceMemTracker);
+
+    if (!strcmp(funcName, "vkGetProcAddr"))
+        return (void *) vkGetProcAddr;
+    if (!strcmp(funcName, "vkGetInstanceProcAddr"))
+        return (void *) vkGetInstanceProcAddr;
+    if (!strcmp(funcName, "vkCreateDevice"))
+        return (void*) vkCreateDevice;
+    if (!strcmp(funcName, "GetGlobalExtensionInfo"))
+        return (void*) vkGetGlobalExtensionInfo;
+    if (!strcmp(funcName, "vkEnumerateLayers"))
+        return (void*) vkEnumerateLayers;
+        if (!strcmp(funcName, "vkDbgRegisterMsgCallback"))
+        return (void*) vkDbgRegisterMsgCallback;
+    if (!strcmp(funcName, "vkDbgUnregisterMsgCallback"))
+        return (void*) vkDbgUnregisterMsgCallback;
+    else {
+        if (instw->pGPA == NULL) {
+            return NULL;
+        }
+        return instw->pGPA((VkObject)instw->nextObject, funcName);
     }
 }
diff --git a/layers/multi.cpp b/layers/multi.cpp
index b26e67d..78ee302 100644
--- a/layers/multi.cpp
+++ b/layers/multi.cpp
@@ -120,18 +120,42 @@
 
     getLayer1Table(gpuw);
 
-    if (!strncmp("vkCreateDevice", pName, sizeof ("vkCreateDevice")))
+    if (!strcmp("vkCreateDevice", pName))
         return (void *) multi1CreateDevice;
-    else if (!strncmp("vkEnumerateLayers", pName, sizeof ("vkEnumerateLayers")))
+    else if (!strcmp("vkEnumerateLayers", pName))
         return (void *) multi1EnumerateLayers;
-    else if (!strncmp("vkCreateGraphicsPipeline", pName, sizeof ("vkCreateGraphicsPipeline")))
+    else if (!strcmp("GetGlobalExtensionInfo", pName))
+        return (void*) vkGetGlobalExtensionInfo;
+    else if (!strcmp("vkCreateGraphicsPipeline", pName))
         return (void *) multi1CreateGraphicsPipeline;
-    else if (!strncmp("vkStorePipeline", pName, sizeof ("vkStorePipeline")))
+    else if (!strcmp("vkStorePipeline", pName))
         return (void *) multi1StorePipeline;
     else {
         if (gpuw->pGPA == NULL)
             return NULL;
-        return gpuw->pGPA((VkPhysicalDevice) gpuw->nextObject, pName);
+        return gpuw->pGPA((VkObject) gpuw->nextObject, pName);
+    }
+}
+
+VK_LAYER_EXPORT void * VKAPI multi1InstanceGetProcAddr(VkInstance inst, const char* pName)
+{
+    VkBaseLayerObject* instw = (VkBaseLayerObject *) inst;
+
+    if (inst == NULL)
+        return NULL;
+
+    //TODO getLayer1InstanceTable(instw);
+
+    if (!strcmp("vkCreateDevice", pName))
+        return (void *) multi1CreateDevice;
+    else if (!strcmp("vkEnumerateLayers", pName))
+        return (void *) multi1EnumerateLayers;
+    else if (!strcmp("GetGlobalExtensionInfo", pName))
+        return (void*) vkGetGlobalExtensionInfo;
+    else {
+        if (instw->pGPA == NULL)
+            return NULL;
+        return instw->pGPA((VkObject) instw->nextObject, pName);
     }
 }
 
@@ -218,18 +242,42 @@
 
     getLayer2Table(gpuw);
 
-    if (!strncmp("vkCreateDevice", pName, sizeof ("vkCreateDevice")))
+    if (!strcmp("vkCreateDevice", pName))
         return (void *) multi2CreateDevice;
-    else if (!strncmp("vkEnumerateLayers", pName, sizeof ("vkEnumerateLayers")))
+    else if (!strcmp("vkEnumerateLayers", pName))
         return (void *) multi2EnumerateLayers;
-    else if (!strncmp("vkCreateCommandBuffer", pName, sizeof ("vkCreateCommandBuffer")))
+    else if (!strcmp("GetGlobalExtensionInfo", pName))
+        return (void*) vkGetGlobalExtensionInfo;
+    else if (!strcmp("vkCreateCommandBuffer", pName))
         return (void *) multi2CreateCommandBuffer;
-    else if (!strncmp("vkBeginCommandBuffer", pName, sizeof ("vkBeginCommandBuffer")))
+    else if (!strcmp("vkBeginCommandBuffer", pName))
         return (void *) multi2BeginCommandBuffer;
     else {
         if (gpuw->pGPA == NULL)
             return NULL;
-        return gpuw->pGPA((VkPhysicalDevice) gpuw->nextObject, pName);
+        return gpuw->pGPA((VkObject) gpuw->nextObject, pName);
+    }
+}
+
+VK_LAYER_EXPORT void * VKAPI multi2InstanceGetProcAddr(VkInstance inst, const char* pName)
+{
+    VkBaseLayerObject* instw = (VkBaseLayerObject *) inst;
+
+    if (inst == NULL)
+        return NULL;
+
+    //TODO getLayer2InstanceTable(instw);
+
+    if (!strcmp("vkCreateDevice", pName))
+        return (void *) multi2CreateDevice;
+    else if (!strcmp("vkEnumerateLayers", pName))
+        return (void *) multi2EnumerateLayers;
+    else if (!strcmp("GetGlobalExtensionInfo", pName))
+        return (void*) vkGetGlobalExtensionInfo;
+    else {
+        if (instw->pGPA == NULL)
+            return NULL;
+        return instw->pGPA((VkObject) instw->nextObject, pName);
     }
 }
 
@@ -304,11 +352,11 @@
 VK_LAYER_EXPORT void * VKAPI vkGetProcAddr(VkPhysicalDevice gpu, const char* pName)
 {
     // to find each layers GPA routine Loader will search via "<layerName>GetProcAddr"
-    if (!strncmp("multi1GetProcAddr", pName, sizeof("multi1GetProcAddr")))
+    if (!strcmp("multi1GetProcAddr", pName))
         return (void *) multi1GetProcAddr;
-    else if (!strncmp("multi2GetProcAddr", pName, sizeof("multi2GetProcAddr")))
+    else if (!strcmp("multi2GetProcAddr", pName))
         return (void *) multi2GetProcAddr;
-    else if (!strncmp("vkGetProcAddr", pName, sizeof("vkGetProcAddr")))
+    else if (!strcmp("vkGetProcAddr", pName))
         return (void *) vkGetProcAddr;
 
     // use first layer activated as GPA dispatch table activation happens in order
@@ -321,6 +369,31 @@
 
 }
 
+VK_LAYER_EXPORT void * VKAPI vkGetInstanceProcAddr(VkInstance inst, const char* pName)
+{
+    // to find each layers GPA routine Loader will search via "<layerName>GetProcAddr"
+    if (!strcmp("multi1GetProcAddr", pName))
+        return (void *) multi1GetProcAddr;
+    else if (!strcmp("multi2GetProcAddr", pName))
+        return (void *) multi2GetProcAddr;
+    else if (!strcmp("vkGetProcAddr", pName))
+        return (void *) vkGetProcAddr;
+    else if (!strcmp("multi1GetInstanceProcAddr", pName))
+        return (void *) multi1GetProcAddr;
+    else if (!strcmp("multi2GetInstanceProcAddr", pName))
+        return (void *) multi2GetProcAddr;
+    else if (!strcmp("vkGetInstanceProcAddr", pName))
+        return (void *) vkGetProcAddr;
+
+    // use first layer activated as GPA dispatch table activation happens in order
+    else if (layer1_first_activated)
+        return multi1InstanceGetProcAddr(inst, pName);
+    else if (layer2_first_activated)
+        return multi2InstanceGetProcAddr(inst, pName);
+    else
+        return NULL;
+
+}
 #ifdef __cplusplus
 }    //extern "C"
 #endif
@@ -332,5 +405,5 @@
     if (layerNum == 1 && layer2_first_activated == false)
         layer1_first_activated = true;
 
-    layer_initialize_dispatch_table(pTable, gpuw->pGPA, (VkPhysicalDevice) gpuw->nextObject);
+    layer_initialize_dispatch_table(pTable, (PFN_vkGetProcAddr) gpuw->pGPA, (VkPhysicalDevice) gpuw->nextObject);
 }
diff --git a/layers/param_checker.cpp b/layers/param_checker.cpp
index f91518d..a63e4a9 100644
--- a/layers/param_checker.cpp
+++ b/layers/param_checker.cpp
@@ -65,7 +65,7 @@
     }
 
     PFN_vkGetProcAddr fpNextGPA;
-    fpNextGPA = pCurObj->pGPA;
+    fpNextGPA = (PFN_vkGetProcAddr) pCurObj->pGPA;
     assert(fpNextGPA);
 
     layer_initialize_dispatch_table(&nextTable, fpNextGPA, (VkPhysicalDevice) pCurObj->nextObject);
@@ -1953,7 +1953,296 @@
     return result;
 }
 
-#include "vk_generic_intercept_proc_helper.h"
+static inline void* layer_intercept_proc(const char *name)
+{
+    if (!name || name[0] != 'v' || name[1] != 'k')
+        return NULL;
+
+    name += 2;
+    if (!strcmp(name, "CreateInstance"))
+        return (void*) vkCreateInstance;
+    if (!strcmp(name, "DestroyInstance"))
+        return (void*) vkDestroyInstance;
+    if (!strcmp(name, "GetPhysicalDeviceInfo"))
+        return (void*) vkGetPhysicalDeviceInfo;
+    if (!strcmp(name, "GetProcAddr"))
+        return (void*) vkGetProcAddr;
+    if (!strcmp(name, "CreateDevice"))
+        return (void*) vkCreateDevice;
+    if (!strcmp(name, "DestroyDevice"))
+        return (void*) vkDestroyDevice;
+    if (!strcmp(name, "GetGlobalExtensionInfo"))
+        return (void*) vkGetGlobalExtensionInfo;
+    if (!strcmp(name, "GetPhysicalDeviceExtensionInfo"))
+        return (void*) vkGetPhysicalDeviceExtensionInfo;
+    if (!strcmp(name, "EnumerateLayers"))
+        return (void*) vkEnumerateLayers;
+    if (!strcmp(name, "GetDeviceQueue"))
+        return (void*) vkGetDeviceQueue;
+    if (!strcmp(name, "QueueSubmit"))
+        return (void*) vkQueueSubmit;
+    if (!strcmp(name, "QueueWaitIdle"))
+        return (void*) vkQueueWaitIdle;
+    if (!strcmp(name, "DeviceWaitIdle"))
+        return (void*) vkDeviceWaitIdle;
+    if (!strcmp(name, "AllocMemory"))
+        return (void*) vkAllocMemory;
+    if (!strcmp(name, "FreeMemory"))
+        return (void*) vkFreeMemory;
+    if (!strcmp(name, "SetMemoryPriority"))
+        return (void*) vkSetMemoryPriority;
+    if (!strcmp(name, "MapMemory"))
+        return (void*) vkMapMemory;
+    if (!strcmp(name, "UnmapMemory"))
+        return (void*) vkUnmapMemory;
+    if (!strcmp(name, "FlushMappedMemoryRanges"))
+        return (void*) vkFlushMappedMemoryRanges;
+    if (!strcmp(name, "InvalidateMappedMemoryRanges"))
+        return (void*) vkInvalidateMappedMemoryRanges;
+    if (!strcmp(name, "PinSystemMemory"))
+        return (void*) vkPinSystemMemory;
+    if (!strcmp(name, "GetMultiDeviceCompatibility"))
+        return (void*) vkGetMultiDeviceCompatibility;
+    if (!strcmp(name, "OpenSharedMemory"))
+        return (void*) vkOpenSharedMemory;
+    if (!strcmp(name, "OpenSharedSemaphore"))
+        return (void*) vkOpenSharedSemaphore;
+    if (!strcmp(name, "OpenPeerMemory"))
+        return (void*) vkOpenPeerMemory;
+    if (!strcmp(name, "OpenPeerImage"))
+        return (void*) vkOpenPeerImage;
+    if (!strcmp(name, "DestroyObject"))
+        return (void*) vkDestroyObject;
+    if (!strcmp(name, "GetObjectInfo"))
+        return (void*) vkGetObjectInfo;
+    if (!strcmp(name, "CreateFence"))
+        return (void*) vkCreateFence;
+    if (!strcmp(name, "ResetFences"))
+        return (void*) vkResetFences;
+    if (!strcmp(name, "GetFenceStatus"))
+        return (void*) vkGetFenceStatus;
+    if (!strcmp(name, "WaitForFences"))
+        return (void*) vkWaitForFences;
+    if (!strcmp(name, "CreateSemaphore"))
+        return (void*) vkCreateSemaphore;
+    if (!strcmp(name, "QueueSignalSemaphore"))
+        return (void*) vkQueueSignalSemaphore;
+    if (!strcmp(name, "QueueWaitSemaphore"))
+        return (void*) vkQueueWaitSemaphore;
+    if (!strcmp(name, "CreateEvent"))
+        return (void*) vkCreateEvent;
+    if (!strcmp(name, "GetEventStatus"))
+        return (void*) vkGetEventStatus;
+    if (!strcmp(name, "SetEvent"))
+        return (void*) vkSetEvent;
+    if (!strcmp(name, "ResetEvent"))
+        return (void*) vkResetEvent;
+    if (!strcmp(name, "CreateQueryPool"))
+        return (void*) vkCreateQueryPool;
+    if (!strcmp(name, "GetQueryPoolResults"))
+        return (void*) vkGetQueryPoolResults;
+    if (!strcmp(name, "GetFormatInfo"))
+        return (void*) vkGetFormatInfo;
+    if (!strcmp(name, "CreateBuffer"))
+        return (void*) vkCreateBuffer;
+    if (!strcmp(name, "CreateBufferView"))
+        return (void*) vkCreateBufferView;
+    if (!strcmp(name, "CreateImage"))
+        return (void*) vkCreateImage;
+    if (!strcmp(name, "GetImageSubresourceInfo"))
+        return (void*) vkGetImageSubresourceInfo;
+    if (!strcmp(name, "CreateImageView"))
+        return (void*) vkCreateImageView;
+    if (!strcmp(name, "CreateColorAttachmentView"))
+        return (void*) vkCreateColorAttachmentView;
+    if (!strcmp(name, "CreateDepthStencilView"))
+        return (void*) vkCreateDepthStencilView;
+    if (!strcmp(name, "CreateShader"))
+        return (void*) vkCreateShader;
+    if (!strcmp(name, "CreateGraphicsPipeline"))
+        return (void*) vkCreateGraphicsPipeline;
+    if (!strcmp(name, "CreateGraphicsPipelineDerivative"))
+        return (void*) vkCreateGraphicsPipelineDerivative;
+    if (!strcmp(name, "CreateComputePipeline"))
+        return (void*) vkCreateComputePipeline;
+    if (!strcmp(name, "StorePipeline"))
+        return (void*) vkStorePipeline;
+    if (!strcmp(name, "LoadPipeline"))
+        return (void*) vkLoadPipeline;
+    if (!strcmp(name, "LoadPipelineDerivative"))
+        return (void*) vkLoadPipelineDerivative;
+    if (!strcmp(name, "CreatePipelineLayout"))
+        return (void*) vkCreatePipelineLayout;
+    if (!strcmp(name, "CreateSampler"))
+        return (void*) vkCreateSampler;
+    if (!strcmp(name, "CreateDescriptorSetLayout"))
+        return (void*) vkCreateDescriptorSetLayout;
+    if (!strcmp(name, "CreateDescriptorPool"))
+        return (void*) vkCreateDescriptorPool;
+    if (!strcmp(name, "ResetDescriptorPool"))
+        return (void*) vkResetDescriptorPool;
+    if (!strcmp(name, "AllocDescriptorSets"))
+        return (void*) vkAllocDescriptorSets;
+    if (!strcmp(name, "ClearDescriptorSets"))
+        return (void*) vkClearDescriptorSets;
+    if (!strcmp(name, "CreateDynamicViewportState"))
+        return (void*) vkCreateDynamicViewportState;
+    if (!strcmp(name, "CreateDynamicRasterState"))
+        return (void*) vkCreateDynamicRasterState;
+    if (!strcmp(name, "CreateDynamicColorBlendState"))
+        return (void*) vkCreateDynamicColorBlendState;
+    if (!strcmp(name, "CreateDynamicDepthStencilState"))
+        return (void*) vkCreateDynamicDepthStencilState;
+    if (!strcmp(name, "CreateCommandBuffer"))
+        return (void*) vkCreateCommandBuffer;
+    if (!strcmp(name, "BeginCommandBuffer"))
+        return (void*) vkBeginCommandBuffer;
+    if (!strcmp(name, "EndCommandBuffer"))
+        return (void*) vkEndCommandBuffer;
+    if (!strcmp(name, "ResetCommandBuffer"))
+        return (void*) vkResetCommandBuffer;
+    if (!strcmp(name, "CmdBindPipeline"))
+        return (void*) vkCmdBindPipeline;
+    if (!strcmp(name, "CmdBindDynamicStateObject"))
+        return (void*) vkCmdBindDynamicStateObject;
+    if (!strcmp(name, "CmdBindDescriptorSets"))
+        return (void*) vkCmdBindDescriptorSets;
+    if (!strcmp(name, "CmdBindVertexBuffers"))
+        return (void*) vkCmdBindVertexBuffers;
+    if (!strcmp(name, "CmdBindIndexBuffer"))
+        return (void*) vkCmdBindIndexBuffer;
+    if (!strcmp(name, "CmdDraw"))
+        return (void*) vkCmdDraw;
+    if (!strcmp(name, "CmdDrawIndexed"))
+        return (void*) vkCmdDrawIndexed;
+    if (!strcmp(name, "CmdDrawIndirect"))
+        return (void*) vkCmdDrawIndirect;
+    if (!strcmp(name, "CmdDrawIndexedIndirect"))
+        return (void*) vkCmdDrawIndexedIndirect;
+    if (!strcmp(name, "CmdDispatch"))
+        return (void*) vkCmdDispatch;
+    if (!strcmp(name, "CmdDispatchIndirect"))
+        return (void*) vkCmdDispatchIndirect;
+    if (!strcmp(name, "CmdCopyBuffer"))
+        return (void*) vkCmdCopyBuffer;
+    if (!strcmp(name, "CmdCopyImage"))
+        return (void*) vkCmdCopyImage;
+    if (!strcmp(name, "CmdBlitImage"))
+        return (void*) vkCmdBlitImage;
+    if (!strcmp(name, "CmdCopyBufferToImage"))
+        return (void*) vkCmdCopyBufferToImage;
+    if (!strcmp(name, "CmdCopyImageToBuffer"))
+        return (void*) vkCmdCopyImageToBuffer;
+    if (!strcmp(name, "CmdUpdateBuffer"))
+        return (void*) vkCmdUpdateBuffer;
+    if (!strcmp(name, "CmdFillBuffer"))
+        return (void*) vkCmdFillBuffer;
+    if (!strcmp(name, "CmdClearColorImage"))
+        return (void*) vkCmdClearColorImage;
+    if (!strcmp(name, "CmdClearDepthStencil"))
+        return (void*) vkCmdClearDepthStencil;
+    if (!strcmp(name, "CmdResolveImage"))
+        return (void*) vkCmdResolveImage;
+    if (!strcmp(name, "CmdSetEvent"))
+        return (void*) vkCmdSetEvent;
+    if (!strcmp(name, "CmdResetEvent"))
+        return (void*) vkCmdResetEvent;
+    if (!strcmp(name, "CmdWaitEvents"))
+        return (void*) vkCmdWaitEvents;
+    if (!strcmp(name, "CmdPipelineBarrier"))
+        return (void*) vkCmdPipelineBarrier;
+    if (!strcmp(name, "CmdBeginQuery"))
+        return (void*) vkCmdBeginQuery;
+    if (!strcmp(name, "CmdEndQuery"))
+        return (void*) vkCmdEndQuery;
+    if (!strcmp(name, "CmdResetQueryPool"))
+        return (void*) vkCmdResetQueryPool;
+    if (!strcmp(name, "CmdWriteTimestamp"))
+        return (void*) vkCmdWriteTimestamp;
+    if (!strcmp(name, "CmdCopyQueryPoolResults"))
+        return (void*) vkCmdCopyQueryPoolResults;
+    if (!strcmp(name, "CmdInitAtomicCounters"))
+        return (void*) vkCmdInitAtomicCounters;
+    if (!strcmp(name, "CmdLoadAtomicCounters"))
+        return (void*) vkCmdLoadAtomicCounters;
+    if (!strcmp(name, "CmdSaveAtomicCounters"))
+        return (void*) vkCmdSaveAtomicCounters;
+    if (!strcmp(name, "CreateFramebuffer"))
+        return (void*) vkCreateFramebuffer;
+    if (!strcmp(name, "CreateRenderPass"))
+        return (void*) vkCreateRenderPass;
+    if (!strcmp(name, "CmdBeginRenderPass"))
+        return (void*) vkCmdBeginRenderPass;
+    if (!strcmp(name, "CmdEndRenderPass"))
+        return (void*) vkCmdEndRenderPass;
+    if (!strcmp(name, "DbgSetValidationLevel"))
+        return (void*) vkDbgSetValidationLevel;
+    if (!strcmp(name, "DbgRegisterMsgCallback"))
+        return (void*) vkDbgRegisterMsgCallback;
+    if (!strcmp(name, "DbgUnregisterMsgCallback"))
+        return (void*) vkDbgUnregisterMsgCallback;
+    if (!strcmp(name, "DbgSetMessageFilter"))
+        return (void*) vkDbgSetMessageFilter;
+    if (!strcmp(name, "DbgSetObjectTag"))
+        return (void*) vkDbgSetObjectTag;
+    if (!strcmp(name, "DbgSetGlobalOption"))
+        return (void*) vkDbgSetGlobalOption;
+    if (!strcmp(name, "DbgSetDeviceOption"))
+        return (void*) vkDbgSetDeviceOption;
+    if (!strcmp(name, "CmdDbgMarkerBegin"))
+        return (void*) vkCmdDbgMarkerBegin;
+    if (!strcmp(name, "CmdDbgMarkerEnd"))
+        return (void*) vkCmdDbgMarkerEnd;
+    if (!strcmp(name, "GetDisplayInfoWSI"))
+        return (void*) vkGetDisplayInfoWSI;
+    if (!strcmp(name, "CreateSwapChainWSI"))
+        return (void*) vkCreateSwapChainWSI;
+    if (!strcmp(name, "DestroySwapChainWSI"))
+        return (void*) vkDestroySwapChainWSI;
+    if (!strcmp(name, "GetSwapChainInfoWSI"))
+        return (void*) vkGetSwapChainInfoWSI;
+    if (!strcmp(name, "QueuePresentWSI"))
+        return (void*) vkQueuePresentWSI;
+
+    return NULL;
+}
+
+static inline void* layer_intercept_instance_proc(const char *name)
+{
+    if (!name || name[0] != 'v' || name[1] != 'k')
+        return NULL;
+
+    name += 2;
+    if (!strcmp(name, "GetInstanceProcAddr"))
+        return (void*) vkGetInstanceProcAddr;
+    if (!strcmp(name, "CreateInstance"))
+        return (void*) vkCreateInstance;
+    if (!strcmp(name, "DestroyInstance"))
+        return (void*) vkDestroyInstance;
+    if (!strcmp(name, "GetPhysicalDeviceInfo"))
+        return (void*) vkGetPhysicalDeviceInfo;
+    if (!strcmp(name, "GetProcAddr"))
+        return (void*) vkGetProcAddr;
+    if (!strcmp(name, "CreateDevice"))
+        return (void*) vkCreateDevice;
+    if (!strcmp(name, "GetGlobalExtensionInfo"))
+        return (void*) vkGetGlobalExtensionInfo;
+    if (!strcmp(name, "GetPhysicalDeviceExtensionInfo"))
+        return (void*) vkGetPhysicalDeviceExtensionInfo;
+    if (!strcmp(name, "EnumerateLayers"))
+        return (void*) vkEnumerateLayers;
+    if (!strcmp(name, "GetMultiDeviceCompatibility"))
+        return (void*) vkGetMultiDeviceCompatibility;
+    if (!strcmp(name, "DbgRegisterMsgCallback"))
+        return (void*) vkDbgRegisterMsgCallback;
+    if (!strcmp(name, "DbgUnregisterMsgCallback"))
+        return (void*) vkDbgUnregisterMsgCallback;
+    if (!strcmp(name, "DbgSetGlobalOption"))
+        return (void*) vkDbgSetGlobalOption;
+
+    return NULL;
+}
+
 VK_LAYER_EXPORT void* VKAPI vkGetProcAddr(VkPhysicalDevice gpu, const char* funcName)
 {
     VkBaseLayerObject* gpuw = (VkBaseLayerObject *) gpu;
@@ -1969,7 +2258,25 @@
     else {
         if (gpuw->pGPA == NULL)
             return NULL;
-        return gpuw->pGPA((VkPhysicalDevice)gpuw->nextObject, funcName);
+        return gpuw->pGPA((VkObject)gpuw->nextObject, funcName);
     }
 }
 
+VK_LAYER_EXPORT void* VKAPI vkGetInstanceProcAddr(VkInstance inst, const char* funcName)
+{
+    VkBaseLayerObject* instw = (VkBaseLayerObject *) inst;
+    void* addr;
+    if (inst == NULL)
+        return NULL;
+    //TODO pCurObj = instw;
+    //TODO loader_platform_thread_once(&tabOnce, initParamChecker);
+
+    addr = layer_intercept_instance_proc(funcName);
+    if (addr)
+        return addr;
+    else {
+        if (instw->pGPA == NULL)
+            return NULL;
+        return instw->pGPA((VkObject)instw->nextObject, funcName);
+    }
+}
diff --git a/layers/shader_checker.cpp b/layers/shader_checker.cpp
index a576314..f36fee3 100644
--- a/layers/shader_checker.cpp
+++ b/layers/shader_checker.cpp
@@ -159,8 +159,7 @@
         return it->second;
     }
 
-    layer_initialize_dispatch_table(pTable, gpuw->pGPA, (VkPhysicalDevice) gpuw->nextObject);
-    pCurObj = (VkBaseLayerObject *)gpuw->baseObject;
+    layer_initialize_dispatch_table(pTable, (PFN_vkGetProcAddr) gpuw->pGPA, (VkPhysicalDevice) gpuw->nextObject);
 
     return pTable;
 }
@@ -1011,6 +1010,7 @@
 
     ADD_HOOK(vkGetProcAddr);
     ADD_HOOK(vkEnumerateLayers);
+    ADD_HOOK(vkGetGlobalExtensionInfo);
     ADD_HOOK(vkCreateDevice);
     ADD_HOOK(vkCreateShader);
     ADD_HOOK(vkCreateGraphicsPipeline);
@@ -1021,5 +1021,30 @@
     VkBaseLayerObject* gpuw = (VkBaseLayerObject *) gpu;
     if (gpuw->pGPA == NULL)
         return NULL;
-    return gpuw->pGPA((VkPhysicalDevice) gpuw->nextObject, pName);
+    return gpuw->pGPA((VkObject) gpuw->nextObject, pName);
+}
+
+VK_LAYER_EXPORT void * VKAPI vkGetInstanceProcAddr(VkInstance inst, const char* pName)
+{
+    if (inst == NULL)
+        return NULL;
+
+    //TODO initLayerTable((const VkBaseLayerObject *) inst);
+
+    // TODO loader_platform_thread_once(&g_initOnce, initInstanceLayer);
+
+#define ADD_HOOK(fn)    \
+    if (!strncmp(#fn, pName, sizeof(#fn))) \
+        return (void *) fn
+
+    ADD_HOOK(vkGetProcAddr);
+    ADD_HOOK(vkGetInstanceProcAddr);
+    ADD_HOOK(vkEnumerateLayers);
+    ADD_HOOK(vkGetGlobalExtensionInfo);
+    ADD_HOOK(vkCreateDevice);
+
+    VkBaseLayerObject* instw = (VkBaseLayerObject *) inst;
+    if (instw->pGPA == NULL)
+        return NULL;
+    return instw->pGPA((VkObject) instw->nextObject, pName);
 }