layers: Simplify threadchecker GPA handling

Change-Id: I11cdc2f6524926714d22abd08fba0a670a3a4a97
diff --git a/layers/threading.cpp b/layers/threading.cpp
index 7808a81..b3e2a17 100644
--- a/layers/threading.cpp
+++ b/layers/threading.cpp
@@ -203,13 +203,6 @@
     1, "Google Validation Layer",
 };
 
-static inline PFN_vkVoidFunction layer_intercept_proc(const char *name) {
-    for (unsigned int i = 0; i < sizeof(procmap) / sizeof(procmap[0]); i++) {
-        if (!strcmp(name, procmap[i].name)) return procmap[i].pFunc;
-    }
-    return NULL;
-}
-
 VKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceLayerProperties(uint32_t *pCount, VkLayerProperties *pProperties) {
     return util_GetLayerProperties(1, &layerProps, pCount, pProperties);
 }
@@ -243,62 +236,28 @@
 // Need to prototype this call because it's internal and does not show up in vk.xml
 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetPhysicalDeviceProcAddr(VkInstance instance, const char *funcName);
 
-static inline PFN_vkVoidFunction layer_intercept_instance_proc(const char *name) {
-    if (!name || name[0] != 'v' || name[1] != 'k') return NULL;
-
-    name += 2;
-    if (!strcmp(name, "CreateInstance")) return (PFN_vkVoidFunction)CreateInstance;
-    if (!strcmp(name, "DestroyInstance")) return (PFN_vkVoidFunction)DestroyInstance;
-    if (!strcmp(name, "EnumerateInstanceLayerProperties")) return (PFN_vkVoidFunction)EnumerateInstanceLayerProperties;
-    if (!strcmp(name, "EnumerateInstanceExtensionProperties")) return (PFN_vkVoidFunction)EnumerateInstanceExtensionProperties;
-    if (!strcmp(name, "EnumerateDeviceLayerProperties")) return (PFN_vkVoidFunction)EnumerateDeviceLayerProperties;
-    if (!strcmp(name, "EnumerateDeviceExtensionProperties")) return (PFN_vkVoidFunction)EnumerateDeviceExtensionProperties;
-    if (!strcmp(name, "CreateDevice")) return (PFN_vkVoidFunction)CreateDevice;
-    if (!strcmp(name, "GetInstanceProcAddr")) return (PFN_vkVoidFunction)GetInstanceProcAddr;
-    if (!strcmp(name, "GetPhysicalDeviceProcAddr")) return (PFN_vkVoidFunction)GetPhysicalDeviceProcAddr;
-
-    return NULL;
-}
-
 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetDeviceProcAddr(VkDevice device, const char *funcName) {
-    PFN_vkVoidFunction addr;
-    layer_data *dev_data;
+    const auto item = name_to_funcptr_map.find(funcName);
+    if (item != name_to_funcptr_map.end()) {
+        return reinterpret_cast<PFN_vkVoidFunction>(item->second);
+    }
 
-    assert(device);
-
-    addr = layer_intercept_proc(funcName);
-    if (addr) return addr;
-
-    dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
-    VkLayerDispatchTable *pTable = dev_data->device_dispatch_table;
-
-    if (pTable->GetDeviceProcAddr == NULL) return NULL;
-    return pTable->GetDeviceProcAddr(device, funcName);
+    layer_data *device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
+    auto &table = device_data->device_dispatch_table;
+    if (!table->GetDeviceProcAddr) return nullptr;
+    return table->GetDeviceProcAddr(device, funcName);
 }
 
 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetInstanceProcAddr(VkInstance instance, const char *funcName) {
-    PFN_vkVoidFunction addr;
-    layer_data *my_data;
-
-    addr = layer_intercept_instance_proc(funcName);
-    if (!addr) addr = layer_intercept_proc(funcName);
-    if (addr) {
-        return addr;
+    const auto item = name_to_funcptr_map.find(funcName);
+    if (item != name_to_funcptr_map.end()) {
+        return reinterpret_cast<PFN_vkVoidFunction>(item->second);
     }
 
-    assert(instance);
-
-    my_data = GetLayerDataPtr(get_dispatch_key(instance), layer_data_map);
-    addr = debug_report_get_instance_proc_addr(my_data->report_data, funcName);
-    if (addr) {
-        return addr;
-    }
-
-    VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table;
-    if (pTable->GetInstanceProcAddr == NULL) {
-        return NULL;
-    }
-    return pTable->GetInstanceProcAddr(instance, funcName);
+    auto instance_data = GetLayerDataPtr(get_dispatch_key(instance), layer_data_map);
+    auto &table = instance_data->instance_dispatch_table;
+    if (!table->GetInstanceProcAddr) return nullptr;
+    return table->GetInstanceProcAddr(instance, funcName);
 }
 
 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetPhysicalDeviceProcAddr(VkInstance instance, const char *funcName) {
diff --git a/scripts/threading_generator.py b/scripts/threading_generator.py
index 97d7df0..174b011 100644
--- a/scripts/threading_generator.py
+++ b/scripts/threading_generator.py
@@ -18,6 +18,7 @@
 # limitations under the License.
 #
 # Author: Mike Stroyan <stroyan@google.com>
+# Author: Mark Lobodzinski <mark@lunarg.com>
 
 import os,re,sys
 from generator import *
@@ -271,8 +272,8 @@
         # Finish C++ namespace and multiple inclusion protection
         self.newline()
         # record intercepted procedures
-        write('// intercepts', file=self.outFile)
-        write('struct { const char* name; PFN_vkVoidFunction pFunc;} procmap[] = {', file=self.outFile)
+        write('// Map of all APIs to be intercepted by this layer', file=self.outFile)
+        write('static const std::unordered_map<std::string, void*> name_to_funcptr_map = {', file=self.outFile)
         write('\n'.join(self.intercepts), file=self.outFile)
         write('};\n', file=self.outFile)
         self.newline()
@@ -364,13 +365,6 @@
     # Command generation
     def genCmd(self, cmdinfo, name):
         # Commands shadowed by interface functions and are not implemented
-        interface_functions = [
-            'vkEnumerateInstanceLayerProperties',
-            'vkEnumerateInstanceExtensionProperties',
-            'vkEnumerateDeviceLayerProperties',
-        ]
-        if name in interface_functions:
-            return
         special_functions = [
             'vkGetDeviceProcAddr',
             'vkGetInstanceProcAddr',
@@ -384,13 +378,17 @@
             'vkDestroyDebugReportCallbackEXT',
             'vkAllocateDescriptorSets',
             'vkGetSwapchainImagesKHR',
+            'vkEnumerateInstanceLayerProperties',
+            'vkEnumerateInstanceExtensionProperties',
+            'vkEnumerateDeviceLayerProperties',
+            'vkEnumerateDeviceExtensionProperties',
         ]
         if name in special_functions:
             decls = self.makeCDecls(cmdinfo.elem)
             self.appendSection('command', '')
             self.appendSection('command', '// declare only')
             self.appendSection('command', decls[0])
-            self.intercepts += [ '    {"%s", reinterpret_cast<PFN_vkVoidFunction>(%s)},' % (name,name[2:]) ]
+            self.intercepts += [ '    {"%s", (void*)%s},' % (name,name[2:]) ]
             return
         if "QueuePresentKHR" in name or ("DebugMarker" in name and "EXT" in name):
             self.appendSection('command', '// TODO - not wrapping EXT function ' + name)
@@ -403,7 +401,7 @@
         # record that the function will be intercepted
         if (self.featureExtraProtect != None):
             self.intercepts += [ '#ifdef %s' % self.featureExtraProtect ]
-        self.intercepts += [ '    {"%s", reinterpret_cast<PFN_vkVoidFunction>(%s)},' % (name,name[2:]) ]
+        self.intercepts += [ '    {"%s", (void*)%s},' % (name,name[2:]) ]
         if (self.featureExtraProtect != None):
             self.intercepts += [ '#endif' ]