WSI Validation: Ported better logging approach from generic layer.
diff --git a/layers/swapchain.cpp b/layers/swapchain.cpp
index b45007f..3143741 100644
--- a/layers/swapchain.cpp
+++ b/layers/swapchain.cpp
@@ -36,13 +36,17 @@
 
 #include "swapchain.h"
 
+
 // FIXME/TODO: Make sure this layer is thread-safe!
 
+
 // The following is for logging error messages:
-static layer_data mydata;
+static std::unordered_map<void *, layer_data *> layer_data_map;
 
+template layer_data *get_my_data_ptr<layer_data>(
+        void *data_key,
+        std::unordered_map<void *, layer_data *> &data_map);
 
-static LOADER_PLATFORM_THREAD_ONCE_DECLARATION(initOnce);
 
 // NOTE: The following are for keeping track of info that is used for
 // validating the WSI extensions.
@@ -71,6 +75,7 @@
         deviceMap[device].pPhysicalDevice = pPhysicalDevice;
         pPhysicalDevice->pDevice = &deviceMap[device];
     } else {
+        layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
         LOG_ERROR_NON_VALID_OBJ(VK_OBJECT_TYPE_PHYSICAL_DEVICE,
                                 physicalDevice,
                                 "VkPhysicalDevice");
@@ -119,7 +124,7 @@
 
 
 #include "vk_dispatch_table_helper.h"
-static void initSwapchain(void)
+static void initSwapchain(layer_data *my_data)
 {
     uint32_t report_flags = 0;
     uint32_t debug_action = 0;
@@ -135,9 +140,9 @@
         // Turn on logging, since it was requested:
         option_str = getLayerOption("SwapchainLogFilename");
         log_output = getLayerLogOutput(option_str, "Swapchain");
-        layer_create_msg_callback(mydata.report_data, report_flags,
+        layer_create_msg_callback(my_data->report_data, report_flags,
                                   log_callback, (void *) log_output,
-                                  &mydata.logging_callback);
+                                  &my_data->logging_callback);
     }
 }
 
@@ -205,7 +210,15 @@
     VkResult result = instance_dispatch_table(*pInstance)->CreateInstance(pCreateInfo, pInstance);
     if (result == VK_SUCCESS) {
         // Since it succeeded, do layer-specific work:
+        layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
+        my_data->report_data = debug_report_create_instance(
+                                   instance_dispatch_table(*pInstance),
+                                   *pInstance,
+                                   pCreateInfo->extensionCount,
+                                   pCreateInfo->ppEnabledExtensionNames);
+        // Call the following function after my_data is initialized:
         createInstanceRegisterExtensions(pCreateInfo, *pInstance);
+        initSwapchain(my_data);
     }
     return result;
 }
@@ -217,6 +230,7 @@
     // Validate that a valid VkInstance was used:
     SwpInstance *pInstance = &instanceMap[instance];
     if (!pInstance) {
+        layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
         skipCall |= LOG_ERROR_NON_VALID_OBJ(VK_OBJECT_TYPE_INSTANCE,
                                             instance,
                                             "VkInstance");
@@ -227,6 +241,15 @@
         dispatch_key key = get_dispatch_key(instance);
         VkLayerInstanceDispatchTable *pDisp = instance_dispatch_table(instance);
         pDisp->DestroyInstance(instance);
+
+        // Clean up logging callback, if any
+        layer_data *my_data = get_my_data_ptr(key, layer_data_map);
+        if (my_data->logging_callback) {
+            layer_destroy_msg_callback(my_data->report_data, my_data->logging_callback);
+        }
+        layer_debug_report_destroy_instance(my_data->report_data);
+        layer_data_map.erase(key);
+
         destroy_instance_dispatch_table(key);
     }
 
@@ -252,6 +275,7 @@
     // Validate that a valid VkInstance was used:
     SwpInstance *pInstance = &instanceMap[instance];
     if (!pInstance) {
+        layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
         skipCall |= LOG_ERROR_NON_VALID_OBJ(VK_OBJECT_TYPE_INSTANCE,
                                             instance,
                                             "VkInstance");
@@ -286,6 +310,7 @@
 {
     VkResult result = VK_SUCCESS;
     VkBool32 skipCall = VK_FALSE;
+    layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
 
     // Validate that a valid VkPhysicalDevice was used:
     SwpPhysicalDevice *pPhysicalDevice = &physicalDeviceMap[physicalDevice];
@@ -301,6 +326,7 @@
                 physicalDevice, pCreateInfo, pDevice);
         if (result == VK_SUCCESS) {
             // Since it succeeded, do layer-specific work:
+            my_data->report_data = layer_debug_report_create_device(my_data->report_data, *pDevice);
             createDeviceRegisterExtensions(physicalDevice, pCreateInfo,
                                            *pDevice);
         }
@@ -312,6 +338,7 @@
 VK_LAYER_EXPORT void VKAPI vkDestroyDevice(VkDevice device)
 {
     VkBool32 skipCall = VK_FALSE;
+    layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
 
     // Validate that a valid VkDevice was used:
     SwpDevice *pDevice = &deviceMap[device];
@@ -363,6 +390,7 @@
 {
     VkResult result = VK_SUCCESS;
     VkBool32 skipCall = VK_FALSE;
+    layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
 
     // Validate that a valid VkPhysicalDevice was used, and that the instance
     // extension was enabled:
@@ -406,6 +434,7 @@
 {
     VkResult result = VK_SUCCESS;
     VkBool32 skipCall = VK_FALSE;
+    layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
 
     // Validate that a valid VkDevice was used, and that the device
     // extension was enabled:
@@ -442,6 +471,7 @@
 {
     VkResult result = VK_SUCCESS;
     VkBool32 skipCall = VK_FALSE;
+    layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
 
     // Validate that a valid VkDevice was used, and that the device
     // extension was enabled:
@@ -487,6 +517,7 @@
 {
     VkResult result = VK_SUCCESS;
     VkBool32 skipCall = VK_FALSE;
+    layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
 
     // Validate that a valid VkDevice was used, and that the device
     // extension was enabled:
@@ -537,6 +568,7 @@
 // assumes a new swapchain is being created).
     VkResult result = VK_SUCCESS;
     VkBool32 skipCall = VK_FALSE;
+    layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     char fn[] = "vkCreateSwapchainKHR";
 
     // Validate that a valid VkDevice was used, and that the device
@@ -647,7 +679,7 @@
                 }
             }
             // Log the message that we've built up:
-            skipCall |= debug_report_log_msg(mydata.report_data,
+            skipCall |= debug_report_log_msg(my_data->report_data,
                                              VK_DBG_REPORT_ERROR_BIT,
                                              VK_OBJECT_TYPE_DEVICE,
                                              (uint64_t) device, 0, 
@@ -805,6 +837,7 @@
 VK_LAYER_EXPORT VkResult VKAPI vkDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain)
 {
     VkBool32 skipCall = VK_FALSE;
+    layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
 
     // Validate that a valid VkDevice was used, and that the device
     // extension was enabled:
@@ -858,6 +891,7 @@
 {
     VkResult result = VK_SUCCESS;
     VkBool32 skipCall = VK_FALSE;
+    layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
 
     // Validate that a valid VkDevice was used, and that the device
     // extension was enabled:
@@ -913,6 +947,7 @@
 // (e.g. VK_ERROR_OUT_OF_DATE_KHR).
     VkResult result = VK_SUCCESS;
     VkBool32 skipCall = VK_FALSE;
+    layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
 
     // Validate that a valid VkDevice was used, and that the device
     // extension was enabled:
@@ -989,6 +1024,7 @@
 //   (e.g. VK_ERROR_OUT_OF_DATE_KHR).
     VkResult result = VK_SUCCESS;
     VkBool32 skipCall = VK_FALSE;
+    layer_data *my_data = get_my_data_ptr(get_dispatch_key(queue), layer_data_map);
 
     for (int i = 0; i < pPresentInfo->swapchainCount ; i++) {
         int index = pPresentInfo->imageIndices[i];
@@ -1094,13 +1130,20 @@
 
 VK_LAYER_EXPORT VkResult VKAPI vkDbgCreateMsgCallback(VkInstance instance, VkFlags msgFlags, const PFN_vkDbgMsgCallback pfnMsgCallback, void* pUserData, VkDbgMsgCallback* pMsgCallback)
 {
-    return layer_create_msg_callback(mydata.report_data, msgFlags, pfnMsgCallback, pUserData, pMsgCallback);
+    VkResult result = instance_dispatch_table(instance)->DbgCreateMsgCallback(instance, msgFlags, pfnMsgCallback, pUserData, pMsgCallback);
+    if (VK_SUCCESS == result) {
+        layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
+        result = layer_create_msg_callback(my_data->report_data, msgFlags, pfnMsgCallback, pUserData, pMsgCallback);
+    }
+    return result;
 }
 
 VK_LAYER_EXPORT VkResult VKAPI vkDbgDestroyMsgCallback(VkInstance instance, VkDbgMsgCallback msgCallback)
 {
-    layer_destroy_msg_callback(mydata.report_data, msgCallback);
-    return VK_SUCCESS;
+    VkResult result = instance_dispatch_table(instance)->DbgDestroyMsgCallback(instance, msgCallback);
+    layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
+    layer_destroy_msg_callback(my_data->report_data, msgCallback);
+    return result;
 }
 
 VK_LAYER_EXPORT PFN_vkVoidFunction VKAPI vkGetDeviceProcAddr(VkDevice device, const char* funcName)
@@ -1109,7 +1152,6 @@
     if (device == VK_NULL_HANDLE) {
         return NULL;
     }
-    loader_platform_thread_once(&initOnce, initSwapchain);
 
     /* loader uses this to force layer initialization; device object is wrapped */
     if (!strcmp("vkGetDeviceProcAddr", funcName)) {
@@ -1155,7 +1197,6 @@
     if (instance == VK_NULL_HANDLE) {
         return NULL;
     }
-    loader_platform_thread_once(&initOnce, initSwapchain);
 
     /* loader uses this to force layer initialization; instance object is wrapped */
     if (!strcmp("vkGetInstanceProcAddr", funcName)) {
@@ -1168,6 +1209,12 @@
         return addr;
 
     VkLayerInstanceDispatchTable* pTable = instance_dispatch_table(instance);
+    layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
+    addr = debug_report_get_instance_proc_addr(my_data->report_data, funcName);
+    if (addr) {
+        return addr;
+    }
+
     if (instanceMap.size() != 0 &&
         instanceMap[instance].swapchainExtensionEnabled)
     {
diff --git a/layers/swapchain.h b/layers/swapchain.h
index 24774c1..80a6ea4 100644
--- a/layers/swapchain.h
+++ b/layers/swapchain.h
@@ -87,16 +87,22 @@
 
 #define LAYER_NAME (char *) "Swapchain"
 #define LOG_ERROR_NON_VALID_OBJ(objType, type, obj)                     \
-    log_msg(mydata.report_data, VK_DBG_REPORT_ERROR_BIT, (objType),    \
-            (uint64_t) (obj), 0, SWAPCHAIN_INVALID_HANDLE, LAYER_NAME,  \
-            "%s() called with a non-valid %s.", __FUNCTION__, (obj))
+    (my_data) ?                                                         \
+        log_msg(my_data->report_data, VK_DBG_REPORT_ERROR_BIT, (objType), \
+                (uint64_t) (obj), 0, SWAPCHAIN_INVALID_HANDLE, LAYER_NAME, \
+                "%s() called with a non-valid %s.", __FUNCTION__, (obj)) \
+    : VK_FALSE
 
 #define LOG_ERROR(objType, type, obj, enm, fmt, ...)                    \
-    log_msg(mydata.report_data, VK_DBG_REPORT_ERROR_BIT, (objType),    \
-            (uint64_t) (obj), 0, (enm), LAYER_NAME, (fmt), __VA_ARGS__)
+    (my_data) ?                                                         \
+        log_msg(my_data->report_data, VK_DBG_REPORT_ERROR_BIT, (objType), \
+                (uint64_t) (obj), 0, (enm), LAYER_NAME, (fmt), __VA_ARGS__) \
+    : VK_FALSE
 #define LOG_PERF_WARNING(objType, type, obj, enm, fmt, ...)             \
-    log_msg(mydata.report_data, VK_DBG_REPORT_PERF_WARN_BIT, (objType), \
-            (uint64_t) (obj), 0, (enm), LAYER_NAME, (fmt), __VA_ARGS__)
+    (my_data) ?                                                         \
+        log_msg(my_data->report_data, VK_DBG_REPORT_PERF_WARN_BIT, (objType), \
+                (uint64_t) (obj), 0, (enm), LAYER_NAME, (fmt), __VA_ARGS__) \
+    : VK_FALSE
 
 
 // NOTE: The following struct's/typedef's are for keeping track of