layers: Move layer debug action initialization into layer_utils

Also removed dead code from the layer generation script.

Change-Id: I64fdcaaf1aed8152de62079568c8e247333d8c61
diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp
index c0a4dfd..cf0d5ee 100644
--- a/layers/core_validation.cpp
+++ b/layers/core_validation.cpp
@@ -4528,38 +4528,8 @@
 }
 
 static void init_core_validation(layer_data *my_data, const VkAllocationCallbacks *pAllocator) {
-    uint32_t report_flags = 0;
-    uint32_t debug_action = 0;
-    FILE *log_output = NULL;
-    const char *option_str;
-    VkDebugReportCallbackEXT callback;
-    // initialize draw_state options
-    report_flags = getLayerOptionFlags("lunarg_core_validation.report_flags", 0);
-    getLayerOptionEnum("lunarg_core_validation.debug_action", (uint32_t *)&debug_action);
 
-    if (debug_action & VK_DBG_LAYER_ACTION_LOG_MSG) {
-        option_str = getLayerOption("lunarg_core_validation.log_filename");
-        log_output = getLayerLogOutput(option_str, "lunarg_core_validation");
-        VkDebugReportCallbackCreateInfoEXT dbgInfo;
-        memset(&dbgInfo, 0, sizeof(dbgInfo));
-        dbgInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
-        dbgInfo.pfnCallback = log_callback;
-        dbgInfo.pUserData = log_output;
-        dbgInfo.flags = report_flags;
-        layer_create_msg_callback(my_data->report_data, &dbgInfo, pAllocator, &callback);
-        my_data->logging_callback.push_back(callback);
-    }
-
-    if (debug_action & VK_DBG_LAYER_ACTION_DEBUG_OUTPUT) {
-        VkDebugReportCallbackCreateInfoEXT dbgInfo;
-        memset(&dbgInfo, 0, sizeof(dbgInfo));
-        dbgInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
-        dbgInfo.pfnCallback = win32_debug_output_msg;
-        dbgInfo.pUserData = log_output;
-        dbgInfo.flags = report_flags;
-        layer_create_msg_callback(my_data->report_data, &dbgInfo, pAllocator, &callback);
-        my_data->logging_callback.push_back(callback);
-    }
+    layer_debug_actions(my_data->report_data, my_data->logging_callback, pAllocator, "lunarg_core_validation");
 
     if (!globalLockInitialized) {
         loader_platform_thread_create_mutex(&globalLock);
diff --git a/layers/device_limits.cpp b/layers/device_limits.cpp
index 75422bc..cda1ae7 100644
--- a/layers/device_limits.cpp
+++ b/layers/device_limits.cpp
@@ -84,38 +84,8 @@
 template layer_data *get_my_data_ptr<layer_data>(void *data_key, std::unordered_map<void *, layer_data *> &data_map);
 
 static void init_device_limits(layer_data *my_data, const VkAllocationCallbacks *pAllocator) {
-    uint32_t report_flags = 0;
-    uint32_t debug_action = 0;
-    FILE *log_output = NULL;
-    const char *option_str;
-    VkDebugReportCallbackEXT callback;
-    // initialize device_limits options
-    report_flags = getLayerOptionFlags("lunarg_device_limits.report_flags", 0);
-    getLayerOptionEnum("lunarg_device_limits.debug_action", (uint32_t *)&debug_action);
 
-    if (debug_action & VK_DBG_LAYER_ACTION_LOG_MSG) {
-        option_str = getLayerOption("lunarg_device_limits.log_filename");
-        log_output = getLayerLogOutput(option_str, "lunarg_device_limits");
-        VkDebugReportCallbackCreateInfoEXT dbgCreateInfo;
-        memset(&dbgCreateInfo, 0, sizeof(dbgCreateInfo));
-        dbgCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
-        dbgCreateInfo.flags = report_flags;
-        dbgCreateInfo.pfnCallback = log_callback;
-        dbgCreateInfo.pUserData = (void *)log_output;
-        layer_create_msg_callback(my_data->report_data, &dbgCreateInfo, pAllocator, &callback);
-        my_data->logging_callback.push_back(callback);
-    }
-
-    if (debug_action & VK_DBG_LAYER_ACTION_DEBUG_OUTPUT) {
-        VkDebugReportCallbackCreateInfoEXT dbgCreateInfo;
-        memset(&dbgCreateInfo, 0, sizeof(dbgCreateInfo));
-        dbgCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
-        dbgCreateInfo.flags = report_flags;
-        dbgCreateInfo.pfnCallback = win32_debug_output_msg;
-        dbgCreateInfo.pUserData = NULL;
-        layer_create_msg_callback(my_data->report_data, &dbgCreateInfo, pAllocator, &callback);
-        my_data->logging_callback.push_back(callback);
-    }
+    layer_debug_actions(my_data->report_data, my_data->logging_callback, pAllocator, "lunarg_device_limits");
 
     if (!globalLockInitialized) {
         // TODO/TBD: Need to delete this mutex sometime.  How???  One
diff --git a/layers/image.cpp b/layers/image.cpp
index ca7f223..9d7f6cd 100644
--- a/layers/image.cpp
+++ b/layers/image.cpp
@@ -70,35 +70,9 @@
 
 static unordered_map<void *, layer_data *> layer_data_map;
 
-static void InitImage(layer_data *data, const VkAllocationCallbacks *pAllocator) {
-    VkDebugReportCallbackEXT callback;
-    uint32_t report_flags = getLayerOptionFlags("lunarg_image.report_flags", 0);
+static void init_image(layer_data *my_data, const VkAllocationCallbacks *pAllocator) {
 
-    uint32_t debug_action = 0;
-    getLayerOptionEnum("lunarg_image.debug_action", (uint32_t *)&debug_action);
-    if (debug_action & VK_DBG_LAYER_ACTION_LOG_MSG) {
-        FILE *log_output = NULL;
-        const char *option_str = getLayerOption("lunarg_image.log_filename");
-        log_output = getLayerLogOutput(option_str, "lunarg_image");
-        VkDebugReportCallbackCreateInfoEXT dbgInfo;
-        memset(&dbgInfo, 0, sizeof(dbgInfo));
-        dbgInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
-        dbgInfo.pfnCallback = log_callback;
-        dbgInfo.pUserData = log_output;
-        dbgInfo.flags = report_flags;
-        layer_create_msg_callback(data->report_data, &dbgInfo, pAllocator, &callback);
-        data->logging_callback.push_back(callback);
-    }
-
-    if (debug_action & VK_DBG_LAYER_ACTION_DEBUG_OUTPUT) {
-        VkDebugReportCallbackCreateInfoEXT dbgInfo;
-        memset(&dbgInfo, 0, sizeof(dbgInfo));
-        dbgInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
-        dbgInfo.pfnCallback = win32_debug_output_msg;
-        dbgInfo.flags = report_flags;
-        layer_create_msg_callback(data->report_data, &dbgInfo, pAllocator, &callback);
-        data->logging_callback.push_back(callback);
-    }
+    layer_debug_actions(my_data->report_data, my_data->logging_callback, pAllocator, "lunarg_image");
 }
 
 VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
@@ -153,7 +127,7 @@
     my_data->report_data = debug_report_create_instance(my_data->instance_dispatch_table, *pInstance,
                                                         pCreateInfo->enabledExtensionCount, pCreateInfo->ppEnabledExtensionNames);
 
-    InitImage(my_data, pAllocator);
+    init_image(my_data, pAllocator);
 
     return result;
 }
diff --git a/layers/object_tracker.h b/layers/object_tracker.h
index 2c4b9e7..664bf61 100644
--- a/layers/object_tracker.h
+++ b/layers/object_tracker.h
@@ -31,6 +31,7 @@
 #include "vk_layer_extension_utils.h"
 #include "vk_enum_string_helper.h"
 #include "vk_layer_table.h"
+#include "vk_layer_utils.h"
 
 // Object Tracker ERROR codes
 typedef enum _OBJECT_TRACK_ERROR {
@@ -77,11 +78,11 @@
 struct layer_data {
     debug_report_data *report_data;
     // TODO: put instance data here
-    VkDebugReportCallbackEXT logging_callback;
+    std::vector<VkDebugReportCallbackEXT> logging_callback;
     bool wsi_enabled;
     bool objtrack_extensions_enabled;
 
-    layer_data() : report_data(nullptr), logging_callback(VK_NULL_HANDLE), wsi_enabled(false), objtrack_extensions_enabled(false){};
+    layer_data() : report_data(nullptr), wsi_enabled(false), objtrack_extensions_enabled(false){};
 };
 
 struct instExts {
@@ -325,26 +326,10 @@
 #endif
 
 #include "vk_dispatch_table_helper.h"
-static void initObjectTracker(layer_data *my_data, const VkAllocationCallbacks *pAllocator) {
-    uint32_t report_flags = 0;
-    uint32_t debug_action = 0;
-    FILE *log_output = NULL;
-    const char *option_str;
-    // initialize object_tracker options
-    report_flags = getLayerOptionFlags("lunarg_object_tracker.report_flags", 0);
-    getLayerOptionEnum("lunarg_object_tracker.debug_action", (uint32_t *)&debug_action);
 
-    if (debug_action & VK_DBG_LAYER_ACTION_LOG_MSG) {
-        option_str = getLayerOption("lunarg_object_tracker.log_filename");
-        log_output = getLayerLogOutput(option_str, "lunarg_object_tracker");
-        VkDebugReportCallbackCreateInfoEXT dbgInfo;
-        memset(&dbgInfo, 0, sizeof(dbgInfo));
-        dbgInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
-        dbgInfo.pfnCallback = log_callback;
-        dbgInfo.pUserData = log_output;
-        dbgInfo.flags = report_flags;
-        layer_create_msg_callback(my_data->report_data, &dbgInfo, pAllocator, &my_data->logging_callback);
-    }
+static void init_object_tracker(layer_data *my_data, const VkAllocationCallbacks *pAllocator) {
+
+    layer_debug_actions(my_data->report_data, my_data->logging_callback, pAllocator, "lunarg_object_tracker");
 
     if (!objLockInitialized) {
         // TODO/TBD: Need to delete this mutex sometime.  How???  One
@@ -651,7 +636,7 @@
     my_data->report_data = debug_report_create_instance(pInstanceTable, *pInstance, pCreateInfo->enabledExtensionCount,
                                                         pCreateInfo->ppEnabledExtensionNames);
 
-    initObjectTracker(my_data, pAllocator);
+    init_object_tracker(my_data, pAllocator);
     createInstanceRegisterExtensions(pCreateInfo, *pInstance);
 
     create_instance(*pInstance, *pInstance, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT);
diff --git a/layers/param_checker.cpp b/layers/param_checker.cpp
index dd4d572..77c266f 100644
--- a/layers/param_checker.cpp
+++ b/layers/param_checker.cpp
@@ -92,38 +92,9 @@
     return data->report_data;
 }
 
-static void InitParamChecker(layer_data *data, const VkAllocationCallbacks *pAllocator) {
-    VkDebugReportCallbackEXT callback;
-    uint32_t report_flags = getLayerOptionFlags("lunarg_param_checker.report_flags", 0);
+static void init_param_checker(layer_data *my_data, const VkAllocationCallbacks *pAllocator) {
 
-    uint32_t debug_action = 0;
-    getLayerOptionEnum("lunarg_param_checker.debug_action", (uint32_t *)&debug_action);
-    if (debug_action & VK_DBG_LAYER_ACTION_LOG_MSG) {
-        FILE *log_output = NULL;
-        const char *option_str = getLayerOption("lunarg_param_checker.log_filename");
-        log_output = getLayerLogOutput(option_str, "lunarg_param_checker");
-        VkDebugReportCallbackCreateInfoEXT dbgCreateInfo;
-        memset(&dbgCreateInfo, 0, sizeof(dbgCreateInfo));
-        dbgCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
-        dbgCreateInfo.flags = report_flags;
-        dbgCreateInfo.pfnCallback = log_callback;
-        dbgCreateInfo.pUserData = log_output;
-
-        layer_create_msg_callback(data->report_data, &dbgCreateInfo, pAllocator, &callback);
-        data->logging_callback.push_back(callback);
-    }
-
-    if (debug_action & VK_DBG_LAYER_ACTION_DEBUG_OUTPUT) {
-        VkDebugReportCallbackCreateInfoEXT dbgCreateInfo;
-        memset(&dbgCreateInfo, 0, sizeof(dbgCreateInfo));
-        dbgCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
-        dbgCreateInfo.flags = report_flags;
-        dbgCreateInfo.pfnCallback = win32_debug_output_msg;
-        dbgCreateInfo.pUserData = NULL;
-
-        layer_create_msg_callback(data->report_data, &dbgCreateInfo, pAllocator, &callback);
-        data->logging_callback.push_back(callback);
-    }
+    layer_debug_actions(my_data->report_data, my_data->logging_callback, pAllocator, "lunarg_param_checker");
 }
 
 VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
@@ -1380,7 +1351,7 @@
     my_data->report_data =
         debug_report_create_instance(pTable, *pInstance, pCreateInfo->enabledExtensionCount, pCreateInfo->ppEnabledExtensionNames);
 
-    InitParamChecker(my_data, pAllocator);
+    init_param_checker(my_data, pAllocator);
 
     // Ordinarily we'd check these before calling down the chain, but none of the layer
     // support is in place until now, if we survive we can report the issue now.
diff --git a/layers/swapchain.cpp b/layers/swapchain.cpp
index 41622b4..c2fb1b4 100644
--- a/layers/swapchain.cpp
+++ b/layers/swapchain.cpp
@@ -33,6 +33,7 @@
 #include "swapchain.h"
 #include "vk_layer_extension_utils.h"
 #include "vk_enum_string_helper.h"
+#include "vk_layer_utils.h"
 
 static int globalLockInitialized = 0;
 static loader_platform_thread_mutex globalLock;
@@ -230,40 +231,10 @@
 }
 
 #include "vk_dispatch_table_helper.h"
-static void initSwapchain(layer_data *my_data, const VkAllocationCallbacks *pAllocator) {
-    uint32_t report_flags = 0;
-    uint32_t debug_action = 0;
-    FILE *log_output = NULL;
-    const char *option_str;
-    VkDebugReportCallbackEXT callback;
+static void init_swapchain(layer_data *my_data, const VkAllocationCallbacks *pAllocator) {
 
-    // Initialize swapchain options:
-    report_flags = getLayerOptionFlags("lunarg_swapchain.report_flags", 0);
-    getLayerOptionEnum("lunarg_swapchain.debug_action", (uint32_t *)&debug_action);
+    layer_debug_actions(my_data->report_data, my_data->logging_callback, pAllocator, "lunarg_swapchain");
 
-    if (debug_action & VK_DBG_LAYER_ACTION_LOG_MSG) {
-        // Turn on logging, since it was requested:
-        option_str = getLayerOption("lunarg_swapchain.log_filename");
-        log_output = getLayerLogOutput(option_str, "lunarg_swapchain");
-        VkDebugReportCallbackCreateInfoEXT dbgInfo;
-        memset(&dbgInfo, 0, sizeof(dbgInfo));
-        dbgInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
-        dbgInfo.pfnCallback = log_callback;
-        dbgInfo.pUserData = log_output;
-        dbgInfo.flags = report_flags;
-        layer_create_msg_callback(my_data->report_data, &dbgInfo, pAllocator, &callback);
-        my_data->logging_callback.push_back(callback);
-    }
-    if (debug_action & VK_DBG_LAYER_ACTION_DEBUG_OUTPUT) {
-        VkDebugReportCallbackCreateInfoEXT dbgInfo;
-        memset(&dbgInfo, 0, sizeof(dbgInfo));
-        dbgInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
-        dbgInfo.pfnCallback = win32_debug_output_msg;
-        dbgInfo.pUserData = log_output;
-        dbgInfo.flags = report_flags;
-        layer_create_msg_callback(my_data->report_data, &dbgInfo, pAllocator, &callback);
-        my_data->logging_callback.push_back(callback);
-    }
     if (!globalLockInitialized) {
         loader_platform_thread_create_mutex(&globalLock);
         globalLockInitialized = 1;
@@ -318,7 +289,7 @@
 
     // Call the following function after my_data is initialized:
     createInstanceRegisterExtensions(pCreateInfo, *pInstance);
-    initSwapchain(my_data, pAllocator);
+    init_swapchain(my_data, pAllocator);
 
     return result;
 }
diff --git a/layers/threading.cpp b/layers/threading.cpp
index f715014..e7c4b39 100644
--- a/layers/threading.cpp
+++ b/layers/threading.cpp
@@ -38,47 +38,16 @@
 #include "vk_layer_table.h"
 #include "vk_layer_logging.h"
 #include "threading.h"
-
 #include "vk_dispatch_table_helper.h"
 #include "vk_struct_string_helper_cpp.h"
 #include "vk_layer_data.h"
+#include "vk_layer_utils.h"
 
 #include "thread_check.h"
 
 static void initThreading(layer_data *my_data, const VkAllocationCallbacks *pAllocator) {
 
-    uint32_t report_flags = 0;
-    uint32_t debug_action = 0;
-    FILE *log_output = NULL;
-    const char *strOpt;
-    VkDebugReportCallbackEXT callback;
-    // initialize threading options
-    report_flags = getLayerOptionFlags("google_threading.report_flags", 0);
-    getLayerOptionEnum("google_threading.debug_action", (uint32_t *)&debug_action);
-
-    if (debug_action & VK_DBG_LAYER_ACTION_LOG_MSG) {
-        strOpt = getLayerOption("google_threading.log_filename");
-        log_output = getLayerLogOutput(strOpt, "google_threading");
-        VkDebugReportCallbackCreateInfoEXT dbgCreateInfo;
-        memset(&dbgCreateInfo, 0, sizeof(dbgCreateInfo));
-        dbgCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
-        dbgCreateInfo.flags = report_flags;
-        dbgCreateInfo.pfnCallback = log_callback;
-        dbgCreateInfo.pUserData = (void *)log_output;
-        layer_create_msg_callback(my_data->report_data, &dbgCreateInfo, pAllocator, &callback);
-        my_data->logging_callback.push_back(callback);
-    }
-
-    if (debug_action & VK_DBG_LAYER_ACTION_DEBUG_OUTPUT) {
-        VkDebugReportCallbackCreateInfoEXT dbgCreateInfo;
-        memset(&dbgCreateInfo, 0, sizeof(dbgCreateInfo));
-        dbgCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
-        dbgCreateInfo.flags = report_flags;
-        dbgCreateInfo.pfnCallback = win32_debug_output_msg;
-        dbgCreateInfo.pUserData = NULL;
-        layer_create_msg_callback(my_data->report_data, &dbgCreateInfo, pAllocator, &callback);
-        my_data->logging_callback.push_back(callback);
-    }
+    layer_debug_actions(my_data->report_data, my_data->logging_callback, pAllocator, "google_threading");
 
     if (!threadingLockInitialized) {
         loader_platform_thread_create_mutex(&threadingLock);
diff --git a/layers/vk_layer_utils.cpp b/layers/vk_layer_utils.cpp
index 9fea389..43ddc8d 100644
--- a/layers/vk_layer_utils.cpp
+++ b/layers/vk_layer_utils.cpp
@@ -27,7 +27,9 @@
 
 #include <string.h>
 #include <string>
+#include <vector>
 #include "vulkan/vulkan.h"
+#include "vk_layer_config.h"
 #include "vk_layer_utils.h"
 
 typedef struct _VULKAN_FORMAT_INFO {
@@ -608,3 +610,46 @@
     }
     return result;
 }
+
+void layer_debug_actions(debug_report_data *report_data, std::vector<VkDebugReportCallbackEXT> logging_callback,
+                      const VkAllocationCallbacks *pAllocator, const char *layer_identifier) {
+
+    uint32_t report_flags = 0;
+    uint32_t debug_action = 0;
+    FILE *log_output = NULL;
+    const char *option_str;
+    VkDebugReportCallbackEXT callback;
+
+    std::string option_flags = layer_identifier;
+    std::string log_filename = layer_identifier;
+    option_flags.append(".report_flags");
+    log_filename.append(".log_filename");
+
+    // initialize layer options
+    report_flags = getLayerOptionFlags(option_flags.c_str(), 0);
+    getLayerOptionEnum(log_filename.c_str(), (uint32_t *)&debug_action);
+
+    if (debug_action & VK_DBG_LAYER_ACTION_LOG_MSG) {
+        option_str = getLayerOption(log_filename.c_str());
+        log_output = getLayerLogOutput(option_str, layer_identifier);
+        VkDebugReportCallbackCreateInfoEXT dbgCreateInfo;
+        memset(&dbgCreateInfo, 0, sizeof(dbgCreateInfo));
+        dbgCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
+        dbgCreateInfo.flags = report_flags;
+        dbgCreateInfo.pfnCallback = log_callback;
+        dbgCreateInfo.pUserData = (void *)log_output;
+        layer_create_msg_callback(report_data, &dbgCreateInfo, pAllocator, &callback);
+        logging_callback.push_back(callback);
+    }
+
+    if (debug_action & VK_DBG_LAYER_ACTION_DEBUG_OUTPUT) {
+        VkDebugReportCallbackCreateInfoEXT dbgCreateInfo;
+        memset(&dbgCreateInfo, 0, sizeof(dbgCreateInfo));
+        dbgCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
+        dbgCreateInfo.flags = report_flags;
+        dbgCreateInfo.pfnCallback = win32_debug_output_msg;
+        dbgCreateInfo.pUserData = NULL;
+        layer_create_msg_callback(report_data, &dbgCreateInfo, pAllocator, &callback);
+        logging_callback.push_back(callback);
+    }
+}
diff --git a/layers/vk_layer_utils.h b/layers/vk_layer_utils.h
index 1b69e9c..464c248 100644
--- a/layers/vk_layer_utils.h
+++ b/layers/vk_layer_utils.h
@@ -27,6 +27,9 @@
 
 #pragma once
 #include <stdbool.h>
+#include <vector>
+#include "vk_layer_logging.h"
+
 #ifndef WIN32
 #include <strings.h> /* for ffs() */
 #else
@@ -93,6 +96,9 @@
 } VkStringErrorFlagBits;
 typedef VkFlags VkStringErrorFlags;
 
+void layer_debug_actions(debug_report_data* report_data, std::vector<VkDebugReportCallbackEXT> logging_callback,
+    const VkAllocationCallbacks *pAllocator, const char* layer_identifier);
+
 static inline bool vk_format_is_undef(VkFormat format) { return (format == VK_FORMAT_UNDEFINED); }
 
 bool vk_format_is_depth_or_stencil(VkFormat format);
diff --git a/vk-layer-generate.py b/vk-layer-generate.py
index 242d97e..f2abc14 100755
--- a/vk-layer-generate.py
+++ b/vk-layer-generate.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python3
+#!/usr/bin/env python3
 #
 # VK
 #
@@ -306,7 +306,7 @@
         r_body.append('        VkDebugReportCallbackEXT*                    pCallback)')
         r_body.append('{')
         # Switch to this code section for the new per-instance storage and debug callbacks
-        if self.layer_name in ['object_tracker', 'threading', 'unique_objects']:
+        if self.layer_name in ['object_tracker', 'unique_objects']:
             r_body.append('    VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(%s_instance_table_map, instance);' % self.layer_name )
             r_body.append('    VkResult result = pInstanceTable->CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pCallback);')
             r_body.append('    if (VK_SUCCESS == result) {')
@@ -333,7 +333,7 @@
         r_body.append('VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT msgCallback, const VkAllocationCallbacks *pAllocator)')
         r_body.append('{')
         # Switch to this code section for the new per-instance storage and debug callbacks
-        if self.layer_name in ['object_tracker', 'threading', 'unique_objects']:
+        if self.layer_name in ['object_tracker', 'unique_objects']:
             r_body.append('    VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(%s_instance_table_map, instance);' % self.layer_name )
         else:
             r_body.append('    VkLayerInstanceDispatchTable *pInstanceTable = instance_dispatch_table(instance);')
@@ -349,7 +349,7 @@
         r_body.append('VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT    flags, VkDebugReportObjectTypeEXT objType, uint64_t object, size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg)')
         r_body.append('{')
         # Switch to this code section for the new per-instance storage and debug callbacks
-        if self.layer_name == 'object_tracker' or self.layer_name == 'threading':
+        if self.layer_name == 'object_tracker':
             r_body.append('    VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(%s_instance_table_map, instance);' % self.layer_name )
         else:
             r_body.append('    VkLayerInstanceDispatchTable *pInstanceTable = instance_dispatch_table(instance);')
@@ -363,7 +363,7 @@
         ggep_body.append('%s' % self.lineinfo.get())
 
         ggep_body.append('')
-        if self.layer_name == 'object_tracker' or self.layer_name == 'threading':
+        if self.layer_name == 'object_tracker':
             ggep_body.append('static const VkExtensionProperties instance_extensions[] = {')
             ggep_body.append('    {')
             ggep_body.append('        VK_EXT_DEBUG_REPORT_EXTENSION_NAME,')
@@ -372,7 +372,7 @@
             ggep_body.append('};')
         ggep_body.append('VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount,  VkExtensionProperties* pProperties)')
         ggep_body.append('{')
-        if self.layer_name == 'object_tracker' or self.layer_name == 'threading':
+        if self.layer_name == 'object_tracker':
           ggep_body.append('    return util_GetExtensionProperties(1, instance_extensions, pCount, pProperties);')
         else:
           ggep_body.append('    return util_GetExtensionProperties(0, NULL, pCount, pProperties);')
@@ -386,7 +386,7 @@
         ggep_body.append('%s' % self.lineinfo.get())
         ggep_body.append('static const VkLayerProperties globalLayerProps[] = {')
         ggep_body.append('    {')
-        if self.layer_name in ['threading', 'unique_objects']:
+        if self.layer_name in ['unique_objects']:
           ggep_body.append('        "VK_LAYER_GOOGLE_%s",' % layer)
           ggep_body.append('        VK_API_VERSION, // specVersion')
           ggep_body.append('        1, // implementationVersion')
@@ -412,7 +412,7 @@
         gpdlp_body.append('%s' % self.lineinfo.get())
         gpdlp_body.append('static const VkLayerProperties deviceLayerProps[] = {')
         gpdlp_body.append('    {')
-        if self.layer_name in ['threading', 'unique_objects']:
+        if self.layer_name in ['unique_objects']:
           gpdlp_body.append('        "VK_LAYER_GOOGLE_%s",' % layer)
           gpdlp_body.append('        VK_API_VERSION, // specVersion')
           gpdlp_body.append('        1, // implementationVersion')
@@ -524,7 +524,7 @@
 #
 # New style of GPA Functions for the new layer_data/layer_logging changes
 #
-        if self.layer_name in ['object_tracker', 'threading', 'unique_objects']:
+        if self.layer_name in ['object_tracker', 'unique_objects']:
             func_body.append("VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice device, const char* funcName)\n"
                              "{\n"
                              "    PFN_vkVoidFunction addr;\n"
@@ -702,70 +702,8 @@
                          '{\n' % self.layer_name)
         if init_opts:
             func_body.append('%s' % self.lineinfo.get())
-            func_body.append('    uint32_t report_flags = 0;')
-            func_body.append('    uint32_t debug_action = 0;')
-            func_body.append('    FILE *log_output = NULL;')
-            func_body.append('    const char *option_str;\n')
-            func_body.append('    // initialize %s options' % self.layer_name)
-            func_body.append('    report_flags = getLayerOptionFlags("%sReportFlags", 0);' % self.layer_name)
-            func_body.append('    getLayerOptionEnum("%sDebugAction", (uint32_t *) &debug_action);' % self.layer_name)
             func_body.append('')
-            func_body.append('    if (debug_action & VK_DBG_LAYER_ACTION_LOG_MSG)')
-            func_body.append('    {')
-            func_body.append('        option_str = getLayerOption("%sLogFilename");' % self.layer_name)
-            func_body.append('        log_output = getLayerLogOutput(option_str,"%s");' % self.layer_name)
-            func_body.append('        VkDebugReportCallbackCreateInfoEXT dbgCreateInfo;')
-            func_body.append('        memset(&dbgCreateInfo, 0, sizeof(dbgCreateInfo));')
-            func_body.append('        dbgCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;')
-            func_body.append('        dbgCreateInfo.flags = report_flags;')
-            func_body.append('        dbgCreateInfo.pfnCallback = log_callback;')
-            func_body.append('        dbgCreateInfo.pUserData = NULL;')
-            func_body.append('        layer_create_msg_callback(my_data->report_data, &dbgCreateInfo, pAllocator,')
-            func_body.append('                                  &my_data->logging_callback);')
-            func_body.append('    }')
-            func_body.append('')
-        if lockname is not None:
-            func_body.append('%s' % self.lineinfo.get())
-            func_body.append("    if (!%sLockInitialized)" % lockname)
-            func_body.append("    {")
-            func_body.append("        // TODO/TBD: Need to delete this mutex sometime.  How???")
-            func_body.append("        loader_platform_thread_create_mutex(&%sLock);" % lockname)
-            if condname is not None:
-                func_body.append("        loader_platform_thread_init_cond(&%sCond);" % condname)
-            func_body.append("        %sLockInitialized = 1;" % lockname)
-            func_body.append("    }")
-        func_body.append("}\n")
-        func_body.append('')
-        return "\n".join(func_body)
-
-    def _generate_new_layer_initialization(self, init_opts=False, prefix='vk', lockname=None, condname=None):
-        func_body = ["#include \"vk_dispatch_table_helper.h\""]
-        func_body.append('%s' % self.lineinfo.get())
-        func_body.append('static void init_%s(layer_data *my_data, const VkAllocationCallbacks *pAllocator)\n'
-                         '{\n' % self.layer_name)
-        if init_opts:
-            func_body.append('%s' % self.lineinfo.get())
-            func_body.append('    uint32_t report_flags = 0;')
-            func_body.append('    uint32_t debug_action = 0;')
-            func_body.append('    FILE *log_output = NULL;')
-            func_body.append('    const char *strOpt;')
-            func_body.append('    // initialize %s options' % self.layer_name)
-            func_body.append('    report_flags = getLayerOptionFlags("%sReportFlags", 0);' % self.layer_name)
-            func_body.append('    getLayerOptionEnum("%sDebugAction", (uint32_t *) &debug_action);' % self.layer_name)
-            func_body.append('')
-            func_body.append('    if (debug_action & VK_DBG_LAYER_ACTION_LOG_MSG)')
-            func_body.append('    {')
-            func_body.append('        strOpt = getLayerOption("%sLogFilename");' % self.layer_name)
-            func_body.append('        log_output = getLayerLogOutput(strOpt, "%s");' % self.layer_name)
-            func_body.append('        VkDebugReportCallbackCreateInfoEXT dbgCreateInfo;')
-            func_body.append('        memset(&dbgCreateInfo, 0, sizeof(dbgCreateInfo));')
-            func_body.append('        dbgCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;')
-            func_body.append('        dbgCreateInfo.flags = report_flags;')
-            func_body.append('        dbgCreateInfo.pfnCallback = log_callback;')
-            func_body.append('        dbgCreateInfo.pUserData = log_output;')
-            func_body.append('        layer_create_msg_callback(my_data->report_data, &dbgCreateInfo, pAllocator,')
-            func_body.append('                                  &my_data->logging_callback);')
-            func_body.append('    }')
+            func_body.append('    layer_debug_actions(my_data->report_data, my_data->logging_callback, pAllocator, "lunarg_%s");' % self.layer_name)
             func_body.append('')
         if lockname is not None:
             func_body.append('%s' % self.lineinfo.get())
@@ -1060,10 +998,12 @@
         gedi_txt.append('    VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(object_tracker_instance_table_map, instance);')
         gedi_txt.append('    pInstanceTable->DestroyInstance(instance, pAllocator);')
         gedi_txt.append('')
-        gedi_txt.append('    // Clean up logging callback, if any')
         gedi_txt.append('    layer_data *my_data = get_my_data_ptr(key, layer_data_map);')
-        gedi_txt.append('    if (my_data->logging_callback) {')
-        gedi_txt.append('        layer_destroy_msg_callback(my_data->report_data, my_data->logging_callback, pAllocator);')
+        gedi_txt.append('    // Clean up logging callback, if any')
+        gedi_txt.append('    while (my_data->logging_callback.size() > 0) {')
+        gedi_txt.append('        VkDebugReportCallbackEXT callback = my_data->logging_callback.back();')
+        gedi_txt.append('        layer_destroy_msg_callback(my_data->report_data, callback, pAllocator);')
+        gedi_txt.append('        my_data->logging_callback.pop_back();')
         gedi_txt.append('    }')
         gedi_txt.append('')
         gedi_txt.append('    layer_debug_report_destroy_instance(mid(instance));')
@@ -1761,294 +1701,6 @@
                                                   instance_extensions)]
         return "\n\n".join(body)
 
-class ThreadingSubcommand(Subcommand):
-    thread_check_dispatchable_objects = [
-        "VkQueue",
-        "VkCommandBuffer",
-    ]
-    thread_check_nondispatchable_objects = [
-        "VkDeviceMemory",
-        "VkBuffer",
-        "VkImage",
-        "VkDescriptorSet",
-        "VkDescriptorPool",
-        "VkSemaphore"
-    ]
-    thread_check_object_types = {
-        'VkInstance' : 'VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT',
-        'VkPhysicalDevice' : 'VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT',
-        'VkDevice' : 'VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT',
-        'VkQueue' : 'VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT',
-        'VkCommandBuffer' : 'VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT',
-        'VkFence' : 'VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT',
-        'VkDeviceMemory' : 'VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT',
-        'VkBuffer' : 'VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT',
-        'VkImage' : 'VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT',
-        'VkSemaphore' : 'VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT',
-        'VkEvent' : 'VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT',
-        'VkQueryPool' : 'VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT',
-        'VkBufferView' : 'VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT',
-        'VkImageView' : 'VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT',
-        'VkShaderModule' : 'VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT',
-        'VkShader' : 'VK_DEBUG_REPORT_OBJECT_TYPE_SHADER',
-        'VkPipelineCache' : 'VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT',
-        'VkPipelineLayout' : 'VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT',
-        'VkRenderPass' : 'VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT',
-        'VkPipeline' : 'VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT',
-        'VkDescriptorSetLayout' : 'VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT',
-        'VkSampler' : 'VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT',
-        'VkDescriptorPool' : 'VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT',
-        'VkDescriptorSet' : 'VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT',
-        'VkFramebuffer' : 'VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT',
-        'VkCommandPool' : 'VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT',
-    }
-    def generate_useObject(self, ty):
-        obj_type = self.thread_check_object_types[ty]
-        key = "object"
-        msg_object = "(uint64_t)(object)"
-        header_txt = []
-        header_txt.append('%s' % self.lineinfo.get())
-        header_txt.append('static void use%s(const void* dispatchable_object, %s object)' % (ty, ty))
-        header_txt.append('{')
-        header_txt.append('    loader_platform_thread_id tid = loader_platform_get_thread_id();')
-        header_txt.append('    loader_platform_thread_lock_mutex(&threadingLock);')
-        header_txt.append('    if (%sObjectsInUse.find(%s) == %sObjectsInUse.end()) {' % (ty, key, ty))
-        header_txt.append('        %sObjectsInUse[%s] = tid;' % (ty, key))
-        header_txt.append('    } else {')
-        header_txt.append('        if (%sObjectsInUse[%s] != tid) {' % (ty, key))
-        header_txt.append('            log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_ERROR_BIT_EXT, %s, %s,' % (obj_type, msg_object))
-        header_txt.append('                __LINE__, THREADING_CHECKER_MULTIPLE_THREADS, "THREADING",')
-        header_txt.append('                "THREADING ERROR : object of type %s is simultaneously used in thread %%ld and thread %%ld",' % (ty))
-        header_txt.append('                %sObjectsInUse[%s], tid);' % (ty, key))
-        header_txt.append('            // Wait for thread-safe access to object')
-        header_txt.append('            while (%sObjectsInUse.find(%s) != %sObjectsInUse.end()) {' % (ty, key, ty))
-        header_txt.append('                loader_platform_thread_cond_wait(&threadingCond, &threadingLock);')
-        header_txt.append('            }')
-        header_txt.append('            %sObjectsInUse[%s] = tid;' % (ty, key))
-        header_txt.append('        } else {')
-        header_txt.append('            log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_ERROR_BIT_EXT, %s, %s,' % (obj_type, msg_object))
-        header_txt.append('                __LINE__, THREADING_CHECKER_MULTIPLE_THREADS, "THREADING",')
-        header_txt.append('                "THREADING ERROR : object of type %s is recursively used in thread %%ld",' % (ty))
-        header_txt.append('                tid);')
-        header_txt.append('        }')
-        header_txt.append('    }')
-        header_txt.append('    loader_platform_thread_unlock_mutex(&threadingLock);')
-        header_txt.append('}')
-        return "\n".join(header_txt)
-    def generate_finishUsingObject(self, ty):
-        key = "object"
-        header_txt = []
-        header_txt.append('%s' % self.lineinfo.get())
-        header_txt.append('static void finishUsing%s(%s object)' % (ty, ty))
-        header_txt.append('{')
-        header_txt.append('    // Object is no longer in use')
-        header_txt.append('    loader_platform_thread_lock_mutex(&threadingLock);')
-        header_txt.append('    %sObjectsInUse.erase(%s);' % (ty, key))
-        header_txt.append('    loader_platform_thread_cond_broadcast(&threadingCond);')
-        header_txt.append('    loader_platform_thread_unlock_mutex(&threadingLock);')
-        header_txt.append('}')
-        return "\n".join(header_txt)
-    def generate_header(self):
-        header_txt = []
-        header_txt.append('%s' % self.lineinfo.get())
-        header_txt.append('#include <stdio.h>')
-        header_txt.append('#include <stdlib.h>')
-        header_txt.append('#include <string.h>')
-        header_txt.append('#include <unordered_map>')
-        header_txt.append('#include "vk_loader_platform.h"')
-        header_txt.append('#include "vulkan/vk_layer.h"')
-        header_txt.append('#include "threading.h"')
-        header_txt.append('#include "vk_layer_config.h"')
-        header_txt.append('#include "vk_layer_extension_utils.h"')
-        header_txt.append('#include "vk_enum_validate_helper.h"')
-        header_txt.append('#include "vk_struct_validate_helper.h"')
-        header_txt.append('#include "vk_layer_table.h"')
-        header_txt.append('#include "vk_layer_logging.h"')
-        header_txt.append('')
-        header_txt.append('')
-        header_txt.append('static LOADER_PLATFORM_THREAD_ONCE_DECLARATION(initOnce);')
-        header_txt.append('')
-        header_txt.append('using namespace std;')
-        for ty in self.thread_check_dispatchable_objects:
-            header_txt.append('static unordered_map<%s, loader_platform_thread_id> %sObjectsInUse;' % (ty, ty))
-        for ty in self.thread_check_nondispatchable_objects:
-            header_txt.append('static unordered_map<%s, loader_platform_thread_id> %sObjectsInUse;' % (ty, ty))
-        header_txt.append('static int threadingLockInitialized = 0;')
-        header_txt.append('static loader_platform_thread_mutex threadingLock;')
-        header_txt.append('static loader_platform_thread_cond threadingCond;')
-        header_txt.append('%s' % self.lineinfo.get())
-        for ty in self.thread_check_dispatchable_objects + self.thread_check_nondispatchable_objects:
-            header_txt.append(self.generate_useObject(ty))
-            header_txt.append(self.generate_finishUsingObject(ty))
-        header_txt.append('%s' % self.lineinfo.get())
-        return "\n".join(header_txt)
-
-    def generate_intercept(self, proto, qual):
-        if proto.name in [ 'CreateDebugReportCallbackEXT' ]:
-            # use default version
-            return None
-        decl = proto.c_func(prefix="vk", attr="VKAPI")
-        ret_val = ''
-        stmt = ''
-        funcs = []
-        table = 'device'
-        if proto.ret != "void":
-            ret_val = "%s result = " % proto.ret
-            stmt = "    return result;\n"
-        if proto_is_global(proto):
-           table = 'instance'
-
-        # Memory range calls are special in needed thread checking within structs
-        if proto.name in ["FlushMappedMemoryRanges","InvalidateMappedMemoryRanges"]:
-            funcs.append('%s' % self.lineinfo.get())
-            funcs.append('%s%s\n' % (qual, decl) +
-                     '{\n'
-                     '    for (uint32_t i=0; i<memoryRangeCount; i++) {\n'
-                     '        useVkDeviceMemory((const void *) %s, pMemoryRanges[i].memory);\n' % proto.params[0].name +
-                     '    }\n'
-                     '    VkLayerDispatchTable *pDeviceTable = get_dispatch_table(threading_%s_table_map, %s);\n' % (table, proto.params[0].name) +
-                     '    %s pDeviceTable->%s;\n' % (ret_val, proto.c_call()) +
-                     '    for (uint32_t i=0; i<memoryRangeCount; i++) {\n'
-                     '        finishUsingVkDeviceMemory(pMemoryRanges[i].memory);\n'
-                     '    }\n'
-                     '%s' % (stmt) +
-                     '}')
-            return "\n".join(funcs)
-        # All functions that do a Get are thread safe
-        if 'Get' in proto.name:
-            return None
-        # All WSI functions are thread safe
-        if 'KHR' in proto.name:
-            return None
-        # Initialize in early calls
-        if proto.name == "CreateDevice":
-            funcs.append('%s' % self.lineinfo.get())
-            funcs.append('%s%s\n' % (qual, decl) +
-                     '{\n'
-                     '    VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);\n'
-                     '    PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;\n'
-                     '    PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr;\n'
-                     '    PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice) fpGetInstanceProcAddr(NULL, "vkCreateDevice");\n'
-                     '    if (fpCreateDevice == NULL) {\n'
-                     '        return VK_ERROR_INITIALIZATION_FAILED;\n'
-                     '    }\n'
-                     '    // Advance the link info for the next element on the chain\n'
-                     '    chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;\n'
-                     '    VkResult result = fpCreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice);\n'
-                     '    if (result != VK_SUCCESS) {\n'
-                     '        return result;\n'
-                     '    }\n'
-                     '    layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);\n'
-                     '    layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);\n'
-                     '    initDeviceTable(*pDevice, fpGetDeviceProcAddr, threading_device_table_map);\n'
-                     '    my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice);\n'
-                     '    return result;\n'
-                     '}\n')
-            return "\n".join(funcs)
-        elif proto.params[0].ty == "VkPhysicalDevice":
-            return None
-        # Functions changing command buffers need thread safe use of first parameter
-        if proto.params[0].ty == "VkCommandBuffer":
-            funcs.append('%s' % self.lineinfo.get())
-            funcs.append('%s%s\n' % (qual, decl) +
-                     '{\n'
-                     '    use%s((const void *) %s, %s);\n' % (proto.params[0].ty, proto.params[0].name, proto.params[0].name) +
-                     '    VkLayerDispatchTable *pDeviceTable = get_dispatch_table(threading_%s_table_map, %s);\n' % (table, proto.params[0].name) +
-                     '    %spDeviceTable->%s;\n' % (ret_val, proto.c_call()) +
-                     '    finishUsing%s(%s);\n' % (proto.params[0].ty, proto.params[0].name) +
-                     '%s' % stmt +
-                     '}')
-            return "\n".join(funcs)
-        # Non-Cmd functions that do a Wait are thread safe
-        if 'Wait' in proto.name:
-            return None
-        # Watch use of certain types of objects passed as any parameter
-        checked_params = []
-        for param in proto.params:
-            if param.ty in self.thread_check_dispatchable_objects or param.ty in self.thread_check_nondispatchable_objects:
-                checked_params.append(param)
-        if proto.name == "DestroyDevice":
-            funcs.append('%s%s\n' % (qual, decl) +
-                         '{\n'
-                         '    dispatch_key key = get_dispatch_key(device);\n'
-                         '    VkLayerDispatchTable *pDeviceTable = get_dispatch_table(threading_%s_table_map, %s);\n' % (table, proto.params[0].name) +
-                         '    %spDeviceTable->%s;\n' % (ret_val, proto.c_call()) +
-                         '    threading_device_table_map.erase(key);\n'
-                         '}\n')
-            return "\n".join(funcs);
-        elif proto.name == "DestroyInstance":
-            funcs.append('%s%s\n' % (qual, decl) +
-                         '{\n'
-                         '    dispatch_key key = get_dispatch_key(instance);\n'
-                         '    VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(threading_instance_table_map, %s);\n' % proto.params[0].name +
-                         '    %spInstanceTable->%s;\n' % (ret_val, proto.c_call()) +
-                         '    destroy_dispatch_table(threading_instance_table_map, key);\n'
-                         '\n'
-                         '    // Clean up logging callback, if any\n'
-                         '    layer_data *my_data = get_my_data_ptr(key, layer_data_map);\n'
-                         '    if (my_data->logging_callback) {\n'
-                         '        layer_destroy_msg_callback(my_data->report_data, my_data->logging_callback, pAllocator);\n'
-                         '    }\n'
-                         '\n'
-                         '    layer_debug_report_destroy_instance(my_data->report_data);\n'
-                         '    layer_data_map.erase(pInstanceTable);\n'
-                         '\n'
-                         '    threading_instance_table_map.erase(key);\n'
-                         '}\n')
-            return "\n".join(funcs);
-        elif proto.name == "CreateInstance":
-            funcs.append('%s%s\n'
-                         '{\n'
-                         '    VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);\n'
-                         '    PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;\n'
-                         '    PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance) fpGetInstanceProcAddr(NULL, "vkCreateInstance");\n'
-                         '    if (fpCreateInstance == NULL) {\n'
-                         '        return VK_ERROR_INITIALIZATION_FAILED;\n'
-                         '    }\n'
-                         '    // Advance the link info for the next element on the chain\n'
-                         '    chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;\n'
-                         '    VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance);\n'
-                         '    if (result != VK_SUCCESS) {\n'
-                         '        return result;\n'
-                         '    }\n'
-                         '    VkLayerInstanceDispatchTable *pTable = initInstanceTable(*pInstance, fpGetInstanceProcAddr, threading_instance_table_map);\n'
-                         '    layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);\n'
-                         '    my_data->report_data = debug_report_create_instance(\n'
-                         '            pTable,\n'
-                         '            *pInstance,\n'
-                         '            pCreateInfo->enabledExtensionCount,\n'
-                         '            pCreateInfo->ppEnabledExtensionNames);\n'
-                         '    init_threading(my_data, pAllocator);\n'
-                         '    return result;\n'
-                         '}\n' % (qual, decl))
-            return "\n".join(funcs);
-        if len(checked_params) == 0:
-            return None
-        # Surround call with useObject and finishUsingObject for each checked_param
-        funcs.append('%s' % self.lineinfo.get())
-        funcs.append('%s%s' % (qual, decl))
-        funcs.append('{')
-        for param in checked_params:
-            funcs.append('    use%s((const void *) %s, %s);' % (param.ty, proto.params[0].name, param.name))
-        funcs.append('    VkLayerDispatchTable *pDeviceTable = get_dispatch_table(threading_%s_table_map, %s);' % (table, proto.params[0].name));
-        funcs.append('    %spDeviceTable->%s;' % (ret_val, proto.c_call()))
-        for param in checked_params:
-            funcs.append('    finishUsing%s(%s);' % (param.ty, param.name))
-        funcs.append('%s'
-                 '}' % stmt)
-        return "\n".join(funcs)
-
-    def generate_body(self):
-        self.layer_name = "threading"
-        body = [self._generate_new_layer_initialization(True, lockname='threading', condname='threading'),
-                self._generate_dispatch_entrypoints("VK_LAYER_EXPORT"),
-                self._generate_layer_gpa_function(extensions=[],
-                                                  instance_extensions=[('msg_callback_get_proc_addr', [])]),
-                self._gen_create_msg_callback(),
-                self._gen_destroy_msg_callback(),
-                self._gen_debug_report_msg()]
-        return "\n\n".join(body)
-
 def main():
     wsi = {
             "Win32",
@@ -2061,7 +1713,6 @@
 
     subcommands = {
             "object_tracker" : ObjectTrackerSubcommand,
-            "threading" : ThreadingSubcommand,
             "unique_objects" : UniqueObjectsSubcommand,
     }