extensions: begin changes for extension support

This patch starts restructuring the various components
(loader, driver, layers, etc.) to support global and
device extensions. Require GetProcAddr to access the
extension functions and related support.
diff --git a/include/vkDbg.h b/include/vkDbg.h
index f828eb8..9e5fb6e 100644
--- a/include/vkDbg.h
+++ b/include/vkDbg.h
@@ -25,12 +25,12 @@
 
 typedef enum _VK_DBG_MSG_TYPE
 {
-    VK_DBG_MSG_UNKNOWN      = 0x0,
-    VK_DBG_MSG_ERROR        = 0x1,
+    VK_DBG_REPORT_INFO_BIT      = 0x0,
+    VK_DBG_REPORT_ERROR_BIT        = 0x1,
     VK_DBG_MSG_WARNING      = 0x2,
     VK_DBG_MSG_PERF_WARNING = 0x3,
 
-    VK_DBG_MSG_TYPE_BEGIN_RANGE = VK_DBG_MSG_UNKNOWN,
+    VK_DBG_MSG_TYPE_BEGIN_RANGE = VK_DBG_REPORT_INFO_BIT,
     VK_DBG_MSG_TYPE_END_RANGE   = VK_DBG_MSG_PERF_WARNING,
     VK_NUM_DBG_MSG_TYPE         = (VK_DBG_MSG_TYPE_END_RANGE - VK_DBG_MSG_TYPE_BEGIN_RANGE + 1),
 } VK_DBG_MSG_TYPE;
@@ -68,55 +68,6 @@
     VK_NUM_DBG_DEVICE_OPTION         = (VK_DBG_DEVICE_OPTION_END_RANGE - VK_DBG_DEVICE_OPTION_BEGIN_RANGE + 1),
 } VK_DBG_DEVICE_OPTION;
 
-typedef enum _VK_DBG_OBJECT_TYPE
-{
-    VK_DBG_OBJECT_UNKNOWN                = 0x00,
-    VK_DBG_OBJECT_DEVICE                 = 0x01,
-    VK_DBG_OBJECT_QUEUE                  = 0x02,
-    VK_DBG_OBJECT_GPU_MEMORY             = 0x03,
-    VK_DBG_OBJECT_IMAGE                  = 0x04,
-    VK_DBG_OBJECT_IMAGE_VIEW             = 0x05,
-    VK_DBG_OBJECT_COLOR_TARGET_VIEW      = 0x06,
-    VK_DBG_OBJECT_DEPTH_STENCIL_VIEW     = 0x07,
-    VK_DBG_OBJECT_SHADER                 = 0x08,
-    VK_DBG_OBJECT_GRAPHICS_PIPELINE      = 0x09,
-    VK_DBG_OBJECT_COMPUTE_PIPELINE       = 0x0a,
-    VK_DBG_OBJECT_SAMPLER                = 0x0b,
-    VK_DBG_OBJECT_DESCRIPTOR_SET         = 0x0c,
-    VK_DBG_OBJECT_VIEWPORT_STATE         = 0x0d,
-    VK_DBG_OBJECT_RASTER_STATE           = 0x0e,
-    VK_DBG_OBJECT_MSAA_STATE             = 0x0f,
-    VK_DBG_OBJECT_COLOR_BLEND_STATE      = 0x10,
-    VK_DBG_OBJECT_DEPTH_STENCIL_STATE    = 0x11,
-    VK_DBG_OBJECT_CMD_BUFFER             = 0x12,
-    VK_DBG_OBJECT_FENCE                  = 0x13,
-    VK_DBG_OBJECT_SEMAPHORE              = 0x14,
-    VK_DBG_OBJECT_EVENT                  = 0x15,
-    VK_DBG_OBJECT_QUERY_POOL             = 0x16,
-    VK_DBG_OBJECT_SHARED_GPU_MEMORY      = 0x17,
-    VK_DBG_OBJECT_SHARED_SEMAPHORE       = 0x18,
-    VK_DBG_OBJECT_PEER_GPU_MEMORY        = 0x19,
-    VK_DBG_OBJECT_PEER_IMAGE             = 0x1a,
-    VK_DBG_OBJECT_PINNED_GPU_MEMORY      = 0x1b,
-    VK_DBG_OBJECT_INTERNAL_GPU_MEMORY    = 0x1c,
-    VK_DBG_OBJECT_FRAMEBUFFER            = 0x1d,
-    VK_DBG_OBJECT_RENDER_PASS            = 0x1e,
-
-    VK_DBG_OBJECT_INSTANCE,
-    VK_DBG_OBJECT_BUFFER,
-    VK_DBG_OBJECT_BUFFER_VIEW,
-    VK_DBG_OBJECT_DESCRIPTOR_SET_LAYOUT,
-    VK_DBG_OBJECT_PIPELINE_LAYOUT,
-    VK_DBG_OBJECT_DESCRIPTOR_POOL,
-
-    VK_DBG_OBJECT_DISPLAY_WSI,
-    VK_DBG_OBJECT_SWAP_CHAIN_WSI,
-
-    VK_DBG_OBJECT_TYPE_BEGIN_RANGE = VK_DBG_OBJECT_UNKNOWN,
-    VK_DBG_OBJECT_TYPE_END_RANGE   = VK_DBG_OBJECT_SWAP_CHAIN_WSI,
-    VK_NUM_DBG_OBJECT_TYPE         = (VK_DBG_OBJECT_TYPE_END_RANGE - VK_DBG_OBJECT_TYPE_BEGIN_RANGE + 1),
-} VK_DBG_OBJECT_TYPE;
-
 typedef void (VKAPI *VK_DBG_MSG_CALLBACK_FUNCTION)(
     VK_DBG_MSG_TYPE      msgType,
     VkValidationLevel    validationLevel,
diff --git a/include/vkLayer.h b/include/vkLayer.h
index f30ef25..883cca1 100644
--- a/include/vkLayer.h
+++ b/include/vkLayer.h
@@ -5,7 +5,9 @@
 #pragma once
 
 #include "vulkan.h"
-#include "vkDbg.h"
+#include "vk_debug_report_lunarg.h"
+#include "vk_debug_marker_lunarg.h"
+#include "vk_wsi_lunarg.h"
 #include "vk_wsi_lunarg.h"
 #if defined(__GNUC__) && __GNUC__ >= 4
 #  define VK_LAYER_EXPORT __attribute__((visibility("default")))
@@ -130,16 +132,19 @@
     PFN_vkCreateRenderPass CreateRenderPass;
     PFN_vkCmdBeginRenderPass CmdBeginRenderPass;
     PFN_vkCmdEndRenderPass CmdEndRenderPass;
-    PFN_vkDbgSetValidationLevel DbgSetValidationLevel;
-    PFN_vkDbgSetMessageFilter DbgSetMessageFilter;
     PFN_vkDbgSetObjectTag DbgSetObjectTag;
-    PFN_vkDbgSetDeviceOption DbgSetDeviceOption;
     PFN_vkCmdDbgMarkerBegin CmdDbgMarkerBegin;
     PFN_vkCmdDbgMarkerEnd CmdDbgMarkerEnd;
     PFN_vkCreateSwapChainWSI CreateSwapChainWSI;
     PFN_vkDestroySwapChainWSI DestroySwapChainWSI;
     PFN_vkGetSwapChainInfoWSI GetSwapChainInfoWSI;
     PFN_vkQueuePresentWSI QueuePresentWSI;
+    PFN_vkDbgCreateMsgCallback DbgCreateMsgCallback;
+    PFN_vkDbgDestroyMsgCallback DbgDestroyMsgCallback;
+    PFN_vkDbgStringCallback DbgStringCallback;
+    PFN_vkDbgStdioCallback DbgStdioCallback;
+    PFN_vkDbgBreakCallback DbgBreakCallback;
+    PFN_vkDbgSetObjectName DbgSetObjectName;
 } VkLayerDispatchTable;
 
 typedef struct VkLayerInstanceDispatchTable_
@@ -152,38 +157,32 @@
     PFN_vkCreateDevice CreateDevice;
     PFN_vkGetGlobalExtensionInfo GetGlobalExtensionInfo;
     PFN_vkGetPhysicalDeviceExtensionInfo GetPhysicalDeviceExtensionInfo;
-    PFN_vkEnumerateLayers EnumerateLayers;
     PFN_vkGetMultiDeviceCompatibility GetMultiDeviceCompatibility;
-    PFN_vkDbgRegisterMsgCallback DbgRegisterMsgCallback;
-    PFN_vkDbgUnregisterMsgCallback DbgUnregisterMsgCallback;
-    PFN_vkDbgSetGlobalOption DbgSetGlobalOption;
     PFN_vkGetDisplayInfoWSI GetDisplayInfoWSI;
+    PFN_vkDbgCreateMsgCallback DbgCreateMsgCallback;
+    PFN_vkDbgDestroyMsgCallback DbgDestroyMsgCallback;
+    PFN_vkDbgStringCallback DbgStringCallback;
+    PFN_vkDbgStdioCallback DbgStdioCallback;
+    PFN_vkDbgBreakCallback DbgBreakCallback;
 } VkLayerInstanceDispatchTable;
 
 // LL node for tree of dbg callback functions
-typedef struct _VK_LAYER_DBG_FUNCTION_NODE
+typedef struct VkLayerDbgFunctionNode_
 {
-    VK_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback;
-    void *pUserData;
-    struct _VK_LAYER_DBG_FUNCTION_NODE *pNext;
-} VK_LAYER_DBG_FUNCTION_NODE;
+    VkDbgMsgCallback msgCallback;
+    PFN_vkDbgMsgCallback pfnMsgCallback;
+    VkFlags msgFlags;
+    const void *pUserData;
+    struct VkLayerDbgFunctionNode_ *pNext;
+} VkLayerDbgFunctionNode;
 
-typedef enum _VK_LAYER_DBG_ACTION
+typedef enum VkLayerDbgAction_
 {
     VK_DBG_LAYER_ACTION_IGNORE = 0x0,
     VK_DBG_LAYER_ACTION_CALLBACK = 0x1,
     VK_DBG_LAYER_ACTION_LOG_MSG = 0x2,
     VK_DBG_LAYER_ACTION_BREAK = 0x4
-} VK_LAYER_DBG_ACTION;
+} VkLayerDbgAction;
 
-typedef enum _VK_LAYER_DBG_REPORT_LEVEL
-{
-
-    VK_DBG_LAYER_LEVEL_INFO = 0,
-    VK_DBG_LAYER_LEVEL_WARN,
-    VK_DBG_LAYER_LEVEL_PERF_WARN,
-    VK_DBG_LAYER_LEVEL_ERROR,
-    VK_DBG_LAYER_LEVEL_NONE,
-} VK_LAYER_DBG_REPORT_LEVEL;
 // ------------------------------------------------------------------------------------------------
 // API functions
diff --git a/include/vk_dbg.h b/include/vk_dbg.h
index f7f3fc6..9ccf570 100644
--- a/include/vk_dbg.h
+++ b/include/vk_dbg.h
@@ -30,7 +30,9 @@
 #include "vulkan.h"
 
 #define VK_DEBUG_REPORT_EXTENSION_NUMBER 2
+#define VK_DEBUG_REPORT_EXTENSION_VERSION 1
 #define VK_DEBUG_MARKER_EXTENSION_NUMBER 3
+#define VK_DEBUG_MARKER_EXTENSION_VERSION 1
 #ifdef __cplusplus
 extern "C"
 {
@@ -42,22 +44,23 @@
 ***************************************************************************************************
 */
 
+#define DEBUG_REPORT_EXTENSION_NAME "DEBUG_REPORT"
+#define DEBUG_MARKER_EXTENSION_NAME "DEBUG_MARKER"
+
 VK_DEFINE_NONDISP_SUBCLASS_HANDLE(VkDbgMsgCallback, VkObject)
 
 // ------------------------------------------------------------------------------------------------
 // Enumerations
 
-typedef enum VkDbgLevel_
+typedef enum VkDbgReportFlags_
 {
-    VK_DBG_LEVEL_INFO_BIT       = 0x00000001,
-    VK_DBG_LEVEL_WARN_BIT       = 0x00000002,
-    VK_DBG_LEVEL_PERF_WARN_BIT  = 0x00000004,
-    VK_DBG_LEVEL_ERROR_BIT      = 0x00000008,
-
-    VK_ENUM_RANGE(DBG_LEVEL, INFO_BIT, ERROR_BIT)
+    VK_DBG_REPORT_INFO_BIT       = VK_BIT(0),
+    VK_DBG_REPORT_WARN_BIT       = VK_BIT(1),
+    VK_DBG_REPORT_PERF_WARN_BIT  = VK_BIT(2),
+    VK_DBG_REPORT_ERROR_BIT      = VK_BIT(3),
 } VkDbgReportFlags;
 
-#define VK_DBG_ENUM_EXTEND(type,id)    ((type)(VK_DEBUG_MARKER_EXTENSION_NUMBER * -1000 + (id))
+#define VK_DBG_ENUM_EXTEND(type, id)    ((type)(VK_DEBUG_MARKER_EXTENSION_NUMBER * -1000 + (id)))
 
 #define VK_OBJECT_INFO_TYPE_DBG_OBJECT_TAG VK_DBG_ENUM_EXTEND(VkObjectInfoType, 0)
 #define VK_OBJECT_INFO_TYPE_DBG_OBJECT_NAME VK_DBG_ENUM_EXTEND(VkObjectInfoType, 1)
@@ -66,7 +69,7 @@
 // ------------------------------------------------------------------------------------------------
 // Vulkan function pointers
 
-typedef void (VKAPI *PFN_vkDbgMsgCallback)(
+typedef void (*PFN_vkDbgMsgCallback)(
     VkFlags                             msgFlags,
     VkObjectType                        objType,
     VkObject                            srcObject,
@@ -79,10 +82,11 @@
 // ------------------------------------------------------------------------------------------------
 // API functions
 
-typedef VkResult (VKAPI *PFN_vkDbgCreateMsgCallback)(VkInstance instance, VkFlags msgFlags, const PFN_vkDbgMsgCallback pfnMsgCallback, const void* pUserData, const VkDbgMsgCallback* pMsgCallback);
-typedef void (VKAPI *PFN_vkStringCallback)(VkFlags msgFlags, VkObjectType objType, VkObject srcObject, size_t location, int32_t msgCode, const char* pLayerPrefix, const char* pMsg, void* pUserData);
-typedef void (VKAPI *PFN_vkStdioCallback)(VkFlags msgFlags, VkObjectType objType, VkObject srcObject, size_t location, int32_t msgCode, const char* pLayerPrefix, const char* pMsg, void* pUserData);
-typedef void (VKAPI *PFN_vkBreakCallback)(VkFlags msgFlags, VkObjectType objType, VkObject srcObject, size_t location, int32_t msgCode, const char* pLayerPrefix, const char* pMsg, void* pUserData);
+typedef VkResult (VKAPI *PFN_vkDbgCreateMsgCallback)(VkInstance instance, VkFlags msgFlags, const PFN_vkDbgMsgCallback pfnMsgCallback, void* pUserData, VkDbgMsgCallback* pMsgCallback);
+typedef VkResult (VKAPI *PFN_vkDbgDestroyMsgCallback)(VkInstance instance, VkDbgMsgCallback pMsgCallback);
+typedef void (VKAPI *PFN_vkDbgStringCallback)(VkFlags msgFlags, VkObjectType objType, VkObject srcObject, size_t location, int32_t msgCode, const char* pLayerPrefix, const char* pMsg, void* pUserData);
+typedef void (VKAPI *PFN_vkDbgStdioCallback)(VkFlags msgFlags, VkObjectType objType, VkObject srcObject, size_t location, int32_t msgCode, const char* pLayerPrefix, const char* pMsg, void* pUserData);
+typedef void (VKAPI *PFN_vkDbgBreakCallback)(VkFlags msgFlags, VkObjectType objType, VkObject srcObject, size_t location, int32_t msgCode, const char* pLayerPrefix, const char* pMsg, void* pUserData);
 typedef void (VKAPI *PFN_vkCmdDbgMarkerBegin)(VkCmdBuffer cmdBuffer, const char* pMarker);
 typedef void (VKAPI *PFN_vkCmdDbgMarkerEnd)(VkCmdBuffer cmdBuffer);
 typedef VkResult (VKAPI *PFN_vkDbgSetObjectTag)(VkDevice device, VkObjectType objType, VkObject object, size_t tagSize, const void* pTag);
@@ -95,11 +99,15 @@
     VkInstance                          instance,
     VkFlags                             msgFlags,
     const PFN_vkDbgMsgCallback          pfnMsgCallback,
-    const void*                         pUserData,
-    const VkDbgMsgCallback*             pMsgCallback);
+    void*                               pUserData,
+    VkDbgMsgCallback*                   pMsgCallback);
+
+VkResult VKAPI vkDbgDestroyMsgCallback(
+    VkInstance                          instance,
+    VkDbgMsgCallback                    pMsgCallback);
 
 // DebugReport utility callback functions
-void VKAPI vkStringCallback(
+void VKAPI vkDbgStringCallback(
     VkFlags                             msgFlags,
     VkObjectType                        objType,
     VkObject                            srcObject,
@@ -109,7 +117,7 @@
     const char*                         pMsg,
     void*                               pUserData);
 
-void VKAPI vkStdioCallback(
+void VKAPI vkDbgStdioCallback(
     VkFlags                             msgFlags,
     VkObjectType                        objType,
     VkObject                            srcObject,
@@ -119,7 +127,7 @@
     const char*                         pMsg,
     void*                               pUserData);
 
-void VKAPI vkBreakCallback(
+void VKAPI vkDbgBreakCallback(
     VkFlags                             msgFlags,
     VkObjectType                        objType,
     VkObject                            srcObject,
diff --git a/include/vk_debug_marker_lunarg.h b/include/vk_debug_marker_lunarg.h
new file mode 100644
index 0000000..2d3daa1
--- /dev/null
+++ b/include/vk_debug_marker_lunarg.h
@@ -0,0 +1,97 @@
+//
+// File: vk_debug_marker_lunarg.h
+//
+/*
+** Copyright (c) 2015 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+**
+** Authors:
+**   Jon Ashburn <jon@lunarg.com>
+**   Courtney Goeltzenleuchter <courtney@lunarg.com>
+*/
+
+#ifndef __VK_DEBUG_MARKER_H__
+#define __VK_DEBUG_MARKER_H__
+
+#include "vulkan.h"
+
+#define VK_DEBUG_MARKER_EXTENSION_NUMBER 3
+#define VK_DEBUG_MARKER_EXTENSION_VERSION 1
+#ifdef __cplusplus
+extern "C"
+{
+#endif // __cplusplus
+
+/*
+***************************************************************************************************
+*   DebugMarker Vulkan Extension API
+***************************************************************************************************
+*/
+
+#define DEBUG_MARKER_EXTENSION_NAME "DEBUG_MARKER"
+
+// ------------------------------------------------------------------------------------------------
+// Enumerations
+
+#define VK_DEBUG_MARKER_ENUM_EXTEND(type, id)    ((type)(VK_DEBUG_MARKER_EXTENSION_NUMBER * -1000 + (id)))
+
+#define VK_OBJECT_INFO_TYPE_DBG_OBJECT_TAG VK_DEBUG_MARKER_ENUM_EXTEND(VkObjectInfoType, 0)
+#define VK_OBJECT_INFO_TYPE_DBG_OBJECT_NAME VK_DEBUG_MARKER_ENUM_EXTEND(VkObjectInfoType, 1)
+
+// ------------------------------------------------------------------------------------------------
+// API functions
+
+typedef void (VKAPI *PFN_vkCmdDbgMarkerBegin)(VkCmdBuffer cmdBuffer, const char* pMarker);
+typedef void (VKAPI *PFN_vkCmdDbgMarkerEnd)(VkCmdBuffer cmdBuffer);
+typedef VkResult (VKAPI *PFN_vkDbgSetObjectTag)(VkDevice device, VkObjectType objType, VkObject object, size_t tagSize, const void* pTag);
+typedef VkResult (VKAPI *PFN_vkDbgSetObjectName)(VkDevice device, VkObjectType objType, VkObject object, size_t nameSize, const char* pName);
+
+#ifdef VK_PROTOTYPES
+
+// DebugMarker extension entrypoints
+void VKAPI vkCmdDbgMarkerBegin(
+    VkCmdBuffer                         cmdBuffer,
+    const char*                         pMarker);
+
+void VKAPI vkCmdDbgMarkerEnd(
+    VkCmdBuffer                         cmdBuffer);
+
+VkResult VKAPI vkDbgSetObjectTag(
+    VkDevice                            device,
+    VkObjectType                        objType,
+    VkObject                            object,
+    size_t                              tagSize,
+    const void*                         pTag);
+
+VkResult VKAPI vkDbgSetObjectName(
+    VkDevice                            device,
+    VkObjectType                        objType,
+    VkObject                            object,
+    size_t                              nameSize,
+    const char*                         pName);
+
+#endif // VK_PROTOTYPES
+
+#ifdef __cplusplus
+} // extern "C"
+#endif // __cplusplus
+
+#endif // __VK_DEBUG_MARKER_H__
diff --git a/include/vk_debug_report_lunarg.h b/include/vk_debug_report_lunarg.h
new file mode 100644
index 0000000..eb8f9f4
--- /dev/null
+++ b/include/vk_debug_report_lunarg.h
@@ -0,0 +1,141 @@
+//
+// File: vk_debug_report_lunarg.h
+//
+/*
+ * Vulkan
+ *
+ * Copyright (C) 2015 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *   Jon Ashburn <jon@lunarg.com>
+ *   Courtney Goeltzenleuchter <courtney@lunarg.com>
+ */
+
+#ifndef __VK_DEBUG_REPORT_LUNARG_H__
+#define __VK_DEBUG_REPORT_LUNARG_H__
+
+#include "vulkan.h"
+
+#define VK_DEBUG_REPORT_EXTENSION_NUMBER 2
+#define VK_DEBUG_REPORT_EXTENSION_VERSION 0x10
+#ifdef __cplusplus
+extern "C"
+{
+#endif // __cplusplus
+
+/*
+***************************************************************************************************
+*   DebugReport Vulkan Extension API
+***************************************************************************************************
+*/
+
+#define DEBUG_REPORT_EXTENSION_NAME "DEBUG_REPORT"
+
+VK_DEFINE_NONDISP_SUBCLASS_HANDLE(VkDbgMsgCallback, VkObject)
+
+// ------------------------------------------------------------------------------------------------
+// Enumerations
+
+typedef enum VkDbgReportFlags_
+{
+    VK_DBG_REPORT_INFO_BIT       = VK_BIT(0),
+    VK_DBG_REPORT_WARN_BIT       = VK_BIT(1),
+    VK_DBG_REPORT_PERF_WARN_BIT  = VK_BIT(2),
+    VK_DBG_REPORT_ERROR_BIT      = VK_BIT(3),
+} VkDbgReportFlags;
+
+#define VK_DEBUG_REPORT_ENUM_EXTEND(type, id)    ((type)(VK_DEBUG_REPORT_EXTENSION_NUMBER * -1000 + (id)))
+
+#define VK_OBJECT_TYPE_MSG_CALLBACK VK_DEBUG_REPORT_ENUM_EXTEND(VkObjectType, 0)
+// ------------------------------------------------------------------------------------------------
+// Vulkan function pointers
+
+typedef void (*PFN_vkDbgMsgCallback)(
+    VkFlags                             msgFlags,
+    VkObjectType                        objType,
+    VkObject                            srcObject,
+    size_t                              location,
+    int32_t                             msgCode,
+    const char*                         pLayerPrefix,
+    const char*                         pMsg,
+    void*                               pUserData);
+
+// ------------------------------------------------------------------------------------------------
+// API functions
+
+typedef VkResult (VKAPI *PFN_vkDbgCreateMsgCallback)(VkInstance instance, VkFlags msgFlags, const PFN_vkDbgMsgCallback pfnMsgCallback, const void* pUserData, VkDbgMsgCallback* pMsgCallback);
+typedef VkResult (VKAPI *PFN_vkDbgDestroyMsgCallback)(VkInstance instance, VkDbgMsgCallback msgCallback);
+typedef void (VKAPI *PFN_vkDbgStringCallback)(VkFlags msgFlags, VkObjectType objType, VkObject srcObject, size_t location, int32_t msgCode, const char* pLayerPrefix, const char* pMsg, void* pUserData);
+typedef void (VKAPI *PFN_vkDbgStdioCallback)(VkFlags msgFlags, VkObjectType objType, VkObject srcObject, size_t location, int32_t msgCode, const char* pLayerPrefix, const char* pMsg, void* pUserData);
+typedef void (VKAPI *PFN_vkDbgBreakCallback)(VkFlags msgFlags, VkObjectType objType, VkObject srcObject, size_t location, int32_t msgCode, const char* pLayerPrefix, const char* pMsg, void* pUserData);
+
+#ifdef VK_PROTOTYPES
+
+// DebugReport extension entrypoints
+VkResult VKAPI vkDbgCreateMsgCallback(
+    VkInstance                          instance,
+    VkFlags                             msgFlags,
+    const PFN_vkDbgMsgCallback          pfnMsgCallback,
+    void*                               pUserData,
+    VkDbgMsgCallback*                   pMsgCallback);
+
+VkResult VKAPI vkDbgDestroyMsgCallback(
+    VkInstance                          instance,
+    VkDbgMsgCallback                    msgCallback);
+
+// DebugReport utility callback functions
+void VKAPI vkDbgStringCallback(
+    VkFlags                             msgFlags,
+    VkObjectType                        objType,
+    VkObject                            srcObject,
+    size_t                              location,
+    int32_t                             msgCode,
+    const char*                         pLayerPrefix,
+    const char*                         pMsg,
+    void*                               pUserData);
+
+void VKAPI vkDbgStdioCallback(
+    VkFlags                             msgFlags,
+    VkObjectType                        objType,
+    VkObject                            srcObject,
+    size_t                              location,
+    int32_t                             msgCode,
+    const char*                         pLayerPrefix,
+    const char*                         pMsg,
+    void*                               pUserData);
+
+void VKAPI vkDbgBreakCallback(
+    VkFlags                             msgFlags,
+    VkObjectType                        objType,
+    VkObject                            srcObject,
+    size_t                              location,
+    int32_t                             msgCode,
+    const char*                         pLayerPrefix,
+    const char*                         pMsg,
+    void*                               pUserData);
+
+#endif // VK_PROTOTYPES
+
+#ifdef __cplusplus
+} // extern "C"
+#endif // __cplusplus
+
+#endif // __VK_DEBUG_REPORT_LUNARG_H__
diff --git a/include/vulkan.h b/include/vulkan.h
index 89431af..dbc6f86 100644
--- a/include/vulkan.h
+++ b/include/vulkan.h
@@ -835,18 +835,17 @@
     VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO                 = 38,
     VK_STRUCTURE_TYPE_CMD_BUFFER_GRAPHICS_BEGIN_INFO        = 39,
     VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO               = 40,
-    VK_STRUCTURE_TYPE_LAYER_CREATE_INFO                     = 41,
-    VK_STRUCTURE_TYPE_MEMORY_BARRIER                        = 42,
-    VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER                 = 43,
-    VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER                  = 44,
-    VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO           = 45,
+    VK_STRUCTURE_TYPE_MEMORY_BARRIER                        = 41,
+    VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER                 = 42,
+    VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER                  = 43,
+    VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO           = 44,
     VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET                  = 46,
     VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET                   = 47,
     VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO                  = 48,
     VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO           = 49,
-    VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE                   = 50,
+    VK_STRUCTURE_TYPE_EXTENSION_PROPERTIES                  = 50,
 
-    VK_ENUM_RANGE(STRUCTURE_TYPE, APPLICATION_INFO, MAPPED_MEMORY_RANGE)
+    VK_ENUM_RANGE(STRUCTURE_TYPE, APPLICATION_INFO, EXTENSION_PROPERTIES)
 } VkStructureType;
 
 // Object type enumerant
@@ -936,6 +935,7 @@
     VK_ERROR_MEMORY_NOT_BOUND                               = -(0x0000001F),
     VK_ERROR_INCOMPATIBLE_QUEUE                             = -(0x00000020),
     VK_ERROR_NOT_SHAREABLE                                  = -(0x00000021),
+    VK_ERROR_MISSING_EXTENSION_DEPENDENCY                   = -(0x00000022),
 
     VK_MAX_ENUM(RESULT)
 } VkResult;
@@ -1279,8 +1279,10 @@
 
 typedef struct VkExtensionProperties_
 {
-    char                                        extName[VK_MAX_EXTENSION_NAME];     // extension name
+    VkStructureType                             sType;                              // Type of structure. Should be VK_STRUCTURE_TYPE_EXTENSION_PROPERTIES
+    char                                        name[VK_MAX_EXTENSION_NAME];        // extension name
     uint32_t                                    version;                            // version of the extension specification
+    char                                        description[VK_MAX_EXTENSION_NAME]; // Name of library implementing this extension
 } VkExtensionProperties;
 
 typedef struct VkApplicationInfo_
@@ -1324,7 +1326,7 @@
     uint32_t                                    queueRecordCount;
     const VkDeviceQueueCreateInfo*              pRequestedQueues;
     uint32_t                                    extensionCount;
-    const char*const*                           ppEnabledExtensionNames;
+    const VkExtensionProperties*                pEnabledExtensions;         // Indicate extensions to enable by index value
     VkDeviceCreateFlags                         flags;                      // Device creation flags
 } VkDeviceCreateInfo;
 
@@ -1335,18 +1337,9 @@
     const VkApplicationInfo*                    pAppInfo;
     const VkAllocCallbacks*                     pAllocCb;
     uint32_t                                    extensionCount;
-    const char*const*                           ppEnabledExtensionNames;    // layer or extension name to be enabled
+    const VkExtensionProperties*                pEnabledExtensions;         // Indicate extensions to enable by index value
 } VkInstanceCreateInfo;
 
-// can be added to VkDeviceCreateInfo via pNext
-typedef struct VkLayerCreateInfo_
-{
-    VkStructureType                             sType;                      // Should be VK_STRUCTURE_TYPE_LAYER_CREATE_INFO
-    const void*                                 pNext;                      // Pointer to next structure
-    uint32_t                                    layerCount;
-    const char *const*                          ppActiveLayerNames;         // layer name from the layer's vkEnumerateLayers())
-} VkLayerCreateInfo;
-
 typedef struct VkPhysicalDeviceQueueProperties_
 {
     VkQueueFlags                                queueFlags;                 // Queue flags
@@ -2093,7 +2086,6 @@
 typedef VkResult (VKAPI *PFN_vkDestroyDevice)(VkDevice device);
 typedef VkResult (VKAPI *PFN_vkGetGlobalExtensionInfo)(VkExtensionInfoType infoType, uint32_t extensionIndex, size_t* pDataSize, void* pData);
 typedef VkResult (VKAPI *PFN_vkGetPhysicalDeviceExtensionInfo)(VkPhysicalDevice physicalDevice, VkExtensionInfoType infoType, uint32_t extensionIndex, size_t* pDataSize, void* pData);
-typedef VkResult (VKAPI *PFN_vkEnumerateLayers)(VkPhysicalDevice physicalDevice, size_t maxStringSize, size_t* pLayerCount, char* const* pOutLayers, void* pReserved);
 typedef VkResult (VKAPI *PFN_vkGetDeviceQueue)(VkDevice device, uint32_t queueNodeIndex, uint32_t queueIndex, VkQueue* pQueue);
 typedef VkResult (VKAPI *PFN_vkQueueSubmit)(VkQueue queue, uint32_t cmdBufferCount, const VkCmdBuffer* pCmdBuffers, VkFence fence);
 typedef VkResult (VKAPI *PFN_vkQueueWaitIdle)(VkQueue queue);
@@ -2252,15 +2244,6 @@
     size_t*                                     pDataSize,
     void*                                       pData);
 
-// Layer discovery functions
-
-VkResult VKAPI vkEnumerateLayers(
-    VkPhysicalDevice                            physicalDevice,
-    size_t                                      maxStringSize,
-    size_t*                                     pLayerCount,
-    char* const*                                pOutLayers,
-    void*                                       pReserved);
-
 // Queue functions
 
 VkResult VKAPI vkGetDeviceQueue(
diff --git a/layers/CMakeLists.txt b/layers/CMakeLists.txt
index c06b8b3..883d880 100644
--- a/layers/CMakeLists.txt
+++ b/layers/CMakeLists.txt
@@ -99,7 +99,6 @@
 add_vk_layer(Multi multi.cpp)
 add_vk_layer(DrawState draw_state.cpp)
 add_vk_layer(MemTracker mem_tracker.cpp)
-#add_vk_layer(GlaveSnapshot glave_snapshot.c)
 add_vk_layer(ShaderChecker shader_checker.cpp)
 # generated
 add_vk_layer(Generic generic_layer.cpp)
diff --git a/layers/basic.cpp b/layers/basic.cpp
index f5edf7c..0742cb2 100644
--- a/layers/basic.cpp
+++ b/layers/basic.cpp
@@ -91,15 +91,25 @@
     return VK_SUCCESS;
 }
 
-struct extProps {
-    uint32_t version;
-    const char * const name;
-};
 #define BASIC_LAYER_EXT_ARRAY_SIZE 2
-static const struct extProps basicExts[BASIC_LAYER_EXT_ARRAY_SIZE] = {
-    // TODO what is the version?
-    0x10, "Basic",
-    0x10, "vkLayerExtension1"
+
+static const VkExtensionProperties basicExts[BASIC_LAYER_EXT_ARRAY_SIZE] = {
+    {
+        VK_STRUCTURE_TYPE_EXTENSION_PROPERTIES,
+        "Basic",
+        0x10,
+        "Sample layer: Basic ",
+//        0,
+//        NULL,
+    },
+    {
+        VK_STRUCTURE_TYPE_EXTENSION_PROPERTIES,
+        "vkLayerExtension1",
+        0x10,
+        "Sample layer: Basic",
+//        0,
+//        NULL,
+    }
 };
 
 VK_LAYER_EXPORT VkResult VKAPI vkGetGlobalExtensionInfo(
@@ -109,7 +119,6 @@
                                                void*    pData)
 {
     /* This entrypoint is NOT going to init it's own dispatch table since loader calls here early */
-    VkExtensionProperties *ext_props;
     uint32_t *count;
 
     if (pDataSize == NULL)
@@ -129,11 +138,7 @@
                 return VK_SUCCESS;
             if (extensionIndex >= BASIC_LAYER_EXT_ARRAY_SIZE)
                 return VK_ERROR_INVALID_VALUE;
-            ext_props = (VkExtensionProperties *) pData;
-            ext_props->version = basicExts[extensionIndex].version;
-            strncpy(ext_props->extName, basicExts[extensionIndex].name,
-                                        VK_MAX_EXTENSION_NAME);
-            ext_props->extName[VK_MAX_EXTENSION_NAME - 1] = '\0';
+            memcpy((VkExtensionProperties *) pData, &basicExts[extensionIndex], sizeof(VkExtensionProperties));
             break;
         default:
             return VK_ERROR_INVALID_VALUE;
@@ -197,39 +202,6 @@
     return result;
 }
 
-VK_LAYER_EXPORT VkResult VKAPI vkEnumerateLayers(VkPhysicalDevice gpu, size_t maxStringSize, size_t* pLayerCount, char* const* pOutLayers, void* pReserved)
-{
-    if (gpu != NULL)
-    {
-        VkLayerInstanceDispatchTable* pTable = initLayerInstanceTable((const VkBaseLayerObject *) gpu);
-
-        printf("At start of wrapped vkEnumerateLayers() call w/ gpu: %p\n", gpu);
-        VkResult result = pTable->EnumerateLayers(gpu, maxStringSize, pLayerCount, pOutLayers, pReserved);
-        return result;
-    } else
-    {
-        if (pLayerCount == NULL || pOutLayers == NULL || pOutLayers[0] == NULL || pReserved == NULL)
-            return VK_ERROR_INVALID_POINTER;
-
-        // Example of a layer that is only compatible with Intel's GPUs
-        VkBaseLayerObject* gpuw = (VkBaseLayerObject*) pReserved;
-        PFN_vkGetPhysicalDeviceInfo fpGetGpuInfo;
-        VkPhysicalDeviceProperties gpuProps;
-        size_t dataSize = sizeof(VkPhysicalDeviceProperties);
-        fpGetGpuInfo = (PFN_vkGetPhysicalDeviceInfo) gpuw->pGPA((VkPhysicalDevice) gpuw->nextObject, "vkGetPhysicalDeviceInfo");
-        fpGetGpuInfo((VkPhysicalDevice) gpuw->nextObject, VK_PHYSICAL_DEVICE_INFO_TYPE_PROPERTIES, &dataSize, &gpuProps);
-        if (gpuProps.vendorId == 0x8086)
-        {
-            *pLayerCount = 1;
-            strncpy((char *) pOutLayers[0], "Basic", maxStringSize);
-        } else
-        {
-            *pLayerCount = 0;
-        }
-        return VK_SUCCESS;
-    }
-}
-
 VK_LAYER_EXPORT void * VKAPI vkGetDeviceProcAddr(VkDevice device, const char* pName)
 {
     if (device == NULL)
@@ -270,8 +242,6 @@
         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)
diff --git a/layers/debug_support.cpp b/layers/debug_support.cpp
deleted file mode 100644
index 5c36c80..0000000
--- a/layers/debug_support.cpp
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * Vulkan
- *
- * Copyright (C) 2014 LunarG, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-#include <string.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <unordered_map>
-#include "loader_platform.h"
-#include "vk_dispatch_table_helper.h"
-#include "vkLayer.h"
-// The following is #included again to catch certain OS-specific functions
-// being used:
-#include "loader_platform.h"
-
-static std::unordered_map<void *, VkLayerDispatchTable *> tableMap;
-
-static VkLayerDispatchTable * initLayerTable(const VkBaseLayerObject *gpuw)
-{
-    VkLayerDispatchTable *pTable;
-
-    assert(gpuw);
-    std::unordered_map<void *, VkLayerDispatchTable *>::const_iterator it = tableMap.find((void *) gpuw->baseObject);
-    if (it == tableMap.end())
-    {
-        pTable =  new VkLayerDispatchTable;
-        tableMap[(void *) gpuw->baseObject] = pTable;
-    } else
-    {
-        return it->second;
-    }
-
-    layer_initialize_dispatch_table(pTable, gpuw->pGPA, (VkPhysicalDevice) gpuw->nextObject);
-
-    return pTable;
-}
-
-VK_LAYER_EXPORT VkResult VKAPI vkLayerExtension1(VkDevice device)
-{
-    printf("In vkLayerExtension1() call w/ device: %p\n", (void*)device);
-    printf("vkLayerExtension1 returning SUCCESS\n");
-    return VK_SUCCESS;
-}
-
-struct extProps {
-    uint32_t version;
-    const char * const name;
-};
-#define DEBUG_SUPPORT_LAYER_EXT_ARRAY_SIZE 2
-static const struct extProps debugReportExts[DEBUG_SUPPORT_LAYER_EXT_ARRAY_SIZE] = {
-    0x10, "DebugReport",
-    0x10, "DebugMarker",
-};
-
-VK_LAYER_EXPORT VkResult VKAPI vkGetGlobalExtensionInfo(
-                                               VkExtensionInfoType infoType,
-                                               uint32_t extensionIndex,
-                                               size_t*  pDataSize,
-                                               void*    pData)
-{
-    /* This entrypoint is NOT going to init it's own dispatch table since loader calls here early */
-    VkExtensionProperties *ext_props;
-    uint32_t *count;
-
-    if (pDataSize == NULL)
-        return VK_ERROR_INVALID_POINTER;
-
-    switch (infoType) {
-        case VK_EXTENSION_INFO_TYPE_COUNT:
-            *pDataSize = sizeof(uint32_t);
-            if (pData == NULL)
-                return VK_SUCCESS;
-            count = (uint32_t *) pData;
-            *count = DEBUG_SUPPORT_LAYER_EXT_ARRAY_SIZE;
-            break;
-        case VK_EXTENSION_INFO_TYPE_PROPERTIES:
-            *pDataSize = sizeof(VkExtensionProperties);
-            if (pData == NULL)
-                return VK_SUCCESS;
-            if (extensionIndex >= DEBUG_SUPPORT_LAYER_EXT_ARRAY_SIZE)
-                return VK_ERROR_INVALID_VALUE;
-            ext_props = (VkExtensionProperties *) pData;
-            ext_props->version = debugReportExts[extensionIndex].version;
-            strncpy(ext_props->extName, debugReportExts[extensionIndex].name,
-                                        VK_MAX_EXTENSION_NAME);
-            ext_props->extName[VK_MAX_EXTENSION_NAME - 1] = '\0';
-            break;
-        default:
-            return VK_ERROR_INVALID_VALUE;
-    };
-
-    return VK_SUCCESS;
-}
-
-static VkResult VKAPI DbgCreateMsgCallback(
-    VkInstance                          instance,
-    VkFlags                             msgFlags,
-    const PFN_vkDbgMsgCallback          pfnMsgCallback,
-    const void*                         pUserData,
-    const VkDbgMsgCallback*             pMsgCallback)
-{
-
-}
-
-// DebugReport utility callback functions
-static void VKAPI StringCallback(
-    VkFlags                             msgFlags,
-    VkObjectType                        objType,
-    VkObject                            srcObject,
-    size_t                              location,
-    int32_t                             msgCode,
-    const char*                         pLayerPrefix,
-    const char*                         pMsg,
-    void*                               pUserData)
-{
-
-}
-
-static void VKAPI StdioCallback(
-    VkFlags                             msgFlags,
-    VkObjectType                        objType,
-    VkObject                            srcObject,
-    size_t                              location,
-    int32_t                             msgCode,
-    const char*                         pLayerPrefix,
-    const char*                         pMsg,
-    void*                               pUserData)
-{
-
-}
-
-static void VKAPI BreakCallback(
-    VkFlags                             msgFlags,
-    VkObjectType                        objType,
-    VkObject                            srcObject,
-    size_t                              location,
-    int32_t                             msgCode,
-    const char*                         pLayerPrefix,
-    const char*                         pMsg,
-    void*                               pUserData)
-{
-
-}
-
-// DebugMarker extension entrypoints
-static void VKAPI CmdDbgMarkerBegin(
-    VkCmdBuffer                         cmdBuffer,
-    const char*                         pMarker)
-{
-
-}
-
-static void VKAPI CmdDbgMarkerEnd(
-    VkCmdBuffer                         cmdBuffer)
-{
-
-}
-
-static VkResult VKAPI DbgSetObjectTag(
-    VkDevice                            device,
-    VkObjectType                        objType,
-    VkObject                            object,
-    size_t                              tagSize,
-    const void*                         pTag)
-{
-
-}
-
-static VkResult VKAPI DbgSetObjectName(
-    VkDevice                            device,
-    VkObjectType                        objType,
-    VkObject                            object,
-    size_t                              nameSize,
-    const char*                         pName)
-{
-
-}
-
-VK_LAYER_EXPORT void * VKAPI vkGetProcAddr(VkPhysicalDevice gpu, const char* pName)
-{
-    if (gpu == NULL)
-        return NULL;
-
-    initLayerTable((const VkBaseLayerObject *) gpu);
-
-    if (!strncmp("vkGetProcAddr", pName, sizeof("vkGetProcAddr")))
-        return (void *) vkGetProcAddr;
-    else if (!strcmp("vkDbgCreateMsgCallback", pName))
-        return (void *) DbgCreateMsgCallback;
-    else if (!strcmp("vkStringCallback", pName))
-        return (void *) StringCallback;
-    else if (!strcmp("vkStdioCallback", pName))
-        return (void *) StdioCallback;
-    else if (!strcmp("vkBreakCallback", pName))
-        return (void *) BreakCallback;
-    else if (!strcmp("vkCmdDbgMarkerBegin", pName))
-        return (void *) CmdDbgMarkerBegin;
-    else if (!strcmp("vkCmdDbgMarkerEnd", pName))
-        return (void *) CmdDbgMarkerEnd;
-    else if (!strcmp("vkDbgSetObjectTag", pName))
-        return (void *) DbgSetObjectTag;
-    else if (!strcmp("vkDbgSetObjectName", pName))
-        return (void *) DbgSetObjectName;
-    else {
-        VkBaseLayerObject* gpuw = (VkBaseLayerObject *) gpu;
-        if (gpuw->pGPA == NULL)
-            return NULL;
-        return gpuw->pGPA((VkPhysicalDevice) gpuw->nextObject, pName);
-    }
-}
diff --git a/layers/draw_state.cpp b/layers/draw_state.cpp
index fc7afa5..61f8804 100644
--- a/layers/draw_state.cpp
+++ b/layers/draw_state.cpp
@@ -315,7 +315,8 @@
     loader_platform_thread_unlock_mutex(&globalLock);
 }
 // Check object status for selected flag state
-static bool32_t validate_status(VkCmdBuffer cb, CBStatusFlags enable_mask, CBStatusFlags status_mask, CBStatusFlags status_flag, VK_DBG_MSG_TYPE error_level, DRAW_STATE_ERROR error_code, const char* fail_msg) {
+static bool32_t validate_status(VkCmdBuffer cb, CBStatusFlags enable_mask, CBStatusFlags status_mask, CBStatusFlags status_flag, VkFlags msg_flags, DRAW_STATE_ERROR error_code, const char* fail_msg)
+{
     if (cmdBufferMap.find(cb) != cmdBufferMap.end()) {
         GLOBAL_CB_NODE* pNode = cmdBufferMap[cb];
         // If non-zero enable mask is present, check it against status but if enable_mask
@@ -323,8 +324,8 @@
         if ((!enable_mask) || (enable_mask & pNode->status)) {
             if ((pNode->status & status_mask) != status_flag) {
                 char str[1024];
-                sprintf(str, "CB object 0x%" PRIxLEAST64 ": %s", reinterpret_cast<VkUintPtrLeast64>(cb), fail_msg);
-                layerCbMsg(error_level, VK_VALIDATION_LEVEL_0, cb, 0, error_code, "DS", str);
+                sprintf(str, "CB object 0x%" PRIxLEAST64 ": %s", reinterpret_cast<VkUintPtrLeast64>(cb), str);
+                layerCbMsg(msg_flags, VK_OBJECT_TYPE_COMMAND_BUFFER, cb, 0, error_code, "DS", str);
                 return VK_FALSE;
             }
         }
@@ -334,16 +335,16 @@
         // If we do not find it print an error
         char str[1024];
         sprintf(str, "Unable to obtain status for non-existent CB object 0x%" PRIxLEAST64, reinterpret_cast<VkUintPtrLeast64>(cb));
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cb, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
+        layerCbMsg(msg_flags, (VkObjectType) 0, cb, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
         return VK_FALSE;
     }
 }
 static bool32_t validate_draw_state_flags(VkCmdBuffer cb) {
     bool32_t result1, result2, result3, result4;
-    result1 = validate_status(cb, CBSTATUS_NONE, CBSTATUS_VIEWPORT_BOUND, CBSTATUS_VIEWPORT_BOUND, VK_DBG_MSG_ERROR, DRAWSTATE_VIEWPORT_NOT_BOUND, "Viewport object not bound to this command buffer");
-    result2 = validate_status(cb, CBSTATUS_NONE, CBSTATUS_RASTER_BOUND,   CBSTATUS_RASTER_BOUND,   VK_DBG_MSG_ERROR, DRAWSTATE_RASTER_NOT_BOUND,   "Raster object not bound to this command buffer");
-    result3 = validate_status(cb, CBSTATUS_COLOR_BLEND_WRITE_ENABLE, CBSTATUS_COLOR_BLEND_BOUND,   CBSTATUS_COLOR_BLEND_BOUND,   VK_DBG_MSG_ERROR,  DRAWSTATE_COLOR_BLEND_NOT_BOUND,   "Color-blend object not bound to this command buffer");
-    result4 = validate_status(cb, CBSTATUS_DEPTH_STENCIL_WRITE_ENABLE, CBSTATUS_DEPTH_STENCIL_BOUND, CBSTATUS_DEPTH_STENCIL_BOUND, VK_DBG_MSG_ERROR,  DRAWSTATE_DEPTH_STENCIL_NOT_BOUND, "Depth-stencil object not bound to this command buffer");
+    result1 = validate_status(cb, CBSTATUS_NONE, CBSTATUS_VIEWPORT_BOUND, CBSTATUS_VIEWPORT_BOUND, VK_DBG_REPORT_ERROR_BIT, DRAWSTATE_VIEWPORT_NOT_BOUND, "Viewport object not bound to this command buffer");
+    result2 = validate_status(cb, CBSTATUS_NONE, CBSTATUS_RASTER_BOUND,   CBSTATUS_RASTER_BOUND,   VK_DBG_REPORT_ERROR_BIT, DRAWSTATE_RASTER_NOT_BOUND,   "Raster object not bound to this command buffer");
+    result3 = validate_status(cb, CBSTATUS_COLOR_BLEND_WRITE_ENABLE, CBSTATUS_COLOR_BLEND_BOUND,   CBSTATUS_COLOR_BLEND_BOUND,   VK_DBG_REPORT_ERROR_BIT,  DRAWSTATE_COLOR_BLEND_NOT_BOUND,   "Color-blend object not bound to this command buffer");
+    result4 = validate_status(cb, CBSTATUS_DEPTH_STENCIL_WRITE_ENABLE, CBSTATUS_DEPTH_STENCIL_BOUND, CBSTATUS_DEPTH_STENCIL_BOUND, VK_DBG_REPORT_ERROR_BIT,  DRAWSTATE_DEPTH_STENCIL_NOT_BOUND, "Depth-stencil object not bound to this command buffer");
     return ((result1 == VK_TRUE) && (result2 == VK_TRUE) && (result3 == VK_TRUE) && (result4 == VK_TRUE));
 }
 // Print the last bound dynamic state
@@ -356,13 +357,12 @@
         for (uint32_t i = 0; i < VK_NUM_STATE_BIND_POINT; i++) {
             if (pCB->lastBoundDynamicState[i]) {
                 sprintf(str, "Reporting CreateInfo for currently bound %s object %p", string_VkStateBindPoint((VkStateBindPoint)i), pCB->lastBoundDynamicState[i]->stateObj);
-                layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, pCB->lastBoundDynamicState[i]->stateObj, 0, DRAWSTATE_NONE, "DS", str);
-                layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, pCB->lastBoundDynamicState[i]->stateObj, 0, DRAWSTATE_NONE, "DS", dynamic_display(pCB->lastBoundDynamicState[i]->pCreateInfo, "  ").c_str());
+                layerCbMsg(VK_DBG_REPORT_INFO_BIT, pCB->lastBoundDynamicState[i]->objType, pCB->lastBoundDynamicState[i]->stateObj, 0, DRAWSTATE_NONE, "DS", str);
+                layerCbMsg(VK_DBG_REPORT_INFO_BIT, pCB->lastBoundDynamicState[i]->objType, pCB->lastBoundDynamicState[i]->stateObj, 0, DRAWSTATE_NONE, "DS", dynamic_display(pCB->lastBoundDynamicState[i]->pCreateInfo, "  ").c_str());
                 break;
-            }
-            else {
+            } else {
                 sprintf(str, "No dynamic state of type %s bound", string_VkStateBindPoint((VkStateBindPoint)i));
-                layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", str);
+                layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, DRAWSTATE_NONE, "DS", str);
             }
         }
         loader_platform_thread_unlock_mutex(&globalLock);
@@ -370,7 +370,7 @@
     else {
         char str[1024];
         sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cb);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cb, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cb, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
     }
 }
 // Retrieve pipeline node ptr for given pipeline object
@@ -558,7 +558,7 @@
             if ((psoNumSamples != pFBCI->sampleCount) || (psoNumSamples != pRPCI->sampleCount)) {
                 char str[1024];
                 sprintf(str, "Num samples mismatch! Binding PSO (%p) with %u samples while current RenderPass (%p) w/ %u samples uses FB (%p) with %u samples!", (void*)pipeline, psoNumSamples, (void*)pCB->activeRenderPass, pRPCI->sampleCount, (void*)pCB->framebuffer, pFBCI->sampleCount);
-                layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, pipeline, 0, DRAWSTATE_NUM_SAMPLES_MISMATCH, "DS", str);
+                layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_PIPELINE, pipeline, 0, DRAWSTATE_NUM_SAMPLES_MISMATCH, "DS", str);
             }
         } else {
             // TODO : I believe it's an error if we reach this point and don't have an activeRenderPass
@@ -615,7 +615,7 @@
             return 1;
         default:
             sprintf(str, "Unexpected UPDATE struct of type %s (value %u) in vkUpdateDescriptors() struct tree", string_VkStructureType(pUpdateStruct->sType), pUpdateStruct->sType);
-            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_INVALID_UPDATE_STRUCT, "DS", str);
+            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, VK_NULL_HANDLE, 0, DRAWSTATE_INVALID_UPDATE_STRUCT, "DS", str);
             return 0;
     }
 }
@@ -631,7 +631,7 @@
             return ((VkCopyDescriptorSet*)pUpdateStruct)->destBinding;
         default:
             sprintf(str, "Unexpected UPDATE struct of type %s (value %u) in vkUpdateDescriptors() struct tree", string_VkStructureType(pUpdateStruct->sType), pUpdateStruct->sType);
-            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_INVALID_UPDATE_STRUCT, "DS", str);
+            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, VK_NULL_HANDLE, 0, DRAWSTATE_INVALID_UPDATE_STRUCT, "DS", str);
             return 0xFFFFFFFF;
     }
 }
@@ -648,7 +648,7 @@
             return ((VkCopyDescriptorSet*)pUpdateStruct)->destArrayElement;
         default:
             sprintf(str, "Unexpected UPDATE struct of type %s (value %u) in vkUpdateDescriptors() struct tree", string_VkStructureType(pUpdateStruct->sType), pUpdateStruct->sType);
-            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_INVALID_UPDATE_STRUCT, "DS", str);
+            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, VK_NULL_HANDLE, 0, DRAWSTATE_INVALID_UPDATE_STRUCT, "DS", str);
             return 0;
     }
 }
@@ -665,7 +665,7 @@
             return ((VkCopyDescriptorSet*)pUpdateStruct)->count;
         default:
             sprintf(str, "Unexpected UPDATE struct of type %s (value %u) in vkUpdateDescriptors() struct tree", string_VkStructureType(pUpdateStruct->sType), pUpdateStruct->sType);
-            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_INVALID_UPDATE_STRUCT, "DS", str);
+            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, VK_NULL_HANDLE, 0, DRAWSTATE_INVALID_UPDATE_STRUCT, "DS", str);
             return 0;
     }
 }
@@ -715,7 +715,7 @@
             break;
         default:
             sprintf(str, "Unexpected UPDATE struct of type %s (value %u) in vkUpdateDescriptors() struct tree", string_VkStructureType(pUpdateStruct->sType), pUpdateStruct->sType);
-            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_INVALID_UPDATE_STRUCT, "DS", str);
+            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, VK_NULL_HANDLE, 0, DRAWSTATE_INVALID_UPDATE_STRUCT, "DS", str);
             return 0;
     }
     for (i = getUpdateStartIndex(pLayout, pUpdateStruct); i <= getUpdateEndIndex(pLayout, pUpdateStruct); i++) {
@@ -754,7 +754,7 @@
             break;
         default:
             sprintf(str, "Unexpected UPDATE struct of type %s (value %u) in vkUpdateDescriptors() struct tree", string_VkStructureType(pUpdate->sType), pUpdate->sType);
-            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_INVALID_UPDATE_STRUCT, "DS", str);
+            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, DRAWSTATE_INVALID_UPDATE_STRUCT, "DS", str);
             return NULL;
     }
     // Make sure that pNext for the end of shadow copy is NULL
@@ -793,7 +793,7 @@
         if (pLayout->createInfo.count < getUpdateBinding(pUpdate)) {
             char str[1024];
             sprintf(str, "Descriptor Set %p does not have binding to match update binding %u for update type %s!", ds, getUpdateBinding(pUpdate), string_VkStructureType(pUpdate->sType));
-            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, ds, 0, DRAWSTATE_INVALID_UPDATE_INDEX, "DS", str);
+            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DESCRIPTOR_SET, ds, 0, DRAWSTATE_INVALID_UPDATE_INDEX, "DS", str);
             result = 0;
         }
         else {
@@ -803,7 +803,7 @@
                 pLayoutCI = &pLayout->createInfo;
                 string DSstr = vk_print_vkdescriptorsetlayoutcreateinfo(pLayoutCI, "{DS}    ");
                 sprintf(str, "Descriptor update type of %s is out of bounds for matching binding %u in Layout w/ CI:\n%s!", string_VkStructureType(pUpdate->sType), getUpdateBinding(pUpdate), DSstr.c_str());
-                layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, ds, 0, DRAWSTATE_DESCRIPTOR_UPDATE_OUT_OF_BOUNDS, "DS", str);
+                layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DESCRIPTOR_SET, ds, 0, DRAWSTATE_DESCRIPTOR_UPDATE_OUT_OF_BOUNDS, "DS", str);
                 result = 0;
             }
             else { // TODO : should we skip update on a type mismatch or force it?
@@ -811,7 +811,7 @@
                 if (!validateUpdateType(pLayout, pUpdate)) {
                     char str[1024];
                     sprintf(str, "Descriptor update type of %s does not match overlapping binding type!", string_VkStructureType(pUpdate->sType));
-                    layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, ds, 0, DRAWSTATE_DESCRIPTOR_TYPE_MISMATCH, "DS", str);
+                    layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DESCRIPTOR_SET, ds, 0, DRAWSTATE_DESCRIPTOR_TYPE_MISMATCH, "DS", str);
                     result = 0;
                 }
                 else {
@@ -822,7 +822,7 @@
                     if (NULL == pNewNode) {
                         char str[1024];
                         sprintf(str, "Out of memory while attempting to allocate UPDATE struct in vkUpdateDescriptors()");
-                        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, ds, 0, DRAWSTATE_OUT_OF_MEMORY, "DS", str);
+                        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DESCRIPTOR_SET, ds, 0, DRAWSTATE_OUT_OF_MEMORY, "DS", str);
                         result = 0;
                     }
                     else {
@@ -942,7 +942,7 @@
     if (!pPool) {
         char str[1024];
         sprintf(str, "Unable to find pool node for pool %p specified in vkResetDescriptorPool() call", (void*)pool);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, pool, 0, DRAWSTATE_INVALID_POOL, "DS", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DESCRIPTOR_POOL, pool, 0, DRAWSTATE_INVALID_POOL, "DS", str);
     }
     else
     {
@@ -993,7 +993,7 @@
     else {
         char str[1024];
         sprintf(str, "Out of memory while attempting to allocate new CMD_NODE for cmdBuffer %p", (void*)pCB->cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, pCB->cmdBuffer, 0, DRAWSTATE_OUT_OF_MEMORY, "DS", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, pCB->cmdBuffer, 0, DRAWSTATE_OUT_OF_MEMORY, "DS", str);
     }
 }
 static void resetCB(const VkCmdBuffer cb)
@@ -1052,7 +1052,7 @@
         if (dynamicStateMap.find(state) == dynamicStateMap.end()) {
             char str[1024];
             sprintf(str, "Unable to find dynamic state object %p, was it ever created?", (void*)state);
-            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, state, 0, DRAWSTATE_INVALID_DYNAMIC_STATE_OBJECT, "DS", str);
+            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, state, 0, DRAWSTATE_INVALID_DYNAMIC_STATE_OBJECT, "DS", str);
         }
         else {
             pCB->lastBoundDynamicState[sType] = dynamicStateMap[state];
@@ -1063,7 +1063,7 @@
     else {
         char str[1024];
         sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
     }
 }
 // Print the last bound Gfx Pipeline
@@ -1077,7 +1077,7 @@
         }
         else {
             string pipeStr = vk_print_vkgraphicspipelinecreateinfo(&pPipeTrav->graphicsPipelineCI, "{DS}").c_str();
-            layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", pipeStr.c_str());
+            layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, DRAWSTATE_NONE, "DS", pipeStr.c_str());
         }
     }
 }
@@ -1320,7 +1320,7 @@
         char str[1024];
         if (!pPipeTrav) {
             sprintf(str, "Can't find last bound Pipeline %p!", (void*)pCB->lastBoundPipeline);
-            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NO_PIPELINE_BOUND, "DS", str);
+            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, DRAWSTATE_NO_PIPELINE_BOUND, "DS", str);
             return false;
         }
         else {
@@ -1329,18 +1329,18 @@
                 if (pCB->lastVtxBinding >= pPipeTrav->vtxBindingCount) {
                     if (0 == pPipeTrav->vtxBindingCount) {
                         sprintf(str, "Vtx Buffer Index %u was bound, but no vtx buffers are attached to PSO.", pCB->lastVtxBinding);
-                        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_VTX_INDEX_OUT_OF_BOUNDS, "DS", str);
+                        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, DRAWSTATE_VTX_INDEX_OUT_OF_BOUNDS, "DS", str);
                         return false;
                     }
                     else {
                         sprintf(str, "Vtx binding Index of %u exceeds PSO pVertexBindingDescriptions max array index of %u.", pCB->lastVtxBinding, (pPipeTrav->vtxBindingCount - 1));
-                        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_VTX_INDEX_OUT_OF_BOUNDS, "DS", str);
+                        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, DRAWSTATE_VTX_INDEX_OUT_OF_BOUNDS, "DS", str);
                         return false;
                     }
                 }
                 else {
                     string tmpStr = vk_print_vkvertexinputbindingdescription(&pPipeTrav->pVertexBindingDescriptions[pCB->lastVtxBinding], "{DS}INFO : ").c_str();
-                    layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", tmpStr.c_str());
+                    layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, DRAWSTATE_NONE, "DS", tmpStr.c_str());
                 }
             }
         }
@@ -1359,41 +1359,41 @@
         POOL_NODE* pPool = getPoolNode(pSet->pool);
         // Print out pool details
         sprintf(tmp_str, "Details for pool %p.", (void*)pPool->pool);
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", tmp_str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, DRAWSTATE_NONE, "DS", tmp_str);
         string poolStr = vk_print_vkdescriptorpoolcreateinfo(&pPool->createInfo, " ");
         sprintf(ds_config_str, "%s", poolStr.c_str());
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", ds_config_str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, DRAWSTATE_NONE, "DS", ds_config_str);
         // Print out set details
         char prefix[10];
         uint32_t index = 0;
         sprintf(tmp_str, "Details for descriptor set %p.", (void*)pSet->set);
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", tmp_str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, DRAWSTATE_NONE, "DS", tmp_str);
         LAYOUT_NODE* pLayout = pSet->pLayout;
         // Print layout details
         sprintf(tmp_str, "Layout #%u, (object %p) for DS %p.", index+1, (void*)pLayout->layout, (void*)pSet->set);
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", tmp_str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, DRAWSTATE_NONE, "DS", tmp_str);
         sprintf(prefix, "  [L%u] ", index);
         string DSLstr = vk_print_vkdescriptorsetlayoutcreateinfo(&pLayout->createInfo, prefix).c_str();
         sprintf(ds_config_str, "%s", DSLstr.c_str());
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", ds_config_str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, DRAWSTATE_NONE, "DS", ds_config_str);
         index++;
         GENERIC_HEADER* pUpdate = pSet->pUpdateStructs;
         if (pUpdate) {
             sprintf(tmp_str, "Update Chain [UC] for descriptor set %p:", (void*)pSet->set);
-            layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", tmp_str);
+            layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, DRAWSTATE_NONE, "DS", tmp_str);
             sprintf(prefix, "  [UC] ");
             sprintf(ds_config_str, "%s", dynamic_display(pUpdate, prefix).c_str());
-            layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", ds_config_str);
+            layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, DRAWSTATE_NONE, "DS", ds_config_str);
             // TODO : If there is a "view" associated with this update, print CI for that view
         }
         else {
             if (0 != pSet->descriptorCount) {
                 sprintf(tmp_str, "No Update Chain for descriptor set %p which has %u descriptors (vkUpdateDescriptors has not been called)", (void*)pSet->set, pSet->descriptorCount);
-                layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", tmp_str);
+                layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, DRAWSTATE_NONE, "DS", tmp_str);
             }
             else {
                 sprintf(tmp_str, "FYI: No descriptors in descriptor set %p.", (void*)pSet->set);
-                layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", tmp_str);
+                layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, DRAWSTATE_NONE, "DS", tmp_str);
             }
         }
     }
@@ -1405,11 +1405,11 @@
     if (pCB && pCB->pCmds.size() > 0) {
         char str[1024];
         sprintf(str, "Cmds in CB %p", (void*)cb);
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, DRAWSTATE_NONE, "DS", str);
         vector<CMD_NODE*> pCmds = pCB->pCmds;
         for (vector<CMD_NODE*>::iterator ii=pCmds.begin(); ii!=pCmds.end(); ++ii) {
             sprintf(str, "  CMD#%lu: %s", (*ii)->cmdNumber, cmdTypeToString((*ii)->type).c_str());
-            layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, cb, 0, DRAWSTATE_NONE, "DS", str);
+            layerCbMsg(VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cb, 0, DRAWSTATE_NONE, "DS", str);
         }
     }
     else {
@@ -1487,7 +1487,7 @@
 {
     const char *strOpt;
     // initialize DrawState options
-    getLayerOptionEnum("DrawStateReportLevel", (uint32_t *) &g_reportingLevel);
+    getLayerOptionEnum("DrawStateReportLevel", (uint32_t *) &g_reportFlags);
     g_actionIsDefault = getLayerOptionEnum("DrawStateDebugAction", (uint32_t *) &g_debugAction);
 
     if (g_debugAction & VK_DBG_LAYER_ACTION_LOG_MSG)
@@ -1516,7 +1516,7 @@
 /* hook DestroyInstance to remove tableInstanceMap entry */
 VK_LAYER_EXPORT VkResult VKAPI vkDestroyInstance(VkInstance instance)
 {
-   VkLayerInstanceDispatchTable *pDisp = *(VkLayerInstanceDispatchTable **) instance;
+    VkLayerInstanceDispatchTable *pDisp = *(VkLayerInstanceDispatchTable **) instance;
     VkLayerInstanceDispatchTable *pTable = tableInstanceMap[pDisp];
     VkResult res = pTable->DestroyInstance(instance);
     tableInstanceMap.erase(pDisp);
@@ -1556,24 +1556,25 @@
     uint32_t version;
     const char * const name;
 };
-#define DRAW_STATE_LAYER_EXT_ARRAY_SIZE 5
-static const struct extProps dsExts[DRAW_STATE_LAYER_EXT_ARRAY_SIZE] = {
-    // TODO what is the version?
-    0x10, "DrawState",
-    0x10, "Validation",
-    0x10, "drawStateDumpDotFile",
-    0x10, "drawStateDumpCommandBufferDotFile",
-    0x10, "drawStateDumpPngFile"
+#define DRAW_STATE_LAYER_EXT_ARRAY_SIZE 1
+static const VkExtensionProperties dsExts[DRAW_STATE_LAYER_EXT_ARRAY_SIZE] = {
+    {
+        VK_STRUCTURE_TYPE_EXTENSION_PROPERTIES,
+        "DrawState",
+        0x10,
+        "Sample layer: DrawState",
+//        0,
+//        NULL,
+    }
 };
 
 VK_LAYER_EXPORT VkResult VKAPI vkGetGlobalExtensionInfo(
-                                               VkExtensionInfoType infoType,
-                                               uint32_t extensionIndex,
-                                               size_t*  pDataSize,
-                                               void*    pData)
+        VkExtensionInfoType infoType,
+        uint32_t extensionIndex,
+        size_t*  pDataSize,
+        void*    pData)
 {
     /* This entrypoint is NOT going to init it's own dispatch table since loader calls here early */
-    VkExtensionProperties *ext_props;
     uint32_t *count;
 
     if (pDataSize == NULL)
@@ -1593,11 +1594,7 @@
                 return VK_SUCCESS;
             if (extensionIndex >= DRAW_STATE_LAYER_EXT_ARRAY_SIZE)
                 return VK_ERROR_INVALID_VALUE;
-            ext_props = (VkExtensionProperties *) pData;
-            ext_props->version = dsExts[extensionIndex].version;
-            strncpy(ext_props->extName, dsExts[extensionIndex].name,
-                                        VK_MAX_EXTENSION_NAME);
-            ext_props->extName[VK_MAX_EXTENSION_NAME - 1] = '\0';
+            memcpy((VkExtensionProperties *) pData, &dsExts[extensionIndex], sizeof(VkExtensionProperties));
             break;
         default:
             return VK_ERROR_INVALID_VALUE;
@@ -1606,24 +1603,6 @@
     return VK_SUCCESS;
 }
 
-VK_LAYER_EXPORT VkResult VKAPI vkEnumerateLayers(VkPhysicalDevice gpu, size_t maxStringSize, size_t* pLayerCount, char* const* pOutLayers, void* pReserved)
-{
-    if (gpu != NULL)
-    {
-        VkLayerInstanceDispatchTable* pTable = initInstanceTable((const VkBaseLayerObject *) gpu);
-
-        VkResult result = pTable->EnumerateLayers(gpu, maxStringSize, pLayerCount, pOutLayers, pReserved);
-        return result;
-    } else {
-        if (pLayerCount == NULL || pOutLayers == NULL || pOutLayers[0] == NULL)
-            return VK_ERROR_INVALID_POINTER;
-        // This layer compatible with all GPUs
-        *pLayerCount = 1;
-        strncpy((char *) pOutLayers[0], "DrawState", maxStringSize);
-        return VK_SUCCESS;
-    }
-}
-
 VK_LAYER_EXPORT VkResult VKAPI vkQueueSubmit(VkQueue queue, uint32_t cmdBufferCount, const VkCmdBuffer* pCmdBuffers, VkFence fence)
 {
     GLOBAL_CB_NODE* pCB = NULL;
@@ -1635,7 +1614,7 @@
             // Flag error for using CB w/o vkEndCommandBuffer() called
             char str[1024];
             sprintf(str, "You must call vkEndCommandBuffer() on CB %p before this call to vkQueueSubmit()!", pCB->cmdBuffer);
-            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, pCB->cmdBuffer, 0, DRAWSTATE_NO_END_CMD_BUFFER, "DS", str);
+            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, pCB->cmdBuffer, 0, DRAWSTATE_NO_END_CMD_BUFFER, "DS", str);
             loader_platform_thread_unlock_mutex(&globalLock);
             return VK_ERROR_UNKNOWN;
         }
@@ -1708,7 +1687,7 @@
     // Create LL HEAD for this Pipeline
     char str[1024];
     sprintf(str, "Created Gfx Pipeline %p", (void*)*pPipeline);
-    layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, *pPipeline, 0, DRAWSTATE_NONE, "DS", str);
+    layerCbMsg(VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_PIPELINE, *pPipeline, 0, DRAWSTATE_NONE, "DS", str);
 
     track_pipeline(pCreateInfo, pPipeline);
 
@@ -1727,7 +1706,7 @@
     // Create LL HEAD for this Pipeline
     char str[1024];
     sprintf(str, "Created Gfx Pipeline %p (derived from pipeline %p)", (void*)*pPipeline, basePipeline);
-    layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, *pPipeline, 0, DRAWSTATE_NONE, "DS", str);
+    layerCbMsg(VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_PIPELINE, *pPipeline, 0, DRAWSTATE_NONE, "DS", str);
 
     track_pipeline(pCreateInfo, pPipeline);
 
@@ -1762,7 +1741,7 @@
         if (NULL == pNewNode) {
             char str[1024];
             sprintf(str, "Out of memory while attempting to allocate LAYOUT_NODE in vkCreateDescriptorSetLayout()");
-            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, *pSetLayout, 0, DRAWSTATE_OUT_OF_MEMORY, "DS", str);
+            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, *pSetLayout, 0, DRAWSTATE_OUT_OF_MEMORY, "DS", str);
         }
         memset(pNewNode, 0, sizeof(LAYOUT_NODE));
         memcpy((void*)&pNewNode->createInfo, pCreateInfo, sizeof(VkDescriptorSetLayoutCreateInfo));
@@ -1820,13 +1799,13 @@
         // Insert this pool into Global Pool LL at head
         char str[1024];
         sprintf(str, "Created Descriptor Pool %p", (void*)*pDescriptorPool);
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, (VkObject)pDescriptorPool, 0, DRAWSTATE_NONE, "DS", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_DESCRIPTOR_POOL, (VkObject)pDescriptorPool, 0, DRAWSTATE_NONE, "DS", str);
         loader_platform_thread_lock_mutex(&globalLock);
         POOL_NODE* pNewNode = new POOL_NODE;
         if (NULL == pNewNode) {
             char str[1024];
             sprintf(str, "Out of memory while attempting to allocate POOL_NODE in vkCreateDescriptorPool()");
-            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, (VkObject)*pDescriptorPool, 0, DRAWSTATE_OUT_OF_MEMORY, "DS", str);
+            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DESCRIPTOR_POOL, (VkObject)*pDescriptorPool, 0, DRAWSTATE_OUT_OF_MEMORY, "DS", str);
         }
         else {
             memset(pNewNode, 0, sizeof(POOL_NODE));
@@ -1871,19 +1850,19 @@
         if (!pPoolNode) {
             char str[1024];
             sprintf(str, "Unable to find pool node for pool %p specified in vkAllocDescriptorSets() call", (void*)descriptorPool);
-            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, descriptorPool, 0, DRAWSTATE_INVALID_POOL, "DS", str);
+            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DESCRIPTOR_POOL, descriptorPool, 0, DRAWSTATE_INVALID_POOL, "DS", str);
         }
         else {
             for (uint32_t i = 0; i < *pCount; i++) {
                 char str[1024];
                 sprintf(str, "Created Descriptor Set %p", (void*)pDescriptorSets[i]);
-                layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, pDescriptorSets[i], 0, DRAWSTATE_NONE, "DS", str);
+                layerCbMsg(VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_DESCRIPTOR_SET, pDescriptorSets[i], 0, DRAWSTATE_NONE, "DS", str);
                 // Create new set node and add to head of pool nodes
                 SET_NODE* pNewNode = new SET_NODE;
                 if (NULL == pNewNode) {
                     char str[1024];
                     sprintf(str, "Out of memory while attempting to allocate SET_NODE in vkAllocDescriptorSets()");
-                    layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, pDescriptorSets[i], 0, DRAWSTATE_OUT_OF_MEMORY, "DS", str);
+                    layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DESCRIPTOR_SET, pDescriptorSets[i], 0, DRAWSTATE_OUT_OF_MEMORY, "DS", str);
                 }
                 else {
                     memset(pNewNode, 0, sizeof(SET_NODE));
@@ -1894,7 +1873,7 @@
                     if (NULL == pLayout) {
                         char str[1024];
                         sprintf(str, "Unable to find set layout node for layout %p specified in vkAllocDescriptorSets() call", (void*)pSetLayouts[i]);
-                        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, pSetLayouts[i], 0, DRAWSTATE_INVALID_LAYOUT, "DS", str);
+                        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, pSetLayouts[i], 0, DRAWSTATE_INVALID_LAYOUT, "DS", str);
                     }
                     pNewNode->pLayout = pLayout;
                     pNewNode->pool = descriptorPool;
@@ -2012,7 +1991,7 @@
         else {
             char str[1024];
             sprintf(str, "In vkBeginCommandBuffer() and unable to find CmdBuffer Node for CB %p!", (void*)cmdBuffer);
-            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
+            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
         }
         updateCBTracking(cmdBuffer);
     }
@@ -2035,7 +2014,7 @@
         else {
             char str[1024];
             sprintf(str, "In vkEndCommandBuffer() and unable to find CmdBuffer Node for CB %p!", (void*)cmdBuffer);
-            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
+            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
         }
         updateCBTracking(cmdBuffer);
         //cbDumpDotFile("cb_dump.dot");
@@ -2075,13 +2054,13 @@
         else {
             char str[1024];
             sprintf(str, "Attempt to bind Pipeline %p that doesn't exist!", (void*)pipeline);
-            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, pipeline, 0, DRAWSTATE_INVALID_PIPELINE, "DS", str);
+            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_PIPELINE, pipeline, 0, DRAWSTATE_INVALID_PIPELINE, "DS", str);
         }
     }
     else {
         char str[1024];
         sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
     }
 }
 
@@ -2109,12 +2088,12 @@
                     loader_platform_thread_unlock_mutex(&globalLock);
                     char str[1024];
                     sprintf(str, "DS %p bound on pipeline %s", (void*)pDescriptorSets[i], string_VkPipelineBindPoint(pipelineBindPoint));
-                    layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, pDescriptorSets[i], 0, DRAWSTATE_NONE, "DS", str);
+                    layerCbMsg(VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_DESCRIPTOR_SET, pDescriptorSets[i], 0, DRAWSTATE_NONE, "DS", str);
                 }
                 else {
                     char str[1024];
                     sprintf(str, "Attempt to bind DS %p that doesn't exist!", (void*)pDescriptorSets[i]);
-                    layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, pDescriptorSets[i], 0, DRAWSTATE_INVALID_SET, "DS", str);
+                    layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DESCRIPTOR_SET, pDescriptorSets[i], 0, DRAWSTATE_INVALID_SET, "DS", str);
                 }
             }
             VkLayerDispatchTable *pDisp =  *(VkLayerDispatchTable **) cmdBuffer;
@@ -2125,7 +2104,7 @@
     else {
         char str[1024];
         sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
     }
 }
 
@@ -2140,7 +2119,7 @@
     else {
         char str[1024];
         sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
     }
     VkLayerDispatchTable *pDisp =  *(VkLayerDispatchTable **) cmdBuffer;
     VkLayerDispatchTable *pTable = tableMap[pDisp];
@@ -2168,7 +2147,7 @@
     } else {
         char str[1024];
         sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
     }
 }
 
@@ -2185,13 +2164,13 @@
         loader_platform_thread_unlock_mutex(&globalLock);
         char str[1024];
         sprintf(str, "vkCmdDraw() call #%lu, reporting DS state:", g_drawCount[DRAW]++);
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_NONE, "DS", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_NONE, "DS", str);
         synchAndPrintDSConfig(cmdBuffer);
     }
     else {
         char str[1024];
         sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
     }
     if (valid) {
         VkLayerDispatchTable *pDisp =  *(VkLayerDispatchTable **) cmdBuffer;
@@ -2213,13 +2192,13 @@
         loader_platform_thread_unlock_mutex(&globalLock);
         char str[1024];
         sprintf(str, "vkCmdDrawIndexed() call #%lu, reporting DS state:", g_drawCount[DRAW_INDEXED]++);
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_NONE, "DS", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_NONE, "DS", str);
         synchAndPrintDSConfig(cmdBuffer);
     }
     else {
         char str[1024];
         sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
     }
     if (valid) {
         VkLayerDispatchTable *pDisp =  *(VkLayerDispatchTable **) cmdBuffer;
@@ -2241,13 +2220,13 @@
         loader_platform_thread_unlock_mutex(&globalLock);
         char str[1024];
         sprintf(str, "vkCmdDrawIndirect() call #%lu, reporting DS state:", g_drawCount[DRAW_INDIRECT]++);
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_NONE, "DS", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_NONE, "DS", str);
         synchAndPrintDSConfig(cmdBuffer);
     }
     else {
         char str[1024];
         sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
     }
     if (valid) {
         VkLayerDispatchTable *pDisp =  *(VkLayerDispatchTable **) cmdBuffer;
@@ -2269,13 +2248,13 @@
         loader_platform_thread_unlock_mutex(&globalLock);
         char str[1024];
         sprintf(str, "vkCmdDrawIndexedIndirect() call #%lu, reporting DS state:", g_drawCount[DRAW_INDEXED_INDIRECT]++);
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_NONE, "DS", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_NONE, "DS", str);
         synchAndPrintDSConfig(cmdBuffer);
     }
     else {
         char str[1024];
         sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
     }
     if (valid) {
         VkLayerDispatchTable *pDisp =  *(VkLayerDispatchTable **) cmdBuffer;
@@ -2294,7 +2273,7 @@
     else {
         char str[1024];
         sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
     }
     VkLayerDispatchTable *pDisp =  *(VkLayerDispatchTable **) cmdBuffer;
     VkLayerDispatchTable *pTable = tableMap[pDisp];
@@ -2311,7 +2290,7 @@
     else {
         char str[1024];
         sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
     }
     VkLayerDispatchTable *pDisp =  *(VkLayerDispatchTable **) cmdBuffer;
     VkLayerDispatchTable *pTable = tableMap[pDisp];
@@ -2328,7 +2307,7 @@
     else {
         char str[1024];
         sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
     }
     VkLayerDispatchTable *pDisp =  *(VkLayerDispatchTable **) cmdBuffer;
     VkLayerDispatchTable *pTable = tableMap[pDisp];
@@ -2350,7 +2329,7 @@
     else {
         char str[1024];
         sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
     }
     VkLayerDispatchTable *pDisp =  *(VkLayerDispatchTable **) cmdBuffer;
     VkLayerDispatchTable *pTable = tableMap[pDisp];
@@ -2371,7 +2350,7 @@
     else {
         char str[1024];
         sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
     }
     VkLayerDispatchTable *pDisp =  *(VkLayerDispatchTable **) cmdBuffer;
     VkLayerDispatchTable *pTable = tableMap[pDisp];
@@ -2391,7 +2370,7 @@
     else {
         char str[1024];
         sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
     }
     VkLayerDispatchTable *pDisp =  *(VkLayerDispatchTable **) cmdBuffer;
     VkLayerDispatchTable *pTable = tableMap[pDisp];
@@ -2411,7 +2390,7 @@
     else {
         char str[1024];
         sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
     }
     VkLayerDispatchTable *pDisp =  *(VkLayerDispatchTable **) cmdBuffer;
     VkLayerDispatchTable *pTable = tableMap[pDisp];
@@ -2428,7 +2407,7 @@
     else {
         char str[1024];
         sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
     }
     VkLayerDispatchTable *pDisp =  *(VkLayerDispatchTable **) cmdBuffer;
     VkLayerDispatchTable *pTable = tableMap[pDisp];
@@ -2445,7 +2424,7 @@
     else {
         char str[1024];
         sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
     }
     VkLayerDispatchTable *pDisp =  *(VkLayerDispatchTable **) cmdBuffer;
     VkLayerDispatchTable *pTable = tableMap[pDisp];
@@ -2466,7 +2445,7 @@
     else {
         char str[1024];
         sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
     }
     VkLayerDispatchTable *pDisp =  *(VkLayerDispatchTable **) cmdBuffer;
     VkLayerDispatchTable *pTable = tableMap[pDisp];
@@ -2486,7 +2465,7 @@
     else {
         char str[1024];
         sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
     }
     VkLayerDispatchTable *pDisp =  *(VkLayerDispatchTable **) cmdBuffer;
     VkLayerDispatchTable *pTable = tableMap[pDisp];
@@ -2506,7 +2485,7 @@
     else {
         char str[1024];
         sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
     }
     VkLayerDispatchTable *pDisp =  *(VkLayerDispatchTable **) cmdBuffer;
     VkLayerDispatchTable *pTable = tableMap[pDisp];
@@ -2523,7 +2502,7 @@
     else {
         char str[1024];
         sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
     }
     VkLayerDispatchTable *pDisp =  *(VkLayerDispatchTable **) cmdBuffer;
     VkLayerDispatchTable *pTable = tableMap[pDisp];
@@ -2540,7 +2519,7 @@
     else {
         char str[1024];
         sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
     }
     VkLayerDispatchTable *pDisp =  *(VkLayerDispatchTable **) cmdBuffer;
     VkLayerDispatchTable *pTable = tableMap[pDisp];
@@ -2557,7 +2536,7 @@
     else {
         char str[1024];
         sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
     }
     VkLayerDispatchTable *pDisp =  *(VkLayerDispatchTable **) cmdBuffer;
     VkLayerDispatchTable *pTable = tableMap[pDisp];
@@ -2574,7 +2553,7 @@
     else {
         char str[1024];
         sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
     }
     VkLayerDispatchTable *pDisp =  *(VkLayerDispatchTable **) cmdBuffer;
     VkLayerDispatchTable *pTable = tableMap[pDisp];
@@ -2591,7 +2570,7 @@
     else {
         char str[1024];
         sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
     }
     VkLayerDispatchTable *pDisp =  *(VkLayerDispatchTable **) cmdBuffer;
     VkLayerDispatchTable *pTable = tableMap[pDisp];
@@ -2608,7 +2587,7 @@
     else {
         char str[1024];
         sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
     }
     VkLayerDispatchTable *pDisp =  *(VkLayerDispatchTable **) cmdBuffer;
     VkLayerDispatchTable *pTable = tableMap[pDisp];
@@ -2625,7 +2604,7 @@
     else {
         char str[1024];
         sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
     }
     VkLayerDispatchTable *pDisp =  *(VkLayerDispatchTable **) cmdBuffer;
     VkLayerDispatchTable *pTable = tableMap[pDisp];
@@ -2642,7 +2621,7 @@
     else {
         char str[1024];
         sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
     }
     VkLayerDispatchTable *pDisp =  *(VkLayerDispatchTable **) cmdBuffer;
     VkLayerDispatchTable *pTable = tableMap[pDisp];
@@ -2659,7 +2638,7 @@
     else {
         char str[1024];
         sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
     }
     VkLayerDispatchTable *pDisp =  *(VkLayerDispatchTable **) cmdBuffer;
     VkLayerDispatchTable *pTable = tableMap[pDisp];
@@ -2676,7 +2655,7 @@
     else {
         char str[1024];
         sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
     }
     VkLayerDispatchTable *pDisp =  *(VkLayerDispatchTable **) cmdBuffer;
     VkLayerDispatchTable *pTable = tableMap[pDisp];
@@ -2693,7 +2672,7 @@
     else {
         char str[1024];
         sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
     }
     VkLayerDispatchTable *pDisp =  *(VkLayerDispatchTable **) cmdBuffer;
     VkLayerDispatchTable *pTable = tableMap[pDisp];
@@ -2760,7 +2739,7 @@
     } else {
         char str[1024];
         sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
     }
     VkLayerDispatchTable *pDisp =  *(VkLayerDispatchTable **) cmdBuffer;
     VkLayerDispatchTable *pTable = tableMap[pDisp];
@@ -2778,61 +2757,32 @@
     else {
         char str[1024];
         sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
     }
     VkLayerDispatchTable *pDisp =  *(VkLayerDispatchTable **) cmdBuffer;
     VkLayerDispatchTable *pTable = tableMap[pDisp];
     pTable->CmdEndRenderPass(cmdBuffer, renderPass);
 }
 
-VK_LAYER_EXPORT VkResult VKAPI vkDbgRegisterMsgCallback(VkInstance instance, VK_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback, void* pUserData)
+VK_LAYER_EXPORT VkResult VKAPI vkDbgCreateMsgCallback(
+    VkInstance                          instance,
+    VkFlags                             msgFlags,
+    const PFN_vkDbgMsgCallback          pfnMsgCallback,
+    void*                               pUserData,
+    VkDbgMsgCallback*                   pMsgCallback)
 {
-    // This layer intercepts callbacks
-    VK_LAYER_DBG_FUNCTION_NODE* pNewDbgFuncNode = new VK_LAYER_DBG_FUNCTION_NODE;
-    if (!pNewDbgFuncNode)
-        return VK_ERROR_OUT_OF_HOST_MEMORY;
-    pNewDbgFuncNode->pfnMsgCallback = pfnMsgCallback;
-    pNewDbgFuncNode->pUserData = pUserData;
-    pNewDbgFuncNode->pNext = g_pDbgFunctionHead;
-    g_pDbgFunctionHead = pNewDbgFuncNode;
-    // force callbacks if DebugAction hasn't been set already other than initial value
-    if (g_actionIsDefault) {
-        g_debugAction = VK_DBG_LAYER_ACTION_CALLBACK;
-    }
-
-    VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) instance;
-    VkLayerInstanceDispatchTable* pInstTable = tableInstanceMap[*ppDisp];
-    VkResult result = pInstTable->DbgRegisterMsgCallback(instance, pfnMsgCallback, pUserData);
-    return result;
+    VkLayerInstanceDispatchTable *pDisp = *(VkLayerInstanceDispatchTable **) instance;
+    VkLayerInstanceDispatchTable *pTable = tableInstanceMap[pDisp];
+    return layer_create_msg_callback(instance, pTable, msgFlags, pfnMsgCallback, pUserData, pMsgCallback);
 }
 
-VK_LAYER_EXPORT VkResult VKAPI vkDbgUnregisterMsgCallback(VkInstance instance, VK_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback)
+VK_LAYER_EXPORT VkResult VKAPI vkDbgDestroyMsgCallback(
+    VkInstance                          instance,
+    VkDbgMsgCallback                    msgCallback)
 {
-    VK_LAYER_DBG_FUNCTION_NODE *pTrav = g_pDbgFunctionHead;
-    VK_LAYER_DBG_FUNCTION_NODE *pPrev = pTrav;
-    while (pTrav) {
-        if (pTrav->pfnMsgCallback == pfnMsgCallback) {
-            pPrev->pNext = pTrav->pNext;
-            if (g_pDbgFunctionHead == pTrav)
-                g_pDbgFunctionHead = pTrav->pNext;
-            delete pTrav;
-            break;
-        }
-        pPrev = pTrav;
-        pTrav = pTrav->pNext;
-    }
-    if (g_pDbgFunctionHead == NULL)
-    {
-        if (g_actionIsDefault)
-            g_debugAction = VK_DBG_LAYER_ACTION_LOG_MSG;
-        else
-            g_debugAction = (VK_LAYER_DBG_ACTION)(g_debugAction & ~((uint32_t)VK_DBG_LAYER_ACTION_CALLBACK));
-    }
-
-    VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) instance;
-    VkLayerInstanceDispatchTable* pInstTable = tableInstanceMap[*ppDisp];
-    VkResult result = pInstTable->DbgUnregisterMsgCallback(instance, pfnMsgCallback);
-    return result;
+    VkLayerInstanceDispatchTable *pDisp = *(VkLayerInstanceDispatchTable **) instance;
+    VkLayerInstanceDispatchTable *pTable = tableInstanceMap[pDisp];
+    return layer_destroy_msg_callback(instance, pTable, msgCallback);
 }
 
 VK_LAYER_EXPORT void VKAPI vkCmdDbgMarkerBegin(VkCmdBuffer cmdBuffer, const char* pMarker)
@@ -2845,7 +2795,7 @@
     else {
         char str[1024];
         sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
     }
     VkLayerDispatchTable *pDisp =  *(VkLayerDispatchTable **) cmdBuffer;
     VkLayerDispatchTable *pTable = tableMap[pDisp];
@@ -2862,7 +2812,7 @@
     else {
         char str[1024];
         sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
     }
     VkLayerDispatchTable *pDisp =  *(VkLayerDispatchTable **) cmdBuffer;
     VkLayerDispatchTable *pTable = tableMap[pDisp];
@@ -2888,7 +2838,7 @@
 // FIXME: NEED WINDOWS EQUIVALENT
         char str[1024];
         sprintf(str, "Cannot execute dot program yet on Windows.");
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_MISSING_DOT_PROGRAM, "DS", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, DRAWSTATE_MISSING_DOT_PROGRAM, "DS", str);
 #else // WIN32
     char dotExe[32] = "/usr/bin/dot";
     if( access(dotExe, X_OK) != -1) {
@@ -2902,7 +2852,7 @@
     else {
         char str[1024];
         sprintf(str, "Cannot execute dot program at (%s) to dump requested %s file.", dotExe, outFileName);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_MISSING_DOT_PROGRAM, "DS", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, DRAWSTATE_MISSING_DOT_PROGRAM, "DS", str);
     }
 #endif // WIN32
 }
@@ -3035,6 +2985,8 @@
         return (void*) vkCmdBeginRenderPass;
     if (!strcmp(funcName, "vkCmdEndRenderPass"))
         return (void*) vkCmdEndRenderPass;
+    if (!strcmp(funcName, "vkDbgCreateMsgCallback"))
+        return (void*) vkDbgCreateMsgCallback;
     if (!strcmp(funcName, "vkCmdDbgMarkerBegin"))
         return (void*) vkCmdDbgMarkerBegin;
     if (!strcmp(funcName, "vkCmdDbgMarkerEnd"))
@@ -3067,12 +3019,6 @@
         return (void *) vkDestroyInstance;
     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;
diff --git a/layers/draw_state.h b/layers/draw_state.h
index a7351bb..d56f2db 100644
--- a/layers/draw_state.h
+++ b/layers/draw_state.h
@@ -122,7 +122,8 @@
 } BUFFER_NODE;
 
 typedef struct _DYNAMIC_STATE_NODE {
-    VkDynamicStateObject    stateObj;
+    VkObjectType                objType;
+    VkDynamicStateObject        stateObj;
     GENERIC_HEADER*             pCreateInfo;
     union {
         VkDynamicVpStateCreateInfo vpci;
diff --git a/layers/layers_config.cpp b/layers/layers_config.cpp
index 134bf16..5f72664 100644
--- a/layers/layers_config.cpp
+++ b/layers/layers_config.cpp
@@ -53,7 +53,7 @@
 
 static ConfigFile g_configFileObj;
 
-static unsigned int convertStringEnumVal(const char *_enum)
+static VkLayerDbgAction stringToDbgAction(const char *_enum)
 {
     // only handles single enum values
     if (!strcmp(_enum, "VK_DBG_LAYER_ACTION_IGNORE"))
@@ -64,18 +64,34 @@
         return VK_DBG_LAYER_ACTION_LOG_MSG;
     else if (!strcmp(_enum, "VK_DBG_LAYER_ACTION_BREAK"))
         return VK_DBG_LAYER_ACTION_BREAK;
-    else if (!strcmp(_enum, "VK_DBG_LAYER_LEVEL_INFO"))
-        return VK_DBG_LAYER_LEVEL_INFO;
-    else if (!strcmp(_enum, "VK_DBG_LAYER_LEVEL_WARN"))
-        return VK_DBG_LAYER_LEVEL_WARN;
-    else if (!strcmp(_enum, "VK_DBG_LAYER_LEVEL_PERF_WARN"))
-        return VK_DBG_LAYER_LEVEL_PERF_WARN;
-    else if (!strcmp(_enum, "VK_DBG_LAYER_LEVEL_ERROR"))
-        return VK_DBG_LAYER_LEVEL_ERROR;
-    else if (!strcmp(_enum, "VK_DBG_LAYER_LEVEL_NONE"))
-        return VK_DBG_LAYER_LEVEL_NONE;
-    return 0;
+    return (VkLayerDbgAction) 0;
 }
+
+static VkFlags stringToDbgReportFlags(const char *_enum)
+{
+    // only handles single enum values
+    if (!strcmp(_enum, "VK_DBG_REPORT_INFO"))
+        return VK_DBG_REPORT_INFO_BIT;
+    else if (!strcmp(_enum, "VK_DBG_REPORT_WARN"))
+        return VK_DBG_REPORT_WARN_BIT;
+    else if (!strcmp(_enum, "VK_DBG_REPORT_PERF_WARN"))
+        return VK_DBG_REPORT_PERF_WARN_BIT;
+    else if (!strcmp(_enum, "VK_DBG_REPORT_ERROR"))
+        return VK_DBG_REPORT_ERROR_BIT;
+    return (VkFlags) 0;
+}
+
+static unsigned int convertStringEnumVal(const char *_enum)
+{
+    unsigned int ret;
+
+    ret = stringToDbgAction(_enum);
+    if (ret)
+        return ret;
+
+    return stringToDbgReportFlags(_enum);
+}
+
 const char *getLayerOption(const char *_option)
 {
     return g_configFileObj.getOption(_option);
diff --git a/layers/layers_msg.h b/layers/layers_msg.h
index 3cd5a0c..88208f9 100644
--- a/layers/layers_msg.h
+++ b/layers/layers_msg.h
@@ -23,45 +23,132 @@
  */
 #include <stdio.h>
 #include <stdbool.h>
+#include "vkLayer.h"
 
-static VK_LAYER_DBG_FUNCTION_NODE *g_pDbgFunctionHead = NULL;
-static VK_LAYER_DBG_REPORT_LEVEL g_reportingLevel = VK_DBG_LAYER_LEVEL_INFO;
-static VK_LAYER_DBG_ACTION g_debugAction = VK_DBG_LAYER_ACTION_LOG_MSG;
+static VkLayerDbgFunctionNode *g_pDbgFunctionHead = NULL;
+static VkFlags g_reportFlags = (VkFlags) 0;
+static VkLayerDbgAction g_debugAction = VK_DBG_LAYER_ACTION_LOG_MSG;
 static bool g_actionIsDefault = true;
+static bool g_DEBUG_REPORT = false;
 static FILE *g_logFile = NULL;
 
+static void enable_debug_report(
+        uint32_t                        extension_count,
+        const VkExtensionProperties*    pEnabledExtensions)    // layer or extension name to be enabled
+{
+    for (uint32_t i = 0; i < extension_count; i++) {
+        /* TODO: Check other property fields */
+        if (strcmp(pEnabledExtensions[i].name, DEBUG_REPORT_EXTENSION_NAME) == 0) {
+            g_DEBUG_REPORT = true;
+        }
+    }
+}
+
+static VkResult layer_create_msg_callback(
+        VkInstance instance,
+        VkLayerInstanceDispatchTable* nextTable,
+        VkFlags msgFlags,
+        const PFN_vkDbgMsgCallback pfnMsgCallback,
+        void* pUserData,
+        VkDbgMsgCallback* pMsgCallback)
+{
+    VkLayerDbgFunctionNode *pNewDbgFuncNode = (VkLayerDbgFunctionNode*)malloc(sizeof(VkLayerDbgFunctionNode));
+    if (!pNewDbgFuncNode)
+        return VK_ERROR_OUT_OF_HOST_MEMORY;
+    VkResult result = nextTable->DbgCreateMsgCallback(instance, msgFlags, pfnMsgCallback, pUserData, pMsgCallback);
+    if (result == VK_SUCCESS) {
+        pNewDbgFuncNode->msgCallback = *pMsgCallback;
+        pNewDbgFuncNode->pfnMsgCallback = pfnMsgCallback;
+        pNewDbgFuncNode->msgFlags = msgFlags;
+        pNewDbgFuncNode->pUserData = pUserData;
+        pNewDbgFuncNode->pNext = g_pDbgFunctionHead;
+        g_pDbgFunctionHead = pNewDbgFuncNode;
+    } else {
+        free(pNewDbgFuncNode);
+    }
+    return result;
+}
+
+static VkResult layer_destroy_msg_callback(
+        VkInstance instance,
+        VkLayerInstanceDispatchTable *nextTable,
+        VkDbgMsgCallback msg_callback)
+{
+    VkLayerDbgFunctionNode *pTrav = g_pDbgFunctionHead;
+    VkLayerDbgFunctionNode *pPrev = pTrav;
+
+    VkResult result = nextTable->DbgDestroyMsgCallback(instance, msg_callback);
+
+    while (pTrav) {
+        if (pTrav->msgCallback == msg_callback) {
+            pPrev->pNext = pTrav->pNext;
+            if (g_pDbgFunctionHead == pTrav)
+                g_pDbgFunctionHead = pTrav->pNext;
+            free(pTrav);
+            break;
+        }
+        pPrev = pTrav;
+        pTrav = pTrav->pNext;
+    }
+
+    return result;
+}
+
 // Utility function to handle reporting
 //  If callbacks are enabled, use them, otherwise use printf
-static void layerCbMsg(VK_DBG_MSG_TYPE msgType,
-    VkValidationLevel    validationLevel,
-    VkObject             srcObject,
-    size_t               location,
-    int32_t              msgCode,
-    const char*          pLayerPrefix,
-    const char*          pMsg)
+static void layerCbMsg(
+    VkFlags    msgFlags,
+    VkObjectType        objectType,
+    VkObject            srcObject,
+    size_t              location,
+    int32_t             msgCode,
+    const char*         pLayerPrefix,
+    const char*         pMsg)
 {
     if (g_logFile == NULL) {
 	g_logFile = stdout;
     }
 
+    VkLayerDbgFunctionNode *pTrav = g_pDbgFunctionHead;
+    while (pTrav) {
+        if (pTrav->msgFlags & msgFlags) {
+            pTrav->pfnMsgCallback(msgFlags,
+                                  objectType, srcObject,
+                                  location,
+                                  msgCode,
+                                  pLayerPrefix,
+                                  pMsg,
+                                  (void *) pTrav->pUserData);
+        }
+        pTrav = pTrav->pNext;
+    }
+#if 0
     if (g_debugAction & (VK_DBG_LAYER_ACTION_LOG_MSG | VK_DBG_LAYER_ACTION_CALLBACK)) {
-        VK_LAYER_DBG_FUNCTION_NODE *pTrav = g_pDbgFunctionHead;
-        switch (msgType) {
-            case VK_DBG_MSG_ERROR:
-                if (g_reportingLevel <= VK_DBG_LAYER_LEVEL_ERROR) {
-                    if (g_debugAction & VK_DBG_LAYER_ACTION_LOG_MSG) {
-                        fprintf(g_logFile, "{%s}ERROR : %s\n", pLayerPrefix, pMsg);
-                        fflush(g_logFile);
-                    }
-                    if (g_debugAction & VK_DBG_LAYER_ACTION_CALLBACK)
-                        while (pTrav) {
-				            pTrav->pfnMsgCallback(msgType, validationLevel, srcObject, location, msgCode, pMsg, pTrav->pUserData);
-                            pTrav = pTrav->pNext;
-                        }
+        if (msgFlags & VK_DBG_REPORT_ERROR_BIT) {
+            if (g_reportFlags <= VK_DBG_LAYER_LEVEL_ERROR) {
+                if (g_debugAction & VK_DBG_LAYER_ACTION_LOG_MSG) {
+                    fprintf(g_logFile, "{%s}ERROR : %s\n", pLayerPrefix, pMsg);
+                    fflush(g_logFile);
                 }
+                if (g_debugAction & VK_DBG_LAYER_ACTION_CALLBACK) {
+                    while (pTrav) {
+                        pTrav->pfnMsgCallback(msgFlags,
+                                              objectType, srcObject,
+                                              location,
+                                              msgCode,
+                                              pLayerPrefix,
+                                              pMsg,
+                                              pTrav->pUserData);
+                        pTrav = pTrav->pNext;
+                    }
+                }
+            }
+        }
+        switch (msgType) {
+            case VK_DBG_REPORT_ERROR_BIT:
                 break;
             case VK_DBG_MSG_WARNING:
-                if (g_reportingLevel <= VK_DBG_LAYER_LEVEL_WARN) {
+                if (g_reportFlags <= VK_DBG_LAYER_LEVEL_WARN) {
                     if (g_debugAction & VK_DBG_LAYER_ACTION_LOG_MSG)
                         fprintf(g_logFile, "{%s}WARN : %s\n", pLayerPrefix, pMsg);
                     if (g_debugAction & VK_DBG_LAYER_ACTION_CALLBACK)
@@ -72,7 +159,7 @@
                 }
                 break;
             case VK_DBG_MSG_PERF_WARNING:
-                if (g_reportingLevel <= VK_DBG_LAYER_LEVEL_PERF_WARN) {
+                if (g_reportFlags <= VK_DBG_LAYER_LEVEL_PERF_WARN) {
                     if (g_debugAction & VK_DBG_LAYER_ACTION_LOG_MSG)
                         fprintf(g_logFile, "{%s}PERF_WARN : %s\n", pLayerPrefix, pMsg);
                     if (g_debugAction & VK_DBG_LAYER_ACTION_CALLBACK)
@@ -83,7 +170,7 @@
                 }
                 break;
             default:
-                if (g_reportingLevel <= VK_DBG_LAYER_LEVEL_INFO) {
+                if (g_reportFlags <= VK_DBG_LAYER_LEVEL_INFO) {
                     if (g_debugAction & VK_DBG_LAYER_ACTION_LOG_MSG)
                         fprintf(g_logFile, "{%s}INFO : %s\n", pLayerPrefix, pMsg);
                     if (g_debugAction & VK_DBG_LAYER_ACTION_CALLBACK)
@@ -95,4 +182,5 @@
                 break;
         }
     }
+#endif
 }
diff --git a/layers/mem_tracker.cpp b/layers/mem_tracker.cpp
index f04ab63..a9ef5f4 100644
--- a/layers/mem_tracker.cpp
+++ b/layers/mem_tracker.cpp
@@ -154,7 +154,7 @@
             if (pObjectInfo->create_info.fence_create_info.flags & VK_FENCE_CREATE_SIGNALED_BIT) {
                 char str[1024];
                 sprintf(str, "Fence %p submitted in SIGNALED state.  Fences must be reset before being submitted", fence);
-                layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, fence, 0, MEMTRACK_INVALID_FENCE_STATE, "MEM", str);
+                layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_FENCE, fence, 0, MEMTRACK_INVALID_FENCE_STATE, "MEM", str);
             }
         }
     }
@@ -259,7 +259,7 @@
         char str[1024];
         sprintf(str, "Trying to bind mem obj %p to CB %p but no info for that mem obj.\n    "
                      "Was it correctly allocated? Did it already get freed?", mem, cb);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cb, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
         result = VK_FALSE;
     } else {
         // Search for cmd buffer object in memory object's binding list
@@ -284,7 +284,7 @@
         if (!pCBInfo) {
             char str[1024];
             sprintf(str, "Trying to bind mem obj %p to CB %p but no info for that CB. Was CB incorrectly destroyed?", mem, cb);
-            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
+            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cb, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
             result = VK_FALSE;
         } else {
             // Search for memory object in cmd buffer's reference list
@@ -331,7 +331,7 @@
     if (!pCBInfo) {
         char str[1024];
         sprintf(str, "Unable to find global CB info %p for deletion", cb);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_INVALID_CB, "MEM", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cb, 0, MEMTRACK_INVALID_CB, "MEM", str);
         result = VK_FALSE;
     } else {
         if (pCBInfo->pMemObjList.size() > 0) {
@@ -381,14 +381,14 @@
         char str[1024];
         sprintf(str, "Attempting to free memory object %p which still contains %lu references",
             pMemObjInfo->mem, (cmdBufRefCount + objRefCount));
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, pMemObjInfo->mem, 0, MEMTRACK_INTERNAL_ERROR, "MEM", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DEVICE_MEMORY, pMemObjInfo->mem, 0, MEMTRACK_INTERNAL_ERROR, "MEM", str);
     }
 
     if (cmdBufRefCount > 0 && pMemObjInfo->pCmdBufferBindings.size() > 0) {
         for (list<VkCmdBuffer>::const_iterator it = pMemObjInfo->pCmdBufferBindings.begin(); it != pMemObjInfo->pCmdBufferBindings.end(); ++it) {
             char str[1024];
             sprintf(str, "Command Buffer %p still has a reference to mem obj %p", (*it), pMemObjInfo->mem);
-            layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, (*it), 0, MEMTRACK_NONE, "MEM", str);
+            layerCbMsg(VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, (*it), 0, MEMTRACK_NONE, "MEM", str);
         }
         // Clear the list of hanging references
         pMemObjInfo->pCmdBufferBindings.clear();
@@ -398,7 +398,8 @@
         for (list<VkObject>::const_iterator it = pMemObjInfo->pObjBindings.begin(); it != pMemObjInfo->pObjBindings.end(); ++it) {
             char str[1024];
             sprintf(str, "VK Object %p still has a reference to mem obj %p", (*it), pMemObjInfo->mem);
-            layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, (*it), 0, MEMTRACK_NONE, "MEM", str);
+            /* TODO: Would be nice to return the actual object type */
+            layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, (*it), 0, MEMTRACK_NONE, "MEM", str);
         }
         // Clear the list of hanging references
         pMemObjInfo->pObjBindings.clear();
@@ -416,7 +417,7 @@
     else {
         char str[1024];
         sprintf(str, "Request to delete memory object %p not present in memory Object Map", mem);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DEVICE_MEMORY, mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
     }
 }
 
@@ -429,7 +430,7 @@
     if (!pCBInfo) {
         char str[1024];
         sprintf(str, "Unable to find global CB info %p to check for completion", cb);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_INVALID_CB, "MEM", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cb, 0, MEMTRACK_INVALID_CB, "MEM", str);
         result = VK_FALSE;
     } else if (pCBInfo->lastSubmittedQueue != NULL) {
         VkQueue queue = pCBInfo->lastSubmittedQueue;
@@ -438,7 +439,7 @@
             char str[1024];
             sprintf(str, "fence %p for CB %p has not been checked for completion",
                 (void*)pCBInfo->lastSubmittedFence, cb);
-            layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_NONE, "MEM", str);
+            layerCbMsg(VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cb, 0, MEMTRACK_NONE, "MEM", str);
             result = VK_FALSE;
         }
     }
@@ -456,14 +457,14 @@
         char str[1024];
         sprintf(str, "Couldn't find mem info object for %p\n    Was %p never allocated or previously freed?",
             (void*)mem, (void*)mem);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DEVICE_MEMORY, mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
         result = VK_FALSE;
     } else {
         if (pInfo->allocInfo.allocationSize == 0 && !internal) {
             char str[1024];
             sprintf(str, "Attempting to free memory associated with a Persistent Image, %p, "
                          "this should not be explicitly freed\n", (void*)mem);
-            layerCbMsg(VK_DBG_MSG_WARNING, VK_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
+            layerCbMsg(VK_DBG_REPORT_WARN_BIT, VK_OBJECT_TYPE_DEVICE_MEMORY, mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
             result = VK_FALSE;
         } else {
             // Clear any CB bindings for completed CBs
@@ -507,7 +508,7 @@
         if (!pObjInfo->pMemObjInfo || pObjInfo->pMemObjInfo->pObjBindings.size() <= 0) {
             char str[1024];
             sprintf(str, "Attempting to clear mem binding on obj %p but it has no binding.", (void*)object);
-            layerCbMsg(VK_DBG_MSG_WARNING, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_MEM_OBJ_CLEAR_EMPTY_BINDINGS, "MEM", str);
+            layerCbMsg(VK_DBG_REPORT_WARN_BIT, (VkObjectType) 0, object, 0, MEMTRACK_MEM_OBJ_CLEAR_EMPTY_BINDINGS, "MEM", str);
         } else {
             // This obj is bound to a memory object. Remove the reference to this object in that memory object's list, decrement the memObj's refcount
             // and set the objects memory binding pointer to NULL.
@@ -524,7 +525,7 @@
                 char str[1024];
                 sprintf(str, "While trying to clear mem binding for object %p, unable to find that object referenced by mem obj %p",
                     object, pObjInfo->pMemObjInfo->mem);
-                layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_INTERNAL_ERROR, "MEM", str);
+                layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, object, 0, MEMTRACK_INTERNAL_ERROR, "MEM", str);
             }
         }
     }
@@ -546,27 +547,27 @@
     if (mem == VK_NULL_HANDLE) {
         char str[1024];
         sprintf(str, "Attempting to Bind Obj(%p) to NULL", (void*)object);
-        layerCbMsg(VK_DBG_MSG_WARNING, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_INTERNAL_ERROR, "MEM", str);
+        layerCbMsg(VK_DBG_REPORT_WARN_BIT, (VkObjectType) 0, object, 0, MEMTRACK_INTERNAL_ERROR, "MEM", str);
         return VK_TRUE;
     } else {
         char str[1024];
         MT_OBJ_INFO* pObjInfo = get_object_info(object);
         if (!pObjInfo) {
             sprintf(str, "Attempting to update Binding of Obj(%p) that's not in global list()", (void*)object);
-            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_INTERNAL_ERROR, "MEM", str);
+            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, object, 0, MEMTRACK_INTERNAL_ERROR, "MEM", str);
             return VK_FALSE;
         }
         // non-null case so should have real mem obj
         MT_MEM_OBJ_INFO* pInfo = get_mem_obj_info(mem);
         if (!pInfo) {
             sprintf(str, "While trying to bind mem for obj %p, couldn't find info for mem obj %p", (void*)object, (void*)mem);
-            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
+            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DEVICE_MEMORY, mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
             return VK_FALSE;
         } else {
             if (pObjInfo->pMemObjInfo != NULL) {
                 sprintf(str, "Attempting to bind memory (%p) to object (%p) which has already been bound to mem object %p",
                     (void*)mem, (void*)object, (void*)pObjInfo->pMemObjInfo->mem);
-                layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_REBIND_OBJECT, "MEM", str);
+                layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DEVICE_MEMORY, mem, 0, MEMTRACK_REBIND_OBJECT, "MEM", str);
                 return VK_FALSE;
             }
             else {
@@ -608,14 +609,14 @@
         MT_OBJ_INFO* pObjInfo = get_object_info(object);
         if (!pObjInfo) {
             sprintf(str, "Attempting to update Binding of Obj(%p) that's not in global list()", (void*)object);
-            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_INTERNAL_ERROR, "MEM", str);
+            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, object, 0, MEMTRACK_INTERNAL_ERROR, "MEM", str);
             return VK_FALSE;
         }
         // non-null case so should have real mem obj
         MT_MEM_OBJ_INFO* pInfo = get_mem_obj_info(mem);
         if (!pInfo) {
             sprintf(str, "While trying to bind mem for obj %p, couldn't find info for mem obj %p", (void*)object, (void*)mem);
-            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
+            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DEVICE_MEMORY, mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
             return VK_FALSE;
         } else {
             // Search for object in memory object's binding list
@@ -637,7 +638,7 @@
             if (pObjInfo->pMemObjInfo) {
                 clear_object_binding(object); // Need to clear the previous object binding before setting new binding
                 sprintf(str, "Updating memory binding for object %p from mem obj %p to %p", object, pObjInfo->pMemObjInfo->mem, mem);
-                layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_NONE, "MEM", str);
+                layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, object, 0, MEMTRACK_NONE, "MEM", str);
             }
             pObjInfo->pMemObjInfo = pInfo;
         }
@@ -651,17 +652,14 @@
 {
     MT_OBJ_INFO* pInfo = NULL;
     char str[1024];
-    if (g_reportingLevel > VK_DBG_LAYER_LEVEL_INFO) {
-        return;
-    }
     sprintf(str, "Details of Object list of size %lu elements", objectMap.size());
-    layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
+    layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, MEMTRACK_NONE, "MEM", str);
     if (objectMap.size() <= 0)
         return;
     for (unordered_map<VkObject, MT_OBJ_INFO>::iterator ii=objectMap.begin(); ii!=objectMap.end(); ++ii) {
         pInfo = &(*ii).second;
         sprintf(str, "    ObjInfo %p has object %p, pMemObjInfo %p", pInfo, pInfo->object, pInfo->pMemObjInfo);
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, pInfo->object, 0, MEMTRACK_NONE, "MEM", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, pInfo->object, 0, MEMTRACK_NONE, "MEM", str);
     }
 }
 
@@ -677,13 +675,13 @@
         } else {
             char str[1024];
             sprintf(str, "Trying to get mem binding for object %p but object has no mem binding", (void*)object);
-            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_MISSING_MEM_BINDINGS, "MEM", str);
+            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, object, 0, MEMTRACK_MISSING_MEM_BINDINGS, "MEM", str);
             print_object_list();
         }
     } else {
         char str[1024];
         sprintf(str, "Trying to get mem binding for object %p but no such object in global list", (void*)object);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_INVALID_OBJECT, "MEM", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, object, 0, MEMTRACK_INVALID_OBJECT, "MEM", str);
         print_object_list();
     }
     return mem;
@@ -696,11 +694,8 @@
     MT_MEM_OBJ_INFO* pInfo = NULL;
     // Just printing each msg individually for now, may want to package these into single large print
     char str[1024];
-    if (g_reportingLevel > VK_DBG_LAYER_LEVEL_INFO) {
-        return;
-    }
     sprintf(str, "MEM INFO : Details of Memory Object list of size %lu elements", memObjMap.size());
-    layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
+    layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, MEMTRACK_NONE, "MEM", str);
 
     if (memObjMap.size() <= 0)
         return;
@@ -709,36 +704,36 @@
         pInfo = &(*ii).second;
 
         sprintf(str, "    ===MemObjInfo at %p===", (void*)pInfo);
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, MEMTRACK_NONE, "MEM", str);
         sprintf(str, "    Mem object: %p", (void*)pInfo->mem);
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, MEMTRACK_NONE, "MEM", str);
         sprintf(str, "    Ref Count: %u", pInfo->refCount);
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, MEMTRACK_NONE, "MEM", str);
         if (0 != pInfo->allocInfo.allocationSize) {
             string pAllocInfoMsg = vk_print_vkmemoryallocinfo(&pInfo->allocInfo, "{MEM}INFO :       ");
             sprintf(str, "    Mem Alloc info:\n%s", pAllocInfoMsg.c_str());
-            layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
+            layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, MEMTRACK_NONE, "MEM", str);
         } else {
             sprintf(str, "    Mem Alloc info is NULL (alloc done by vkCreateSwapChainWSI())");
-            layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
+            layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, MEMTRACK_NONE, "MEM", str);
         }
 
         sprintf(str, "    VK OBJECT Binding list of size %lu elements:", pInfo->pObjBindings.size());
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, MEMTRACK_NONE, "MEM", str);
         if (pInfo->pObjBindings.size() > 0) {
             for (list<VkObject>::iterator it = pInfo->pObjBindings.begin(); it != pInfo->pObjBindings.end(); ++it) {
                 sprintf(str, "       VK OBJECT %p", (*it));
-                layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
+                layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, MEMTRACK_NONE, "MEM", str);
             }
         }
 
         sprintf(str, "    VK Command Buffer (CB) binding list of size %lu elements", pInfo->pCmdBufferBindings.size());
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, MEMTRACK_NONE, "MEM", str);
         if (pInfo->pCmdBufferBindings.size() > 0)
         {
             for (list<VkCmdBuffer>::iterator it = pInfo->pCmdBufferBindings.begin(); it != pInfo->pCmdBufferBindings.end(); ++it) {
                 sprintf(str, "      VK CB %p", (*it));
-                layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
+                layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, MEMTRACK_NONE, "MEM", str);
             }
         }
     }
@@ -749,11 +744,8 @@
 {
     char str[1024];
     MT_CB_INFO* pCBInfo = NULL;
-    if (g_reportingLevel > VK_DBG_LAYER_LEVEL_INFO) {
-        return;
-    }
     sprintf(str, "Details of CB list of size %lu elements", cbMap.size());
-    layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
+    layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, MEMTRACK_NONE, "MEM", str);
 
     if (cbMap.size() <= 0)
         return;
@@ -764,13 +756,13 @@
         sprintf(str, "    CB Info (%p) has CB %p, fenceId %" PRIx64", and fence %p",
             (void*)pCBInfo, (void*)pCBInfo->cmdBuffer, pCBInfo->fenceId,
             (void*)pCBInfo->lastSubmittedFence);
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, MEMTRACK_NONE, "MEM", str);
 
         if (pCBInfo->pMemObjList.size() <= 0)
             continue;
         for (list<VkDeviceMemory>::iterator it = pCBInfo->pMemObjList.begin(); it != pCBInfo->pMemObjList.end(); ++it) {
             sprintf(str, "      Mem obj %p", (*it));
-            layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
+            layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, MEMTRACK_NONE, "MEM", str);
         }
     }
 }
@@ -797,7 +789,7 @@
 {
     const char *strOpt;
     // initialize MemTracker options
-    getLayerOptionEnum("MemTrackerReportLevel", (uint32_t *) &g_reportingLevel);
+    getLayerOptionEnum("MemTrackerReportLevel", (uint32_t *) &g_reportFlags);
     g_actionIsDefault = getLayerOptionEnum("MemTrackerDebugAction", (uint32_t *) &g_debugAction);
 
     if (g_debugAction & VK_DBG_LAYER_ACTION_LOG_MSG)
@@ -823,14 +815,30 @@
     }
 }
 
+//VkResult VKAPI vkCreateInstance(
+//    const VkInstanceCreateInfo*                 pCreateInfo,
+//    VkInstance*                                 pInstance)
+//{
+//    loader_platform_thread_once(&g_initOnce, initMemTracker);
+//    VkResult result = nextTable.CreateInstance(pCreateInfo, pInstance);
+//    if (result == VK_SUCCESS) {
+//        enable_debug_report(pCreateInfo->extensionCount, pCreateInfo->ppEnabledExtensionNames);
+//    }
+//    return result;
+//}
+
 VK_LAYER_EXPORT VkResult VKAPI vkCreateDevice(
     VkPhysicalDevice          gpu,
     const VkDeviceCreateInfo *pCreateInfo,
     VkDevice                 *pDevice)
 {
     VkResult result = nextInstanceTable.CreateDevice(gpu, pCreateInfo, pDevice);
-    // Save off device in case we need it to create Fences
-    globalDevice = *pDevice;
+    if (result == VK_SUCCESS) {
+        // Save off device in case we need it to create Fences
+        globalDevice = *pDevice;
+
+        enable_debug_report(pCreateInfo->extensionCount, pCreateInfo->pEnabledExtensions);
+    }
     return result;
 }
 
@@ -840,13 +848,13 @@
     char str[1024];
     sprintf(str, "Printing List details prior to vkDestroyDevice()");
     loader_platform_thread_lock_mutex(&globalLock);
-    layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, device, 0, MEMTRACK_NONE, "MEM", str);
+    layerCbMsg(VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_DEVICE, device, 0, MEMTRACK_NONE, "MEM", str);
     print_mem_list();
     printCBList();
     print_object_list();
     if (VK_FALSE == delete_cmd_buf_info_list()) {
         sprintf(str, "Issue deleting global CB list in vkDestroyDevice()");
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, device, 0, MEMTRACK_INTERNAL_ERROR, "MEM", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DEVICE, device, 0, MEMTRACK_INTERNAL_ERROR, "MEM", str);
     }
     // Report any memory leaks
     MT_MEM_OBJ_INFO* pInfo = NULL;
@@ -857,7 +865,7 @@
             if (pInfo->allocInfo.allocationSize != 0) {
                 sprintf(str, "Mem Object %p has not been freed. You should clean up this memory by calling "
                          "vkFreeMemory(%p) prior to vkDestroyDevice().", pInfo->mem, pInfo->mem);
-                layerCbMsg(VK_DBG_MSG_WARNING, VK_VALIDATION_LEVEL_0, pInfo->mem, 0, MEMTRACK_MEMORY_LEAK, "MEM", str);
+                layerCbMsg(VK_DBG_REPORT_WARN_BIT, VK_OBJECT_TYPE_DEVICE_MEMORY, pInfo->mem, 0, MEMTRACK_MEMORY_LEAK, "MEM", str);
             }
         }
     }
@@ -874,11 +882,14 @@
     uint32_t version;
     const char * const name;
 };
-#define MEM_TRACKER_LAYER_EXT_ARRAY_SIZE 2
-static const struct extProps mtExts[MEM_TRACKER_LAYER_EXT_ARRAY_SIZE] = {
-    // TODO what is the version?
-    0x10, "MemTracker",
-    0x10, "Validation"
+#define MEM_TRACKER_LAYER_EXT_ARRAY_SIZE 1
+static const VkExtensionProperties mtExts[MEM_TRACKER_LAYER_EXT_ARRAY_SIZE] = {
+    {
+        VK_STRUCTURE_TYPE_EXTENSION_PROPERTIES,
+        "MemTracker",
+        0x10,
+        "Sample layer: MemTracker",
+    }
 };
 
 VK_LAYER_EXPORT VkResult VKAPI vkGetGlobalExtensionInfo(
@@ -888,7 +899,6 @@
     void                *pData)
 {
     // This entrypoint is NOT going to init its own dispatch table since loader calls here early
-    VkExtensionProperties *ext_props;
     uint32_t *count;
 
     if (pDataSize == NULL) {
@@ -912,11 +922,7 @@
             if (extensionIndex >= MEM_TRACKER_LAYER_EXT_ARRAY_SIZE) {
                 return VK_ERROR_INVALID_VALUE;
             }
-            ext_props = (VkExtensionProperties *) pData;
-            ext_props->version = mtExts[extensionIndex].version;
-            strncpy(ext_props->extName, mtExts[extensionIndex].name,
-                                        VK_MAX_EXTENSION_NAME);
-            ext_props->extName[VK_MAX_EXTENSION_NAME - 1] = '\0';
+            memcpy((VkExtensionProperties *) pData, &mtExts[extensionIndex], sizeof(VkExtensionProperties));
             break;
         default:
             return VK_ERROR_INVALID_VALUE;
@@ -925,33 +931,6 @@
     return VK_SUCCESS;
 }
 
-VK_LAYER_EXPORT VkResult VKAPI vkEnumerateLayers(
-    VkPhysicalDevice  gpu,
-    size_t            maxStringSize,
-    size_t           *pLayerCount,
-    char* const      *pOutLayers,
-    void             *pReserved)
-{
-    if (gpu != NULL)
-    {
-        pCurObj = (VkBaseLayerObject *)  gpu;
-        loader_platform_thread_once(&g_initOnce, initMemTracker);
-        loader_platform_thread_once(&g_tabDeviceOnce, initDeviceTable);
-        VkResult result = nextInstanceTable.EnumerateLayers(gpu,
-            maxStringSize, pLayerCount, pOutLayers, pReserved);
-        return result;
-    } else
-    {
-        if (pLayerCount == NULL || pOutLayers == NULL || pOutLayers[0] == NULL) {
-            return VK_ERROR_INVALID_POINTER;
-        }
-        // This layer compatible with all GPUs
-        *pLayerCount = 1;
-        strncpy((char *) pOutLayers[0], "MemTracker", maxStringSize);
-        return VK_SUCCESS;
-    }
-}
-
 VK_LAYER_EXPORT VkResult VKAPI vkGetDeviceQueue(
     VkDevice  device,
     uint32_t  queueNodeIndex,
@@ -1023,7 +1002,7 @@
     if (noerror == VK_FALSE) {
         char str[1024];
         sprintf(str, "Freeing memory object while it still has references: mem obj %p", (void*)mem);
-        layerCbMsg(VK_DBG_MSG_WARNING, VK_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_FREED_MEM_REF, "MEM", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DEVICE_MEMORY, mem, 0, MEMTRACK_DESTROY_OBJECT_ERROR, "MEM", str);
     }
     loader_platform_thread_unlock_mutex(&globalLock);
     VkResult result = nextTable.FreeMemory(device, mem);
@@ -1055,7 +1034,7 @@
     if ((pMemObj->allocInfo.memProps & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == 0) {
         char str[1024];
         sprintf(str, "Mapping Memory without VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT set: mem obj %p", (void*)mem);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_STATE, "MEM", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DEVICE_MEMORY, mem, 0, MEMTRACK_INVALID_STATE, "MEM", str);
     }
     loader_platform_thread_unlock_mutex(&globalLock);
     VkResult result = nextTable.MapMemory(device, mem, offset, size, flags, ppData);
@@ -1204,7 +1183,7 @@
     if (VK_FALSE == set_sparse_buffer_binding(buffer, mem)) {
         char str[1024];
         sprintf(str, "Unable to set object %p binding to mem obj %p", (void*)buffer, (void*)mem);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, buffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_BUFFER, buffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
     }
     print_object_list();
     print_mem_list();
@@ -1242,7 +1221,7 @@
                 if (!(pObjectInfo->create_info.fence_create_info.flags & VK_FENCE_CREATE_SIGNALED_BIT)) {
                     char str[1024];
                     sprintf(str, "Fence %p submitted to VkResetFences in UNSIGNALED STATE", pFences[i]);
-                    layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, pFences[i], 0, MEMTRACK_INVALID_FENCE_STATE, "MEM", str);
+                    layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_FENCE, pFences[i], 0, MEMTRACK_INVALID_FENCE_STATE, "MEM", str);
                     result = VK_ERROR_INVALID_VALUE;
                 }
                 else {
@@ -1283,7 +1262,7 @@
             if (pObjectInfo->create_info.fence_create_info.flags & VK_FENCE_CREATE_SIGNALED_BIT) {
                 char str[1024];
                 sprintf(str, "VkWaitForFences specified fence %p already in SIGNALED state.", pFences[i]);
-                layerCbMsg(VK_DBG_MSG_WARNING, VK_VALIDATION_LEVEL_0, pFences[i], 0, MEMTRACK_INVALID_FENCE_STATE, "MEM", str);
+                layerCbMsg(VK_DBG_REPORT_WARN_BIT, VK_OBJECT_TYPE_FENCE, pFences[i], 0, MEMTRACK_INVALID_FENCE_STATE, "MEM", str);
             }
         }
     }
@@ -1585,7 +1564,7 @@
         char str[1024];
         sprintf(str, "Calling vkBeginCommandBuffer() on active CB %p before it has completed. "
                      "You must check CB flag before this call.", cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_RESET_CB_WHILE_IN_FLIGHT, "MEM", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, MEMTRACK_RESET_CB_WHILE_IN_FLIGHT, "MEM", str);
     }
     loader_platform_thread_unlock_mutex(&globalLock);
     VkResult result = nextTable.BeginCommandBuffer(cmdBuffer, pBeginInfo);
@@ -1612,7 +1591,7 @@
         char str[1024];
         sprintf(str, "Resetting CB %p before it has completed. You must check CB flag before "
                      "calling vkResetCommandBuffer().", cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_RESET_CB_WHILE_IN_FLIGHT, "MEM", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, MEMTRACK_RESET_CB_WHILE_IN_FLIGHT, "MEM", str);
     }
     // Clear memory references as this point.
     clear_cmd_buf_and_mem_references(cmdBuffer);
@@ -1636,13 +1615,13 @@
         } else {
             char str[1024];
             sprintf(str, "Attempt to bind Pipeline %p to non-existant command buffer %p!", (void*)pipeline, cmdBuffer);
-            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_INVALID_CB, (char *) "DS", (char *) str);
+            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, MEMTRACK_INVALID_CB, (char *) "DS", (char *) str);
         }
     }
     else {
         char str[1024];
         sprintf(str, "Attempt to bind Pipeline %p that doesn't exist!", (void*)pipeline);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, pipeline, 0, MEMTRACK_INVALID_OBJECT, (char *) "DS", (char *) str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_PIPELINE, pipeline, 0, MEMTRACK_INVALID_OBJECT, (char *) "DS", (char *) str);
     }
 #endif
     nextTable.CmdBindPipeline(cmdBuffer, pipelineBindPoint, pipeline);
@@ -1659,13 +1638,14 @@
     if (!pCmdBuf) {
         char str[1024];
         sprintf(str, "Unable to find command buffer object %p, was it ever created?", (void*)cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_INVALID_CB, "DD", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, MEMTRACK_INVALID_CB, "DD", str);
     }
     pObjInfo = get_object_info(state);
     if (!pObjInfo) {
         char str[1024];
         sprintf(str, "Unable to find dynamic state object %p, was it ever created?", (void*)state);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, state, 0, MEMTRACK_INVALID_OBJECT, "DD", str);
+        /* TODO: put in real object type */
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, state, 0, MEMTRACK_INVALID_OBJECT, "DD", str);
     }
     pCmdBuf->pDynamicState[stateBindPoint] = pObjInfo;
     loader_platform_thread_unlock_mutex(&globalLock);
@@ -1716,7 +1696,7 @@
     if (VK_FALSE == update_cmd_buf_and_mem_references(cmdBuffer, mem)) {
         char str[1024];
         sprintf(str, "In vkCmdDrawIndirect() call unable to update binding of buffer %p to cmdBuffer %p", buffer, cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
     }
     loader_platform_thread_unlock_mutex(&globalLock);
     nextTable.CmdDrawIndirect(cmdBuffer, buffer, offset, count, stride);
@@ -1734,7 +1714,7 @@
     if (VK_FALSE == update_cmd_buf_and_mem_references(cmdBuffer, mem)) {
         char str[1024];
         sprintf(str, "In vkCmdDrawIndexedIndirect() call unable to update binding of buffer %p to cmdBuffer %p", buffer, cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
     }
     loader_platform_thread_unlock_mutex(&globalLock);
     nextTable.CmdDrawIndexedIndirect(cmdBuffer, buffer, offset, count, stride);
@@ -1750,7 +1730,7 @@
     if (VK_FALSE == update_cmd_buf_and_mem_references(cmdBuffer, mem)) {
         char str[1024];
         sprintf(str, "In vkCmdDispatchIndirect() call unable to update binding of buffer %p to cmdBuffer %p", buffer, cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
     }
     loader_platform_thread_unlock_mutex(&globalLock);
     nextTable.CmdDispatchIndirect(cmdBuffer, buffer, offset);
@@ -1768,13 +1748,13 @@
     if (VK_FALSE == update_cmd_buf_and_mem_references(cmdBuffer, mem)) {
         char str[1024];
         sprintf(str, "In vkCmdCopyBuffer() call unable to update binding of srcBuffer %p to cmdBuffer %p", srcBuffer, cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
     }
     mem = get_mem_binding_from_object(destBuffer);
     if (VK_FALSE == update_cmd_buf_and_mem_references(cmdBuffer, mem)) {
         char str[1024];
         sprintf(str, "In vkCmdCopyBuffer() call unable to update binding of destBuffer %p to cmdBuffer %p", destBuffer, cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
     }
     loader_platform_thread_unlock_mutex(&globalLock);
     nextTable.CmdCopyBuffer(cmdBuffer, srcBuffer, destBuffer, regionCount, pRegions);
@@ -1821,14 +1801,14 @@
     if (VK_FALSE == update_cmd_buf_and_mem_references(cmdBuffer, mem)) {
         char str[1024];
         sprintf(str, "In vkCmdCopyMemoryToImage() call unable to update binding of destImage buffer %p to cmdBuffer %p", destImage, cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
     }
 
     mem = get_mem_binding_from_object(srcBuffer);
     if (VK_FALSE == update_cmd_buf_and_mem_references(cmdBuffer, mem)) {
         char str[1024];
         sprintf(str, "In vkCmdCopyMemoryToImage() call unable to update binding of srcBuffer %p to cmdBuffer %p", srcBuffer, cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
     }
     loader_platform_thread_unlock_mutex(&globalLock);
     nextTable.CmdCopyBufferToImage(cmdBuffer, srcBuffer, destImage, destImageLayout, regionCount, pRegions);
@@ -1848,13 +1828,13 @@
     if (VK_FALSE == update_cmd_buf_and_mem_references(cmdBuffer, mem)) {
         char str[1024];
         sprintf(str, "In vkCmdCopyImageToMemory() call unable to update binding of srcImage buffer %p to cmdBuffer %p", srcImage, cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
     }
     mem = get_mem_binding_from_object(destBuffer);
     if (VK_FALSE == update_cmd_buf_and_mem_references(cmdBuffer, mem)) {
         char str[1024];
         sprintf(str, "In vkCmdCopyImageToMemory() call unable to update binding of destBuffer %p to cmdBuffer %p", destBuffer, cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
     }
     loader_platform_thread_unlock_mutex(&globalLock);
     nextTable.CmdCopyImageToBuffer(cmdBuffer, srcImage, srcImageLayout, destBuffer, regionCount, pRegions);
@@ -1872,7 +1852,7 @@
     if (VK_FALSE == update_cmd_buf_and_mem_references(cmdBuffer, mem)) {
         char str[1024];
         sprintf(str, "In vkCmdUpdateMemory() call unable to update binding of destBuffer %p to cmdBuffer %p", destBuffer, cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
     }
     loader_platform_thread_unlock_mutex(&globalLock);
     nextTable.CmdUpdateBuffer(cmdBuffer, destBuffer, destOffset, dataSize, pData);
@@ -1890,7 +1870,7 @@
     if (VK_FALSE == update_cmd_buf_and_mem_references(cmdBuffer, mem)) {
         char str[1024];
         sprintf(str, "In vkCmdFillMemory() call unable to update binding of destBuffer %p to cmdBuffer %p", destBuffer, cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
     }
     loader_platform_thread_unlock_mutex(&globalLock);
     nextTable.CmdFillBuffer(cmdBuffer, destBuffer, destOffset, fillSize, data);
@@ -1910,7 +1890,7 @@
     if (VK_FALSE == update_cmd_buf_and_mem_references(cmdBuffer, mem)) {
         char str[1024];
         sprintf(str, "In vkCmdClearColorImage() call unable to update binding of image buffer %p to cmdBuffer %p", image, cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
     }
     loader_platform_thread_unlock_mutex(&globalLock);
     nextTable.CmdClearColorImage(cmdBuffer, image, imageLayout, pColor, rangeCount, pRanges);
@@ -1931,7 +1911,7 @@
     if (VK_FALSE == update_cmd_buf_and_mem_references(cmdBuffer, mem)) {
         char str[1024];
         sprintf(str, "In vkCmdClearDepthStencil() call unable to update binding of image buffer %p to cmdBuffer %p", image, cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
     }
     loader_platform_thread_unlock_mutex(&globalLock);
     nextTable.CmdClearDepthStencil(cmdBuffer, image, imageLayout, depth, stencil, rangeCount, pRanges);
@@ -1951,13 +1931,13 @@
     if (VK_FALSE == update_cmd_buf_and_mem_references(cmdBuffer, mem)) {
         char str[1024];
         sprintf(str, "In vkCmdResolveImage() call unable to update binding of srcImage buffer %p to cmdBuffer %p", srcImage, cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
     }
     mem = get_mem_binding_from_object(destImage);
     if (VK_FALSE == update_cmd_buf_and_mem_references(cmdBuffer, mem)) {
         char str[1024];
         sprintf(str, "In vkCmdResolveImage() call unable to update binding of destImage buffer %p to cmdBuffer %p", destImage, cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
     }
     loader_platform_thread_unlock_mutex(&globalLock);
     nextTable.CmdResolveImage(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
@@ -1974,7 +1954,7 @@
     if (VK_FALSE == update_cmd_buf_and_mem_references(cmdBuffer, mem)) {
         char str[1024];
         sprintf(str, "In vkCmdBeginQuery() call unable to update binding of queryPool buffer %p to cmdBuffer %p", queryPool, cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
     }
     loader_platform_thread_unlock_mutex(&globalLock);
     nextTable.CmdBeginQuery(cmdBuffer, queryPool, slot, flags);
@@ -1990,7 +1970,7 @@
     if (VK_FALSE == update_cmd_buf_and_mem_references(cmdBuffer, mem)) {
         char str[1024];
         sprintf(str, "In vkCmdEndQuery() call unable to update binding of queryPool buffer %p to cmdBuffer %p", queryPool, cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
     }
     loader_platform_thread_unlock_mutex(&globalLock);
     nextTable.CmdEndQuery(cmdBuffer, queryPool, slot);
@@ -2007,60 +1987,27 @@
     if (VK_FALSE == update_cmd_buf_and_mem_references(cmdBuffer, mem)) {
         char str[1024];
         sprintf(str, "In vkCmdResetQueryPool() call unable to update binding of queryPool buffer %p to cmdBuffer %p", queryPool, cmdBuffer);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
     }
     loader_platform_thread_unlock_mutex(&globalLock);
     nextTable.CmdResetQueryPool(cmdBuffer, queryPool, startQuery, queryCount);
 }
 
-VK_LAYER_EXPORT VkResult VKAPI vkDbgRegisterMsgCallback(
-    VkInstance                    instance,
-    VK_DBG_MSG_CALLBACK_FUNCTION  pfnMsgCallback,
-    void                         *pUserData)
+VK_LAYER_EXPORT VkResult VKAPI vkDbgCreateMsgCallback(
+        VkInstance instance,
+        VkFlags msgFlags,
+        const PFN_vkDbgMsgCallback pfnMsgCallback,
+        void* pUserData,
+        VkDbgMsgCallback* pMsgCallback)
 {
-    // This layer intercepts callbacks
-    VK_LAYER_DBG_FUNCTION_NODE *pNewDbgFuncNode = (VK_LAYER_DBG_FUNCTION_NODE*)malloc(sizeof(VK_LAYER_DBG_FUNCTION_NODE));
-    if (!pNewDbgFuncNode)
-        return VK_ERROR_OUT_OF_HOST_MEMORY;
-    pNewDbgFuncNode->pfnMsgCallback = pfnMsgCallback;
-    pNewDbgFuncNode->pUserData = pUserData;
-    pNewDbgFuncNode->pNext = g_pDbgFunctionHead;
-    g_pDbgFunctionHead = pNewDbgFuncNode;
-    // force callbacks if DebugAction hasn't been set already other than initial value
-    if (g_actionIsDefault) {
-        g_debugAction = VK_DBG_LAYER_ACTION_CALLBACK;
-    }
-    VkResult result = nextInstanceTable.DbgRegisterMsgCallback(instance, pfnMsgCallback, pUserData);
-    return result;
+    return layer_create_msg_callback(instance, &nextInstanceTable, msgFlags, pfnMsgCallback, pUserData, pMsgCallback);
 }
 
-VK_LAYER_EXPORT VkResult VKAPI vkDbgUnregisterMsgCallback(
-    VkInstance                   instance,
-    VK_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback)
+VK_LAYER_EXPORT VkResult VKAPI vkDbgDestroyMsgCallback(
+        VkInstance instance,
+        VkDbgMsgCallback msgCallback)
 {
-    VK_LAYER_DBG_FUNCTION_NODE *pInfo = g_pDbgFunctionHead;
-    VK_LAYER_DBG_FUNCTION_NODE *pPrev = pInfo;
-    while (pInfo) {
-        if (pInfo->pfnMsgCallback == pfnMsgCallback) {
-            pPrev->pNext = pInfo->pNext;
-            if (g_pDbgFunctionHead == pInfo) {
-                g_pDbgFunctionHead = pInfo->pNext;
-            }
-            free(pInfo);
-            break;
-        }
-        pPrev = pInfo;
-        pInfo = pInfo->pNext;
-    }
-    if (g_pDbgFunctionHead == NULL) {
-        if (g_actionIsDefault) {
-            g_debugAction = VK_DBG_LAYER_ACTION_LOG_MSG;
-        } else {
-            g_debugAction = (VK_LAYER_DBG_ACTION)(g_debugAction & ~((uint32_t)VK_DBG_LAYER_ACTION_CALLBACK));
-        }
-    }
-    VkResult result = nextInstanceTable.DbgUnregisterMsgCallback(instance, pfnMsgCallback);
-    return result;
+    return layer_destroy_msg_callback(instance, &nextInstanceTable, msgCallback);
 }
 
 VK_LAYER_EXPORT VkResult VKAPI vkCreateSwapChainWSI(
@@ -2131,7 +2078,7 @@
                     if (VK_FALSE == set_object_binding(it->image, it->memory)) {
                         char str[1024];
                         sprintf(str, "In vkGetSwapChainInfoWSI(), unable to set image %p binding to mem obj %p", (void*)it->image, (void*)it->memory);
-                        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, it->image, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
+                        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_IMAGE, it->image, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
                     }
                 }
             }
@@ -2142,7 +2089,7 @@
             if (mismatch) {
                 char str[1024];
                 sprintf(str, "vkGetSwapChainInfoWSI(%p, VK_SWAP_CHAIN_INFO_TYPE_PERSISTENT_IMAGES_WSI) returned mismatching data", swapChain);
-                layerCbMsg(VK_DBG_MSG_WARNING, VK_VALIDATION_LEVEL_0, (VkObject) swapChain, 0, MEMTRACK_NONE, "SWAP_CHAIN", str);
+                layerCbMsg(VK_DBG_REPORT_WARN_BIT, VK_OBJECT_TYPE_SWAP_CHAIN_WSI, (VkObject) swapChain, 0, MEMTRACK_NONE, "SWAP_CHAIN", str);
             }
         }
     }
@@ -2289,6 +2236,8 @@
         return (void*) vkCmdEndQuery;
     if (!strcmp(funcName, "vkCmdResetQueryPool"))
         return (void*) vkCmdResetQueryPool;
+    if (g_DEBUG_REPORT && !strcmp(funcName, "vkDbgCreateMsgCallback"))
+        return (void*) vkDbgCreateMsgCallback;
     if (!strcmp(funcName, "vkGetDeviceQueue"))
         return (void*) vkGetDeviceQueue;
     if (!strcmp(funcName, "vkCreateSwapChainWSI"))
@@ -2323,14 +2272,6 @@
         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;
diff --git a/layers/multi.cpp b/layers/multi.cpp
index 36f6d39..2cc9e0c 100644
--- a/layers/multi.cpp
+++ b/layers/multi.cpp
@@ -142,20 +142,6 @@
     return result;
 }
 
-VK_LAYER_EXPORT VkResult VKAPI multi1EnumerateLayers(VkPhysicalDevice gpu, size_t maxStringSize,
-                                                         size_t* pLayerCount, char* const* pOutLayers,
-                                                         void* pReserved)
-{
-    if (gpu == NULL)
-        return vkEnumerateLayers(gpu, maxStringSize, pLayerCount, pOutLayers, pReserved);
-
-    VkLayerInstanceDispatchTable* pTable = tableInstanceMap1[gpu];
-    printf("At start of multi1 layer vkEnumerateLayers()\n");
-    VkResult result = pTable->EnumerateLayers(gpu, maxStringSize, pLayerCount, pOutLayers, pReserved);
-    printf("Completed multi1 layer vkEnumerateLayers()\n");
-    return result;
-}
-
 VK_LAYER_EXPORT void * VKAPI multi1GetDeviceProcAddr(VkDevice device, const char* pName)
 {
     VkBaseLayerObject* devw = (VkBaseLayerObject *) device;
@@ -195,8 +181,6 @@
         return (void *) multi1GetInstanceProcAddr;
     if (!strcmp("vkDestroyInstance", pName))
         return (void *) multi1DestroyInstance;
-    if (!strcmp("vkEnumerateLayers", pName))
-        return (void *) multi1EnumerateLayers;
     else if (!strcmp("GetGlobalExtensionInfo", pName))
         return (void*) vkGetGlobalExtensionInfo;
     else {
@@ -319,21 +303,6 @@
 
 }
 
-VK_LAYER_EXPORT VkResult VKAPI multi2EnumerateLayers(VkPhysicalDevice gpu, size_t maxStringSize,
-                                                         size_t* pLayerCount, char* const* pOutLayers,
-                                                         void* pReserved)
-{
-    if (gpu == NULL)
-        return vkEnumerateLayers(gpu, maxStringSize, pLayerCount, pOutLayers, pReserved);
-
-    VkLayerInstanceDispatchTable* pTable = tableInstanceMap2[gpu];
-
-    printf("At start of multi2 layer vkEnumerateLayers()\n");
-    VkResult result = pTable->EnumerateLayers(gpu, maxStringSize, pLayerCount, pOutLayers, pReserved);
-    printf("Completed multi2 layer vkEnumerateLayers()\n");
-    return result;
-}
-
 VK_LAYER_EXPORT void * VKAPI multi2GetDeviceProcAddr(VkDevice device, const char* pName)
 {
     VkBaseLayerObject* devw = (VkBaseLayerObject *) device;
@@ -375,8 +344,6 @@
         return (void *) multi2DestroyInstance;
     if (!strcmp("vkCreateDevice", pName))
         return (void *) multi2CreateDevice;
-    else if (!strcmp("vkEnumerateLayers", pName))
-        return (void *) multi2EnumerateLayers;
     else if (!strcmp("GetGlobalExtensionInfo", pName))
         return (void*) vkGetGlobalExtensionInfo;
     else {
@@ -408,20 +375,32 @@
 };
 
 #define MULTI_LAYER_EXT_ARRAY_SIZE 2
-static const struct extProps multiExts[MULTI_LAYER_EXT_ARRAY_SIZE] = {
-    // TODO what is the version?
-    0x10, "multi1",
-    0x10, "multi2",
+static const VkExtensionProperties multiExts[MULTI_LAYER_EXT_ARRAY_SIZE] = {
+    {
+        VK_STRUCTURE_TYPE_EXTENSION_PROPERTIES,
+        "multi1",
+        0x10,
+        "Sample layer: multi",
+//        0,
+//        NULL,
+    },
+    {
+        VK_STRUCTURE_TYPE_EXTENSION_PROPERTIES,
+        "multi2",
+        0x10,
+        "Sample layer: multi",
+//        0,
+//        NULL,
+    }
 };
 
 VK_LAYER_EXPORT VkResult VKAPI vkGetGlobalExtensionInfo(
-                                               VkExtensionInfoType infoType,
-                                               uint32_t extensionIndex,
-                                               size_t*  pDataSize,
-                                               void*    pData)
+        VkExtensionInfoType infoType,
+        uint32_t extensionIndex,
+        size_t*  pDataSize,
+        void*    pData)
 {
     /* This entrypoint is NOT going to init it's own dispatch table since loader calls here early */
-    VkExtensionProperties *ext_props;
     uint32_t *count;
 
     if (pDataSize == NULL)
@@ -441,11 +420,7 @@
                 return VK_SUCCESS;
             if (extensionIndex >= MULTI_LAYER_EXT_ARRAY_SIZE)
                 return VK_ERROR_INVALID_VALUE;
-            ext_props = (VkExtensionProperties *) pData;
-            ext_props->version = multiExts[extensionIndex].version;
-            strncpy(ext_props->extName, multiExts[extensionIndex].name,
-                                        VK_MAX_EXTENSION_NAME);
-            ext_props->extName[VK_MAX_EXTENSION_NAME - 1] = '\0';
+            memcpy((VkExtensionProperties *) pData, &multiExts[extensionIndex], sizeof(VkExtensionProperties));
             break;
         default:
             return VK_ERROR_INVALID_VALUE;
diff --git a/layers/object_track.h b/layers/object_track.h
index 6c0378a..da48171 100644
--- a/layers/object_track.h
+++ b/layers/object_track.h
@@ -22,7 +22,9 @@
  * DEALINGS IN THE SOFTWARE.
  */
 
+#include "vulkan.h"
 #include "vkLayer.h"
+#include "vk_enum_string_helper.h"
 // Object Tracker ERROR codes
 typedef enum _OBJECT_TRACK_ERROR
 {
@@ -58,98 +60,6 @@
     OBJSTATUS_GPU_MEM_MAPPED                    = 0x00000020, // Memory object is currently mapped
 } ObjectStatusFlagBits;
 
-static const char* string_VkObjectType(VkObjectType type) {
-    switch (type)
-    {
-        case VK_OBJECT_TYPE_DEVICE:
-            return "DEVICE";
-        case VK_OBJECT_TYPE_PIPELINE:
-            return "PIPELINE";
-        case VK_OBJECT_TYPE_FENCE:
-            return "FENCE";
-        case VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT:
-            return "DESCRIPTOR_SET_LAYOUT";
-        case VK_OBJECT_TYPE_DEVICE_MEMORY:
-            return "DEVICE_MEMORY";
-        case VK_OBJECT_TYPE_PIPELINE_LAYOUT:
-            return "PIPELINE_LAYOUT";
-        case VK_OBJECT_TYPE_QUEUE:
-            return "QUEUE";
-        case VK_OBJECT_TYPE_IMAGE:
-            return "IMAGE";
-        case VK_OBJECT_TYPE_COMMAND_BUFFER:
-            return "CMD_BUFFER";
-        case VK_OBJECT_TYPE_SEMAPHORE:
-            return "SEMAPHORE";
-        case VK_OBJECT_TYPE_FRAMEBUFFER:
-            return "FRAMEBUFFER";
-        case VK_OBJECT_TYPE_SAMPLER:
-            return "SAMPLER";
-        case VK_OBJECT_TYPE_COLOR_ATTACHMENT_VIEW:
-            return "COLOR_ATTACHMENT_VIEW";
-        case VK_OBJECT_TYPE_BUFFER_VIEW:
-            return "BUFFER_VIEW";
-        case VK_OBJECT_TYPE_DESCRIPTOR_SET:
-            return "DESCRIPTOR_SET";
-        case VK_OBJECT_TYPE_PHYSICAL_DEVICE:
-            return "PHYSICAL_DEVICE";
-        case VK_OBJECT_TYPE_IMAGE_VIEW:
-            return "IMAGE_VIEW";
-        case VK_OBJECT_TYPE_BUFFER:
-            return "BUFFER";
-        case VK_OBJECT_TYPE_DYNAMIC_RS_STATE:
-            return "DYNAMIC_RS_STATE_OBJECT";
-        case VK_OBJECT_TYPE_EVENT:
-            return "EVENT";
-        case VK_OBJECT_TYPE_DEPTH_STENCIL_VIEW:
-            return "DEPTH_STENCIL_VIEW";
-        case VK_OBJECT_TYPE_SHADER:
-            return "SHADER";
-        case VK_OBJECT_TYPE_DYNAMIC_DS_STATE:
-            return "DYNAMIC_DS_STATE_OBJECT";
-        case VK_OBJECT_TYPE_DYNAMIC_VP_STATE:
-            return "DYNAMIC_VP_STATE_OBJECT";
-        case VK_OBJECT_TYPE_DYNAMIC_CB_STATE:
-            return "DYNAMIC_CB_STATE_OBJECT";
-        case VK_OBJECT_TYPE_INSTANCE:
-            return "INSTANCE";
-        case VK_OBJECT_TYPE_RENDER_PASS:
-            return "RENDER_PASS";
-        case VK_OBJECT_TYPE_QUERY_POOL:
-            return "QUERY_POOL";
-        case VK_OBJECT_TYPE_DESCRIPTOR_POOL:
-            return "DESCRIPTOR_POOL";
-        default:
-            return NULL;
-    }
-}
-
-static const char* string_VK_OBJECT_TYPE_WSI(uint32_t type) {
-    switch (type)
-    {
-        case VK_OBJECT_TYPE_DISPLAY_WSI:
-            return "DISPLAY_WSI";
-        case VK_OBJECT_TYPE_SWAP_CHAIN_WSI:
-            return "SWAP_CHAIN_WSI";
-        default:
-            return NULL;
-    }
-}
-
-static const char* string_from_vulkan_object_type(uint32_t type) {
-    const char *vkEnumString =  string_VkObjectType((VkObjectType)type);
-    if (vkEnumString != NULL) {
-        return vkEnumString;
-    }
-    else {
-        vkEnumString = string_VK_OBJECT_TYPE_WSI(type);
-        if (vkEnumString != NULL) {
-            return vkEnumString;
-        }
-    }
-    return "Unknown";
-}
-
 typedef struct _OBJTRACK_NODE {
     VkObject          vkObj;
     VkObjectType      objType;
@@ -157,13 +67,13 @@
 } OBJTRACK_NODE;
 
 // prototype for extension functions
-uint64_t objTrackGetObjectsCount(void);
-VkResult objTrackGetObjects(uint64_t objCount, OBJTRACK_NODE* pObjNodeArray);
+uint64_t objTrackGetObjectCount(VkObjectType type);
+VkResult objTrackGetObjects(VkObjectType type, uint64_t objCount, OBJTRACK_NODE* pObjNodeArray);
 uint64_t objTrackGetObjectsOfTypeCount(VkObjectType type);
 VkResult objTrackGetObjectsOfType(VkObjectType type, uint64_t objCount, OBJTRACK_NODE* pObjNodeArray);
 
 // Func ptr typedefs
-typedef uint64_t (*OBJ_TRACK_GET_OBJECTS_COUNT)(void);
-typedef VkResult (*OBJ_TRACK_GET_OBJECTS)(uint64_t, OBJTRACK_NODE*);
+typedef uint64_t (*OBJ_TRACK_GET_OBJECT_COUNT)(VkObjectType);
+typedef VkResult (*OBJ_TRACK_GET_OBJECTS)(VkObjectType, uint64_t, OBJTRACK_NODE*);
 typedef uint64_t (*OBJ_TRACK_GET_OBJECTS_OF_TYPE_COUNT)(VkObjectType);
 typedef VkResult (*OBJ_TRACK_GET_OBJECTS_OF_TYPE)(VkObjectType, uint64_t, OBJTRACK_NODE*);
diff --git a/layers/param_checker.cpp b/layers/param_checker.cpp
index 8fdcb8d..3f5af68 100644
--- a/layers/param_checker.cpp
+++ b/layers/param_checker.cpp
@@ -71,7 +71,7 @@
 
     const char *strOpt;
     // initialize ParamChecker options
-    getLayerOptionEnum("ParamCheckerReportLevel", (uint32_t *) &g_reportingLevel);
+    getLayerOptionEnum("ParamCheckerReportLevel", (uint32_t *) &g_reportFlags);
     g_actionIsDefault = getLayerOptionEnum("ParamCheckerDebugAction", (uint32_t *) &g_debugAction);
 
     if (g_debugAction & VK_DBG_LAYER_ACTION_LOG_MSG)
@@ -93,7 +93,7 @@
     {
         char const str[] = "vkCreateInstance parameter, VkApplicationInfo* pAppInfo, is "\
             "nullptr (precondition).";
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         return;
     }
 
@@ -101,7 +101,7 @@
     {
         char const str[] = "vkCreateInstance parameter, VK_STRUCTURE_TYPE_APPLICATION_INFO "\
             "pAppInfo->sType, is not VK_STRUCTURE_TYPE_APPLICATION_INFO (precondition).";
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         return;
     }
 
@@ -115,27 +115,29 @@
         {
             char const str[] = "vkCreateInstance parameter, VkAllocCallbacks* pAllocCb, "\
                 "contains an invalid value (precondition).";
-            layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+            layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
             return;
         }
     }
 }
 
-void PostCreateInstance(VkResult result, VkInstance* pInstance)
+void PostCreateInstance(VkResult result, const VkInstanceCreateInfo *pCreateInfo, VkInstance* pInstance)
 {
     if(result != VK_SUCCESS)
     {
         // TODO: Spit out VkResult value.
         char const str[] = "vkCreateInstance failed (postcondition).";
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         return;
     }
 
+    enable_debug_report(pCreateInfo->extensionCount, pCreateInfo->pEnabledExtensions);
+
     if(pInstance == nullptr)
     {
         char const str[] = "vkCreateInstance parameter, VkInstance* pInstance, is nullptr "\
             "(postcondition).";
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         return;
     }
 }
@@ -144,7 +146,7 @@
 {
     PreCreateInstance(pCreateInfo->pAppInfo, pCreateInfo->pAllocCb);
     VkResult result = nextInstanceTable.CreateInstance(pCreateInfo, pInstance);
-    PostCreateInstance(result, pInstance);
+    PostCreateInstance(result, pCreateInfo, pInstance);
     return result;
 }
 
@@ -160,7 +162,7 @@
     char str[1024];
     if (!validate_VkPhysicalDeviceInfoType(infoType)) {
         sprintf(str, "Parameter infoType to function GetPhysicalDeviceInfo has invalid value of %i.", (int)infoType);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     VkResult result = nextInstanceTable.GetPhysicalDeviceInfo(gpu, infoType, pDataSize, pData);
     return result;
@@ -172,7 +174,7 @@
     {
         char const str[] = "vkCreateDevice parameter, VkPhysicalDevice gpu, is nullptr "\
             "(precondition).";
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         return;
     }
 
@@ -180,7 +182,7 @@
     {
         char const str[] = "vkCreateDevice parameter, VkDeviceCreateInfo* pCreateInfo, is "\
             "nullptr (precondition).";
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         return;
     }
 
@@ -188,7 +190,7 @@
     {
         char const str[] = "vkCreateDevice parameter, VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO "\
             "pCreateInfo->sType, is not VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO (precondition).";
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         return;
     }
 
@@ -196,7 +198,7 @@
     {
         char const str[] = "vkCreateDevice parameter, uint32_t pCreateInfo->queueRecordCount, is "\
             "zero (precondition).";
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         return;
     }
 
@@ -204,7 +206,7 @@
     {
         char const str[] = "vkCreateDevice parameter, VkDeviceQueueCreateInfo* pCreateInfo->pRequestedQueues, is "\
             "nullptr (precondition).";
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         return;
     }
 
@@ -215,27 +217,29 @@
             std::stringstream ss;
             ss << "vkCreateDevice parameter, VkDeviceQueueCreateInfo pCreateInfo->pRequestedQueues[" << i <<
                 "], is invalid (precondition).";
-            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", ss.str().c_str());
+            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", ss.str().c_str());
             continue;
         }
     }
 
 }
 
-void PostCreateDevice(VkResult result, VkDevice* pDevice)
+void PostCreateDevice(VkResult result, const VkDeviceCreateInfo *pCreateInfo, VkDevice* pDevice)
 {
     if(result != VK_SUCCESS)
     {
         // TODO: Spit out VkResult value.
         char const str[] = "vkCreateDevice failed (postcondition).";
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         return;
     }
 
+    enable_debug_report(pCreateInfo->extensionCount, pCreateInfo->pEnabledExtensions);
+
     if(pDevice == nullptr)
     {
         char const str[] = "vkCreateDevice parameter, VkDevice* pDevice, is nullptr (postcondition).";
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         return;
     }
 }
@@ -244,7 +248,7 @@
 {
     PreCreateDevice(gpu, pCreateInfo);
     VkResult result = nextInstanceTable.CreateDevice(gpu, pCreateInfo, pDevice);
-    PostCreateDevice(result, pDevice);
+    PostCreateDevice(result, pCreateInfo, pDevice);
     return result;
 }
 
@@ -255,26 +259,23 @@
     return result;
 }
 
-struct extProps {
-    uint32_t version;
-    const char * const name;
-};
-
-#define PARAM_CHECKER_LAYER_EXT_ARRAY_SIZE 2
-static const struct extProps pcExts[PARAM_CHECKER_LAYER_EXT_ARRAY_SIZE] = {
-    // TODO what is the version?
-    0x10, "ParamChecker",
-    0x10, "Validation",
+#define PARAM_CHECKER_LAYER_EXT_ARRAY_SIZE 1
+static const VkExtensionProperties pcExts[PARAM_CHECKER_LAYER_EXT_ARRAY_SIZE] = {
+    {
+        VK_STRUCTURE_TYPE_EXTENSION_PROPERTIES,
+        "ParamChecker",
+        0x10,
+        "Sample layer: ParamChecker",
+    }
 };
 
 VK_LAYER_EXPORT VkResult VKAPI vkGetGlobalExtensionInfo(
-                                               VkExtensionInfoType infoType,
-                                               uint32_t extensionIndex,
-                                               size_t*  pDataSize,
-                                               void*    pData)
+        VkExtensionInfoType infoType,
+        uint32_t extensionIndex,
+        size_t*  pDataSize,
+        void*    pData)
 {
     /* This entrypoint is NOT going to init it's own dispatch table since loader calls here early */
-    VkExtensionProperties *ext_props;
     uint32_t *count;
 
     if (pDataSize == NULL)
@@ -294,11 +295,7 @@
                 return VK_SUCCESS;
             if (extensionIndex >= PARAM_CHECKER_LAYER_EXT_ARRAY_SIZE)
                 return VK_ERROR_INVALID_VALUE;
-            ext_props = (VkExtensionProperties *) pData;
-            ext_props->version = pcExts[extensionIndex].version;
-            strncpy(ext_props->extName, pcExts[extensionIndex].name,
-                                        VK_MAX_EXTENSION_NAME);
-            ext_props->extName[VK_MAX_EXTENSION_NAME - 1] = '\0';
+            memcpy((VkExtensionProperties *) pData, &pcExts[extensionIndex], sizeof(VkExtensionProperties));
             break;
         default:
             return VK_ERROR_INVALID_VALUE;
@@ -318,30 +315,6 @@
     return result;
 }
 
-VK_LAYER_EXPORT VkResult VKAPI vkEnumerateLayers(VkPhysicalDevice gpu, size_t maxStringSize, size_t* pLayerCount, char* const* pOutLayers, void* pReserved)
-{
-    char str[1024];
-    if (gpu != NULL) {
-        sprintf(str, "At start of layered EnumerateLayers\n");
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, nullptr, 0, 0, "PARAMCHECK", str);
-        pCurObj = (VkBaseLayerObject *) gpu;
-        loader_platform_thread_once(&initOnce, initParamChecker);
-        loader_platform_thread_once(&tabDeviceOnce, initDeviceTable);
-        VkResult result = nextInstanceTable.EnumerateLayers(gpu, maxStringSize, pLayerCount, pOutLayers, pReserved);
-        sprintf(str, "Completed layered EnumerateLayers\n");
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, nullptr, 0, 0, "PARAMCHECK", str);
-        fflush(stdout);
-        return result;
-    } else {
-        if (pLayerCount == NULL || pOutLayers == NULL || pOutLayers[0] == NULL)
-            return VK_ERROR_INVALID_POINTER;
-        // This layer compatible with all GPUs
-        *pLayerCount = 1;
-        strncpy(pOutLayers[0], "ParamChecker", maxStringSize);
-        return VK_SUCCESS;
-    }
-}
-
 VK_LAYER_EXPORT VkResult VKAPI vkGetDeviceQueue(VkDevice device, uint32_t queueNodeIndex, uint32_t queueIndex, VkQueue* pQueue)
 {
 
@@ -374,10 +347,10 @@
     char str[1024];
     if (!pAllocInfo) {
         sprintf(str, "Struct ptr parameter pAllocInfo to function AllocMemory is NULL.");
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     } else if (!vk_validate_vkmemoryallocinfo(pAllocInfo)) {
         sprintf(str, "Parameter pAllocInfo to function AllocMemory contains an invalid value.");
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     VkResult result = nextTable.AllocMemory(device, pAllocInfo, pMem);
     return result;
@@ -395,7 +368,7 @@
     char str[1024];
     if (!validate_VkMemoryPriority(priority)) {
         sprintf(str, "Parameter priority to function SetMemoryPriority has invalid value of %i.", (int)priority);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     VkResult result = nextTable.SetMemoryPriority(device, mem, priority);
     return result;
@@ -454,11 +427,11 @@
     char str[1024];
     if (!pOpenInfo) {
         sprintf(str, "Struct ptr parameter pOpenInfo to function OpenSharedMemory is NULL.");
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     else if (!vk_validate_vkmemoryopeninfo(pOpenInfo)) {
         sprintf(str, "Parameter pOpenInfo to function OpenSharedMemory contains an invalid value.");
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     VkResult result = nextTable.OpenSharedMemory(device, pOpenInfo, pMem);
     return result;
@@ -469,11 +442,11 @@
     char str[1024];
     if (!pOpenInfo) {
         sprintf(str, "Struct ptr parameter pOpenInfo to function OpenSharedSemaphore is NULL.");
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     else if (!vk_validate_vksemaphoreopeninfo(pOpenInfo)) {
         sprintf(str, "Parameter pOpenInfo to function OpenSharedSemaphore contains an invalid value.");
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     VkResult result = nextTable.OpenSharedSemaphore(device, pOpenInfo, pSemaphore);
     return result;
@@ -484,11 +457,11 @@
     char str[1024];
     if (!pOpenInfo) {
         sprintf(str, "Struct ptr parameter pOpenInfo to function OpenPeerMemory is NULL.");
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     else if (!vk_validate_vkpeermemoryopeninfo(pOpenInfo)) {
         sprintf(str, "Parameter pOpenInfo to function OpenPeerMemory contains an invalid value.");
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     VkResult result = nextTable.OpenPeerMemory(device, pOpenInfo, pMem);
     return result;
@@ -499,11 +472,11 @@
     char str[1024];
     if (!pOpenInfo) {
         sprintf(str, "Struct ptr parameter pOpenInfo to function OpenPeerImage is NULL.");
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     else if (!vk_validate_vkpeerimageopeninfo(pOpenInfo)) {
         sprintf(str, "Parameter pOpenInfo to function OpenPeerImage contains an invalid value.");
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     VkResult result = nextTable.OpenPeerImage(device, pOpenInfo, pImage, pMem);
     return result;
@@ -511,7 +484,6 @@
 
 VK_LAYER_EXPORT VkResult VKAPI vkDestroyObject(VkDevice device, VkObjectType objType, VkObject object)
 {
-
     VkResult result = nextTable.DestroyObject(device, objType, object);
     return result;
 }
@@ -521,7 +493,7 @@
     char str[1024];
     if (!validate_VkObjectInfoType(infoType)) {
         sprintf(str, "Parameter infoType to function GetObjectInfo has invalid value of %i.", (int)infoType);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     VkResult result = nextTable.GetObjectInfo(device, objType, object, infoType, pDataSize, pData);
     return result;
@@ -546,11 +518,11 @@
     char str[1024];
     if (!pBindInfo) {
         sprintf(str, "Struct ptr parameter pBindInfo to function QueueBindSparseImageMemory is NULL.");
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     else if (!vk_validate_vkimagememorybindinfo(pBindInfo)) {
         sprintf(str, "Parameter pBindInfo to function BindImageMemoryRange contains an invalid value.");
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     VkResult result = nextTable.QueueBindSparseImageMemory(queue, image, pBindInfo, mem, memOffset);
     return result;
@@ -561,11 +533,11 @@
     char str[1024];
     if (!pCreateInfo) {
         sprintf(str, "Struct ptr parameter pCreateInfo to function CreateFence is NULL.");
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     else if (!vk_validate_vkfencecreateinfo(pCreateInfo)) {
         sprintf(str, "Parameter pCreateInfo to function CreateFence contains an invalid value.");
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     VkResult result = nextTable.CreateFence(device, pCreateInfo, pFence);
     return result;
@@ -597,11 +569,11 @@
     char str[1024];
     if (!pCreateInfo) {
         sprintf(str, "Struct ptr parameter pCreateInfo to function CreateSemaphore is NULL.");
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     else if (!vk_validate_vksemaphorecreateinfo(pCreateInfo)) {
         sprintf(str, "Parameter pCreateInfo to function CreateSemaphore contains an invalid value.");
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     VkResult result = nextTable.CreateSemaphore(device, pCreateInfo, pSemaphore);
     return result;
@@ -626,11 +598,11 @@
     char str[1024];
     if (!pCreateInfo) {
         sprintf(str, "Struct ptr parameter pCreateInfo to function CreateEvent is NULL.");
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     else if (!vk_validate_vkeventcreateinfo(pCreateInfo)) {
         sprintf(str, "Parameter pCreateInfo to function CreateEvent contains an invalid value.");
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     VkResult result = nextTable.CreateEvent(device, pCreateInfo, pEvent);
     return result;
@@ -662,11 +634,11 @@
     char str[1024];
     if (!pCreateInfo) {
         sprintf(str, "Struct ptr parameter pCreateInfo to function CreateQueryPool is NULL.");
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     else if (!vk_validate_vkquerypoolcreateinfo(pCreateInfo)) {
         sprintf(str, "Parameter pCreateInfo to function CreateQueryPool contains an invalid value.");
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     VkResult result = nextTable.CreateQueryPool(device, pCreateInfo, pQueryPool);
     return result;
@@ -684,11 +656,11 @@
     char str[1024];
     if (!validate_VkFormat(format)) {
         sprintf(str, "Parameter format to function GetFormatInfo has invalid value of %i.", (int)format);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     if (!validate_VkFormatInfoType(infoType)) {
         sprintf(str, "Parameter infoType to function GetFormatInfo has invalid value of %i.", (int)infoType);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     VkResult result = nextTable.GetFormatInfo(device, format, infoType, pDataSize, pData);
     return result;
@@ -699,11 +671,11 @@
     char str[1024];
     if (!pCreateInfo) {
         sprintf(str, "Struct ptr parameter pCreateInfo to function CreateBuffer is NULL.");
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     else if (!vk_validate_vkbuffercreateinfo(pCreateInfo)) {
         sprintf(str, "Parameter pCreateInfo to function CreateBuffer contains an invalid value.");
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     VkResult result = nextTable.CreateBuffer(device, pCreateInfo, pBuffer);
     return result;
@@ -714,11 +686,11 @@
     char str[1024];
     if (!pCreateInfo) {
         sprintf(str, "Struct ptr parameter pCreateInfo to function CreateBufferView is NULL.");
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     else if (!vk_validate_vkbufferviewcreateinfo(pCreateInfo)) {
         sprintf(str, "Parameter pCreateInfo to function CreateBufferView contains an invalid value.");
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     VkResult result = nextTable.CreateBufferView(device, pCreateInfo, pView);
     return result;
@@ -730,7 +702,7 @@
     {
         char const str[] = "vkCreateImage parameter, VkImageCreateInfo* pCreateInfo, is "\
             "nullptr (precondition).";
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         return;
     }
 
@@ -738,7 +710,7 @@
     {
         char const str[] = "vkCreateImage parameter, VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO "\
             "pCreateInfo->sType, is not VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO (precondition).";
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         return;
     }
 
@@ -746,7 +718,7 @@
     {
         char const str[] = "vkCreateImage parameter, VkImageType pCreateInfo->imageType, is "\
             "unrecognized (precondition).";
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         return;
     }
 
@@ -754,7 +726,7 @@
     {
         char const str[] = "vkCreateImage parameter, VkFormat pCreateInfo->format, is "\
             "unrecognized (precondition).";
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         return;
     }
 
@@ -766,7 +738,7 @@
     {
         char const str[] = "vkCreateImage parameter, VkFormat pCreateInfo->format, cannot be "\
             "validated (precondition).";
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         return;
     }
 
@@ -774,7 +746,7 @@
     {
         char const str[] = "vkCreateImage parameter, VkFormat pCreateInfo->format, contains "\
             "unsupported format (precondition).";
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         return;
     }
 
@@ -783,7 +755,7 @@
     {
         char const str[] = "vkCreateImage parameter, VkExtent3D pCreateInfo->extent, is invalid "\
             "(precondition).";
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         return;
     }
 
@@ -791,7 +763,7 @@
     {
         char const str[] = "vkCreateImage parameter, VkImageTiling pCreateInfo->tiling, is "\
             "unrecoginized (precondition).";
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         return;
     }
 }
@@ -802,14 +774,14 @@
     {
         // TODO: Spit out VkResult value.
         char const str[] = "vkCreateImage failed (postcondition).";
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         return;
     }
 
     if(pImage == nullptr)
     {
         char const str[] = "vkCreateImage parameter, VkImage* pImage, is nullptr (postcondition).";
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         return;
     }
 }
@@ -827,14 +799,14 @@
     char str[1024];
     if (!pSubresource) {
         sprintf(str, "Struct ptr parameter pSubresource to function GetImageSubresourceInfo is NULL.");
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     } else if (!vk_validate_vkimagesubresource(pSubresource)) {
         sprintf(str, "Parameter pSubresource to function GetImageSubresourceInfo contains an invalid value.");
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     if (!validate_VkSubresourceInfoType(infoType)) {
         sprintf(str, "Parameter infoType to function GetImageSubresourceInfo has invalid value of %i.", (int)infoType);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     VkResult result = nextTable.GetImageSubresourceInfo(device, image, pSubresource, infoType, pDataSize, pData);
     return result;
@@ -845,11 +817,11 @@
     char str[1024];
     if (!pCreateInfo) {
         sprintf(str, "Struct ptr parameter pCreateInfo to function CreateImageView is NULL.");
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     else if (!vk_validate_vkimageviewcreateinfo(pCreateInfo)) {
         sprintf(str, "Parameter pCreateInfo to function CreateImageView contains an invalid value.");
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     VkResult result = nextTable.CreateImageView(device, pCreateInfo, pView);
     return result;
@@ -860,11 +832,11 @@
     char str[1024];
     if (!pCreateInfo) {
         sprintf(str, "Struct ptr parameter pCreateInfo to function CreateColorAttachmentView is NULL.");
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     else if (!vk_validate_vkcolorattachmentviewcreateinfo(pCreateInfo)) {
         sprintf(str, "Parameter pCreateInfo to function CreateColorAttachmentView contains an invalid value.");
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     VkResult result = nextTable.CreateColorAttachmentView(device, pCreateInfo, pView);
     return result;
@@ -875,11 +847,11 @@
     char str[1024];
     if (!pCreateInfo) {
         sprintf(str, "Struct ptr parameter pCreateInfo to function CreateDepthStencilView is NULL.");
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     else if (!vk_validate_vkdepthstencilviewcreateinfo(pCreateInfo)) {
         sprintf(str, "Parameter pCreateInfo to function CreateDepthStencilView contains an invalid value.");
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     VkResult result = nextTable.CreateDepthStencilView(device, pCreateInfo, pView);
     return result;
@@ -890,11 +862,11 @@
     char str[1024];
     if (!pCreateInfo) {
         sprintf(str, "Struct ptr parameter pCreateInfo to function CreateShader is NULL.");
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     else if (!vk_validate_vkshadercreateinfo(pCreateInfo)) {
         sprintf(str, "Parameter pCreateInfo to function CreateShader contains an invalid value.");
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     VkResult result = nextTable.CreateShader(device, pCreateInfo, pShader);
     return result;
@@ -905,11 +877,11 @@
     char str[1024];
     if (!pCreateInfo) {
         sprintf(str, "Struct ptr parameter pCreateInfo to function CreateGraphicsPipeline is NULL.");
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     else if (!vk_validate_vkgraphicspipelinecreateinfo(pCreateInfo)) {
         sprintf(str, "Parameter pCreateInfo to function CreateGraphicsPipeline contains an invalid value.");
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     VkResult result = nextTable.CreateGraphicsPipeline(device, pCreateInfo, pPipeline);
     return result;
@@ -920,11 +892,11 @@
     char str[1024];
     if (!pCreateInfo) {
         sprintf(str, "Struct ptr parameter pCreateInfo to function CreateGraphicsPipelineDerivative is NULL.");
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     else if (!vk_validate_vkgraphicspipelinecreateinfo(pCreateInfo)) {
         sprintf(str, "Parameter pCreateInfo to function CreateGraphicsPipelineDerivative contains an invalid value.");
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     VkResult result = nextTable.CreateGraphicsPipelineDerivative(device, pCreateInfo, basePipeline, pPipeline);
     return result;
@@ -935,11 +907,11 @@
     char str[1024];
     if (!pCreateInfo) {
         sprintf(str, "Struct ptr parameter pCreateInfo to function CreateComputePipeline is NULL.");
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     else if (!vk_validate_vkcomputepipelinecreateinfo(pCreateInfo)) {
         sprintf(str, "Parameter pCreateInfo to function CreateComputePipeline contains an invalid value.");
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     VkResult result = nextTable.CreateComputePipeline(device, pCreateInfo, pPipeline);
     return result;
@@ -971,11 +943,11 @@
     char str[1024];
     if (!pCreateInfo) {
         sprintf(str, "Struct ptr parameter pCreateInfo to function CreateSampler is NULL.");
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     else if (!vk_validate_vksamplercreateinfo(pCreateInfo)) {
         sprintf(str, "Parameter pCreateInfo to function CreateSampler contains an invalid value.");
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     VkResult result = nextTable.CreateSampler(device, pCreateInfo, pSampler);
     return result;
@@ -986,11 +958,11 @@
     char str[1024];
     if (!pCreateInfo) {
         sprintf(str, "Struct ptr parameter pCreateInfo to function CreateDescriptorSetLayout is NULL.");
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     else if (!vk_validate_vkdescriptorsetlayoutcreateinfo(pCreateInfo)) {
         sprintf(str, "Parameter pCreateInfo to function CreateDescriptorSetLayout contains an invalid value.");
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     VkResult result = nextTable.CreateDescriptorSetLayout(device, pCreateInfo, pSetLayout);
     return result;
@@ -1007,15 +979,15 @@
     char str[1024];
     if (!validate_VkDescriptorPoolUsage(poolUsage)) {
         sprintf(str, "Parameter poolUsage to function CreateDescriptorPool has invalid value of %i.", (int)poolUsage);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     if (!pCreateInfo) {
         sprintf(str, "Struct ptr parameter pCreateInfo to function CreateDescriptorPool is NULL.");
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     else if (!vk_validate_vkdescriptorpoolcreateinfo(pCreateInfo)) {
         sprintf(str, "Parameter pCreateInfo to function CreateDescriptorPool contains an invalid value.");
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     VkResult result = nextTable.CreateDescriptorPool(device, poolUsage, maxSets, pCreateInfo, pDescriptorPool);
     return result;
@@ -1033,7 +1005,7 @@
     char str[1024];
     if (!validate_VkDescriptorSetUsage(setUsage)) {
         sprintf(str, "Parameter setUsage to function AllocDescriptorSets has invalid value of %i.", (int)setUsage);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     VkResult result = nextTable.AllocDescriptorSets(device, descriptorPool, setUsage, count, pSetLayouts, pDescriptorSets, pCount);
     return result;
@@ -1056,11 +1028,11 @@
     char str[1024];
     if (!pCreateInfo) {
         sprintf(str, "Struct ptr parameter pCreateInfo to function CreateDynamicViewportState is NULL.");
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     else if (!vk_validate_vkdynamicvpstatecreateinfo(pCreateInfo)) {
         sprintf(str, "Parameter pCreateInfo to function CreateDynamicViewportState contains an invalid value.");
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     VkResult result = nextTable.CreateDynamicViewportState(device, pCreateInfo, pState);
     return result;
@@ -1071,11 +1043,11 @@
     char str[1024];
     if (!pCreateInfo) {
         sprintf(str, "Struct ptr parameter pCreateInfo to function CreateDynamicRasterState is NULL.");
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     else if (!vk_validate_vkdynamicrsstatecreateinfo(pCreateInfo)) {
         sprintf(str, "Parameter pCreateInfo to function CreateDynamicRasterState contains an invalid value.");
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     VkResult result = nextTable.CreateDynamicRasterState(device, pCreateInfo, pState);
     return result;
@@ -1086,11 +1058,11 @@
     char str[1024];
     if (!pCreateInfo) {
         sprintf(str, "Struct ptr parameter pCreateInfo to function CreateDynamicColorBlendState is NULL.");
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     else if (!vk_validate_vkdynamiccbstatecreateinfo(pCreateInfo)) {
         sprintf(str, "Parameter pCreateInfo to function CreateDynamicColorBlendState contains an invalid value.");
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     VkResult result = nextTable.CreateDynamicColorBlendState(device, pCreateInfo, pState);
     return result;
@@ -1101,11 +1073,11 @@
     char str[1024];
     if (!pCreateInfo) {
         sprintf(str, "Struct ptr parameter pCreateInfo to function CreateDynamicDepthStencilState is NULL.");
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     else if (!vk_validate_vkdynamicdsstatecreateinfo(pCreateInfo)) {
         sprintf(str, "Parameter pCreateInfo to function CreateDynamicDepthStencilState contains an invalid value.");
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     VkResult result = nextTable.CreateDynamicDepthStencilState(device, pCreateInfo, pState);
     return result;
@@ -1117,7 +1089,7 @@
     {
         char const str[] = "vkCreateCommandBuffer parameter, VkDevice device, is "\
             "nullptr (precondition).";
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         return;
     }
 
@@ -1125,7 +1097,7 @@
     {
         char const str[] = "vkCreateCommandBuffer parameter, VkCmdBufferCreateInfo* pCreateInfo, is "\
             "nullptr (precondition).";
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         return;
     }
 
@@ -1133,7 +1105,7 @@
     {
         char const str[] = "vkCreateCommandBuffer parameter, VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO "\
             "pCreateInfo->sType, is not VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO (precondition).";
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         return;
     }
 }
@@ -1144,14 +1116,14 @@
     {
         // TODO: Spit out VkResult value.
         char const str[] = "vkCreateCommandBuffer failed (postcondition).";
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         return;
     }
 
     if(pCmdBuffer == nullptr)
     {
         char const str[] = "vkCreateCommandBuffer parameter, VkCmdBuffer* pCmdBuffer, is nullptr (postcondition).";
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         return;
     }
 }
@@ -1170,11 +1142,11 @@
     char str[1024];
     if (!pBeginInfo) {
         sprintf(str, "Struct ptr parameter pBeginInfo to function BeginCommandBuffer is NULL.");
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     else if (!vk_validate_vkcmdbufferbegininfo(pBeginInfo)) {
         sprintf(str, "Parameter pBeginInfo to function BeginCommandBuffer contains an invalid value.");
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     VkResult result = nextTable.BeginCommandBuffer(cmdBuffer, pBeginInfo);
     return result;
@@ -1199,7 +1171,7 @@
     char str[1024];
     if (!validate_VkPipelineBindPoint(pipelineBindPoint)) {
         sprintf(str, "Parameter pipelineBindPoint to function CmdBindPipeline has invalid value of %i.", (int)pipelineBindPoint);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     nextTable.CmdBindPipeline(cmdBuffer, pipelineBindPoint, pipeline);
 }
@@ -1209,7 +1181,7 @@
     char str[1024];
     if (!validate_VkStateBindPoint(stateBindPoint)) {
         sprintf(str, "Parameter stateBindPoint to function CmdBindDynamicStateObject has invalid value of %i.", (int)stateBindPoint);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     nextTable.CmdBindDynamicStateObject(cmdBuffer, stateBindPoint, state);
 }
@@ -1219,7 +1191,7 @@
     char str[1024];
     if (!validate_VkPipelineBindPoint(pipelineBindPoint)) {
         sprintf(str, "Parameter pipelineBindPoint to function CmdBindDescriptorSets has invalid value of %i.", (int)pipelineBindPoint);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     nextTable.CmdBindDescriptorSets(cmdBuffer, pipelineBindPoint, firstSet, setCount, pDescriptorSets, dynamicOffsetCount, pDynamicOffsets);
 }
@@ -1239,7 +1211,7 @@
     char str[1024];
     if (!validate_VkIndexType(indexType)) {
         sprintf(str, "Parameter indexType to function CmdBindIndexBuffer has invalid value of %i.", (int)indexType);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     nextTable.CmdBindIndexBuffer(cmdBuffer, buffer, offset, indexType);
 }
@@ -1287,7 +1259,7 @@
     for (i = 0; i < regionCount; i++) {
         if (!vk_validate_vkbuffercopy(&pRegions[i])) {
             sprintf(str, "Parameter pRegions[%i] to function CmdCopyBuffer contains an invalid value.", i);
-            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         }
     }
     nextTable.CmdCopyBuffer(cmdBuffer, srcBuffer, destBuffer, regionCount, pRegions);
@@ -1298,17 +1270,17 @@
     char str[1024];
     if (!validate_VkImageLayout(srcImageLayout)) {
         sprintf(str, "Parameter srcImageLayout to function CmdCopyImage has invalid value of %i.", (int)srcImageLayout);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     if (!validate_VkImageLayout(destImageLayout)) {
         sprintf(str, "Parameter destImageLayout to function CmdCopyImage has invalid value of %i.", (int)destImageLayout);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     uint32_t i;
     for (i = 0; i < regionCount; i++) {
         if (!vk_validate_vkimagecopy(&pRegions[i])) {
             sprintf(str, "Parameter pRegions[%i] to function CmdCopyImage contains an invalid value.", i);
-            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         }
     }
     nextTable.CmdCopyImage(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
@@ -1319,17 +1291,17 @@
     char str[1024];
     if (!validate_VkImageLayout(srcImageLayout)) {
         sprintf(str, "Parameter srcImageLayout to function CmdBlitImage has invalid value of %i.", (int)srcImageLayout);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     if (!validate_VkImageLayout(destImageLayout)) {
         sprintf(str, "Parameter destImageLayout to function CmdBlitImage has invalid value of %i.", (int)destImageLayout);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     uint32_t i;
     for (i = 0; i < regionCount; i++) {
         if (!vk_validate_vkimageblit(&pRegions[i])) {
             sprintf(str, "Parameter pRegions[%i] to function CmdBlitImage contains an invalid value.", i);
-            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         }
     }
     //TODO:  Add additional check for limitation from header rev 96.
@@ -1343,13 +1315,13 @@
     char str[1024];
     if (!validate_VkImageLayout(destImageLayout)) {
         sprintf(str, "Parameter destImageLayout to function CmdCopyBufferToImage has invalid value of %i.", (int)destImageLayout);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     uint32_t i;
     for (i = 0; i < regionCount; i++) {
         if (!vk_validate_vkbufferimagecopy(&pRegions[i])) {
             sprintf(str, "Parameter pRegions[%i] to function CmdCopyBufferToImage contains an invalid value.", i);
-            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         }
     }
     nextTable.CmdCopyBufferToImage(cmdBuffer, srcBuffer, destImage, destImageLayout, regionCount, pRegions);
@@ -1360,13 +1332,13 @@
     char str[1024];
     if (!validate_VkImageLayout(srcImageLayout)) {
         sprintf(str, "Parameter srcImageLayout to function CmdCopyImageToBuffer has invalid value of %i.", (int)srcImageLayout);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     uint32_t i;
     for (i = 0; i < regionCount; i++) {
         if (!vk_validate_vkbufferimagecopy(&pRegions[i])) {
             sprintf(str, "Parameter pRegions[%i] to function CmdCopyImageToBuffer contains an invalid value.", i);
-            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         }
     }
     nextTable.CmdCopyImageToBuffer(cmdBuffer, srcImage, srcImageLayout, destBuffer, regionCount, pRegions);
@@ -1389,13 +1361,13 @@
     char str[1024];
     if (!validate_VkImageLayout(imageLayout)) {
         sprintf(str, "Parameter imageLayout to function CmdClearColorImage has invalid value of %i.", (int)imageLayout);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     uint32_t i;
     for (i = 0; i < rangeCount; i++) {
         if (!vk_validate_vkimagesubresourcerange(&pRanges[i])) {
             sprintf(str, "Parameter pRanges[%i] to function CmdClearColorImage contains an invalid value.", i);
-            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         }
     }
     nextTable.CmdClearColorImage(cmdBuffer, image, imageLayout, pColor, rangeCount, pRanges);
@@ -1406,13 +1378,13 @@
     char str[1024];
     if (!validate_VkImageLayout(imageLayout)) {
         sprintf(str, "Parameter imageLayout to function CmdClearDepthStencil has invalid value of %i.", (int)imageLayout);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     uint32_t i;
     for (i = 0; i < rangeCount; i++) {
         if (!vk_validate_vkimagesubresourcerange(&pRanges[i])) {
             sprintf(str, "Parameter pRanges[%i] to function CmdClearDepthStencil contains an invalid value.", i);
-            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         }
     }
     nextTable.CmdClearDepthStencil(cmdBuffer, image, imageLayout, depth, stencil, rangeCount, pRanges);
@@ -1423,17 +1395,17 @@
     char str[1024];
     if (!validate_VkImageLayout(srcImageLayout)) {
         sprintf(str, "Parameter srcImageLayout to function CmdResolveImage has invalid value of %i.", (int)srcImageLayout);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     if (!validate_VkImageLayout(destImageLayout)) {
         sprintf(str, "Parameter destImageLayout to function CmdResolveImage has invalid value of %i.", (int)destImageLayout);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     uint32_t i;
     for (i = 0; i < regionCount; i++) {
         if (!vk_validate_vkimageresolve(&pRegions[i])) {
             sprintf(str, "Parameter pRects[%i] to function CmdResolveImage contains an invalid value.", i);
-            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         }
     }
     nextTable.CmdResolveImage(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
@@ -1444,7 +1416,7 @@
     char str[1024];
     if (!validate_VkPipeEvent(pipeEvent)) {
         sprintf(str, "Parameter pipeEvent to function CmdSetEvent has invalid value of %i.", (int)pipeEvent);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     nextTable.CmdSetEvent(cmdBuffer, event, pipeEvent);
 }
@@ -1454,7 +1426,7 @@
     char str[1024];
     if (!validate_VkPipeEvent(pipeEvent)) {
         sprintf(str, "Parameter pipeEvent to function CmdResetEvent has invalid value of %i.", (int)pipeEvent);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     nextTable.CmdResetEvent(cmdBuffer, event, pipeEvent);
 }
@@ -1492,7 +1464,7 @@
     char str[1024];
     if (!validate_VkTimestampType(timestampType)) {
         sprintf(str, "Parameter timestampType to function CmdWriteTimestamp has invalid value of %i.", (int)timestampType);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     nextTable.CmdWriteTimestamp(cmdBuffer, timestampType, destBuffer, destOffset);
 }
@@ -1515,7 +1487,7 @@
     char str[1024];
     if (!validate_VkPipelineBindPoint(pipelineBindPoint)) {
         sprintf(str, "Parameter pipelineBindPoint to function CmdInitAtomicCounters has invalid value of %i.", (int)pipelineBindPoint);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     nextTable.CmdInitAtomicCounters(cmdBuffer, pipelineBindPoint, startCounter, counterCount, pData);
 }
@@ -1525,7 +1497,7 @@
     char str[1024];
     if (!validate_VkPipelineBindPoint(pipelineBindPoint)) {
         sprintf(str, "Parameter pipelineBindPoint to function CmdLoadAtomicCounters has invalid value of %i.", (int)pipelineBindPoint);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     nextTable.CmdLoadAtomicCounters(cmdBuffer, pipelineBindPoint, startCounter, counterCount, srcBuffer, srcOffset);
 }
@@ -1535,7 +1507,7 @@
     char str[1024];
     if (!validate_VkPipelineBindPoint(pipelineBindPoint)) {
         sprintf(str, "Parameter pipelineBindPoint to function CmdSaveAtomicCounters has invalid value of %i.", (int)pipelineBindPoint);
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     nextTable.CmdSaveAtomicCounters(cmdBuffer, pipelineBindPoint, startCounter, counterCount, destBuffer, destOffset);
 }
@@ -1545,11 +1517,11 @@
     char str[1024];
     if (!pCreateInfo) {
         sprintf(str, "Struct ptr parameter pCreateInfo to function CreateFramebuffer is NULL.");
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     else if (!vk_validate_vkframebuffercreateinfo(pCreateInfo)) {
         sprintf(str, "Parameter pCreateInfo to function CreateFramebuffer contains an invalid value.");
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     VkResult result = nextTable.CreateFramebuffer(device, pCreateInfo, pFramebuffer);
     return result;
@@ -1562,7 +1534,7 @@
     {
         char const str[] = "vkCreateRenderPass parameter, VkRenderPassCreateInfo* pCreateInfo, is "\
             "nullptr (precondition).";
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         return;
     }
 
@@ -1570,7 +1542,7 @@
     {
         char const str[] = "vkCreateRenderPass parameter, VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO "\
             "pCreateInfo->sType, is not VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO (precondition).";
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         return;
     }
 
@@ -1578,7 +1550,7 @@
     {
         char const str[] = "vkCreateRenderPass parameter, VkRect pCreateInfo->renderArea, is invalid "\
             "(precondition).";
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         return;
     }
 
@@ -1586,7 +1558,7 @@
     {
         char const str[] = "vkCreateRenderPass parameter, VkExtent2D pCreateInfo->extent, is invalid "\
             "(precondition).";
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         return;
     }
 
@@ -1594,7 +1566,7 @@
     {
         char const str[] = "vkCreateRenderPass parameter, VkFormat* pCreateInfo->pColorFormats, "\
             "is nullptr (precondition).";
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         return;
     }
 
@@ -1605,7 +1577,7 @@
             std::stringstream ss;
             ss << "vkCreateRenderPass parameter, VkFormat pCreateInfo->pColorFormats[" << i <<
                 "], is unrecognized (precondition).";
-            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", ss.str().c_str());
+            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", ss.str().c_str());
             continue;
         }
 
@@ -1618,7 +1590,7 @@
             std::stringstream ss;
             ss << "vkCreateRenderPass parameter, VkFormat pCreateInfo->pColorFormats[" << i <<
                 "], cannot be validated (precondition).";
-            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", ss.str().c_str());
+            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", ss.str().c_str());
             continue;
         }
 
@@ -1627,7 +1599,7 @@
             std::stringstream ss;
             ss << "vkCreateRenderPass parameter, VkFormat pCreateInfo->pColorFormats[" << i <<
                 "], contains unsupported format (precondition).";
-            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", ss.str().c_str());
+            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", ss.str().c_str());
             continue;
         }
 
@@ -1637,7 +1609,7 @@
     {
         char const str[] = "vkCreateRenderPass parameter, VkImageLayout* pCreateInfo->pColorLayouts, "\
             "is nullptr (precondition).";
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         return;
     }
 
@@ -1648,7 +1620,7 @@
             std::stringstream ss;
             ss << "vkCreateRenderPass parameter, VkImageLayout pCreateInfo->pColorLayouts[" << i <<
                 "], is unrecognized (precondition).";
-            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", ss.str().c_str());
+            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", ss.str().c_str());
             continue;
         }
     }
@@ -1657,7 +1629,7 @@
     {
         char const str[] = "vkCreateRenderPass parameter, VkAttachmentLoadOp* pCreateInfo->pColorLoadOps, "\
             "is nullptr (precondition).";
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         return;
     }
 
@@ -1668,7 +1640,7 @@
             std::stringstream ss;
             ss << "vkCreateRenderPass parameter, VkAttachmentLoadOp pCreateInfo->pColorLoadOps[" << i <<
                 "], is unrecognized (precondition).";
-            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", ss.str().c_str());
+            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", ss.str().c_str());
             continue;
         }
     }
@@ -1677,7 +1649,7 @@
     {
         char const str[] = "vkCreateRenderPass parameter, VkAttachmentStoreOp* pCreateInfo->pColorStoreOps, "\
             "is nullptr (precondition).";
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         return;
     }
 
@@ -1688,7 +1660,7 @@
             std::stringstream ss;
             ss << "vkCreateRenderPass parameter, VkAttachmentStoreOp pCreateInfo->pColorStoreOps[" << i <<
                 "], is unrecognized (precondition).";
-            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", ss.str().c_str());
+            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", ss.str().c_str());
             continue;
         }
     }
@@ -1697,7 +1669,7 @@
     {
         char const str[] = "vkCreateRenderPass parameter, VkClearColor* pCreateInfo->"\
             "pColorLoadClearValues, is nullptr (precondition).";
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         return;
     }
 
@@ -1705,7 +1677,7 @@
     {
         char const str[] = "vkCreateRenderPass parameter, VK_ATTACHMENT_STORE_OP* pCreateInfo->pColorStoreOps, "\
             "is nullptr (precondition).";
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         return;
     }
 
@@ -1713,7 +1685,7 @@
     {
         char const str[] = "vkCreateRenderPass parameter, VK_CLEAR_COLOR* pCreateInfo->"\
             "pColorLoadClearValues, is nullptr (precondition).";
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         return;
     }
    
@@ -1724,7 +1696,7 @@
             std::stringstream ss;
             ss << "vkCreateRenderPass parameter, VkClearColor pCreateInfo->pColorLoadClearValues[" << i <<
                 "], is invalid (precondition).";
-            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", ss.str().c_str());
+            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", ss.str().c_str());
             continue;
         }
     }
@@ -1733,7 +1705,7 @@
     {
         char const str[] = "vkCreateRenderPass parameter, VkFormat pCreateInfo->"\
             "depthStencilFormat, is unrecognized (precondition).";
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         return;
     }
 
@@ -1745,7 +1717,7 @@
     {
         char const str[] = "vkCreateRenderPass parameter, VkFormat pCreateInfo->"\
             "depthStencilFormat, cannot be validated (precondition).";
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         return;
     }
 
@@ -1753,7 +1725,7 @@
     {
         char const str[] = "vkCreateRenderPass parameter, VkFormat pCreateInfo->"\
             "depthStencilFormat, contains unsupported format (precondition).";
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         return;
     }
 
@@ -1761,7 +1733,7 @@
     {
         char const str[] = "vkCreateRenderPass parameter, VkImageLayout pCreateInfo->"\
             "depthStencilLayout, is unrecognized (precondition).";
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         return;
     }
 
@@ -1769,7 +1741,7 @@
     {
         char const str[] = "vkCreateRenderPass parameter, VkAttachmentLoadOp pCreateInfo->"\
             "depthLoadOp, is unrecognized (precondition).";
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         return;
     }
 
@@ -1777,7 +1749,7 @@
     {
         char const str[] = "vkCreateRenderPass parameter, VkAttachmentStoreOp pCreateInfo->"\
             "depthStoreOp, is unrecognized (precondition).";
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         return;
     }
 
@@ -1785,7 +1757,7 @@
     {
         char const str[] = "vkCreateRenderPass parameter, VkAttachmentLoadOp pCreateInfo->"\
             "stencilLoadOp, is unrecognized (precondition).";
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         return;
     }
 
@@ -1793,7 +1765,7 @@
     {
         char const str[] = "vkCreateRenderPass parameter, VkAttachmentStoreOp pCreateInfo->"\
             "stencilStoreOp, is unrecognized (precondition).";
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         return;
     }
 }
@@ -1804,14 +1776,14 @@
     {
         // TODO: Spit out VkResult value.
         char const str[] = "vkCreateRenderPass failed (postcondition).";
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         return;
     }
 
     if(pRenderPass == nullptr)
     {
         char const str[] = "vkCreateRenderPass parameter, VkRenderPass* pRenderPass, is nullptr (postcondition).";
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
         return;
     }
 }
@@ -1829,11 +1801,11 @@
     char str[1024];
     if (!pRenderPassBegin) {
         sprintf(str, "Struct ptr parameter pRenderPassBegin to function CmdBeginRenderPass is NULL.");
-        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     else if (!vk_validate_vkrenderpassbegin(pRenderPassBegin)) {
         sprintf(str, "Parameter pRenderPassBegin to function CmdBeginRenderPass contains an invalid value.");
-        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);
+        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, 1, "PARAMCHECK", str);
     }
     nextTable.CmdBeginRenderPass(cmdBuffer, pRenderPassBegin);
 }
@@ -1844,82 +1816,14 @@
     nextTable.CmdEndRenderPass(cmdBuffer, renderPass);
 }
 
-VK_LAYER_EXPORT VkResult VKAPI vkDbgSetValidationLevel(VkDevice device, VkValidationLevel validationLevel)
+VK_LAYER_EXPORT VkResult VKAPI vkDbgCreateMsgCallback(
+        VkInstance instance,
+        VkFlags msgFlags,
+        const PFN_vkDbgMsgCallback pfnMsgCallback,
+        void* pUserData,
+        VkDbgMsgCallback* pMsgCallback)
 {
-    VkResult result = nextTable.DbgSetValidationLevel(device, validationLevel);
-    return result;
-}
-
-VK_LAYER_EXPORT VkResult VKAPI vkDbgRegisterMsgCallback(VkInstance instance, VK_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback, void* pUserData)
-{
-    // This layer intercepts callbacks
-    VK_LAYER_DBG_FUNCTION_NODE *pNewDbgFuncNode = (VK_LAYER_DBG_FUNCTION_NODE*)malloc(sizeof(VK_LAYER_DBG_FUNCTION_NODE));
-    if (!pNewDbgFuncNode)
-        return VK_ERROR_OUT_OF_HOST_MEMORY;
-    pNewDbgFuncNode->pfnMsgCallback = pfnMsgCallback;
-    pNewDbgFuncNode->pUserData = pUserData;
-    pNewDbgFuncNode->pNext = g_pDbgFunctionHead;
-    g_pDbgFunctionHead = pNewDbgFuncNode;
-    // force callbacks if DebugAction hasn't been set already other than initial value
-    if (g_actionIsDefault) {
-        g_debugAction = VK_DBG_LAYER_ACTION_CALLBACK;
-    }
-    VkResult result = nextInstanceTable.DbgRegisterMsgCallback(instance, pfnMsgCallback, pUserData);
-    return result;
-}
-
-VK_LAYER_EXPORT VkResult VKAPI vkDbgUnregisterMsgCallback(VkInstance instance, VK_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback)
-{
-    VK_LAYER_DBG_FUNCTION_NODE *pTrav = g_pDbgFunctionHead;
-    VK_LAYER_DBG_FUNCTION_NODE *pPrev = pTrav;
-    while (pTrav) {
-        if (pTrav->pfnMsgCallback == pfnMsgCallback) {
-            pPrev->pNext = pTrav->pNext;
-            if (g_pDbgFunctionHead == pTrav)
-                g_pDbgFunctionHead = pTrav->pNext;
-            free(pTrav);
-            break;
-        }
-        pPrev = pTrav;
-        pTrav = pTrav->pNext;
-    }
-    if (g_pDbgFunctionHead == NULL)
-    {
-        if (g_actionIsDefault)
-            g_debugAction = VK_DBG_LAYER_ACTION_LOG_MSG;
-        else
-            g_debugAction = (VK_LAYER_DBG_ACTION)(g_debugAction & ~((uint32_t)VK_DBG_LAYER_ACTION_CALLBACK));
-    }
-    VkResult result = nextInstanceTable.DbgUnregisterMsgCallback(instance, pfnMsgCallback);
-    return result;
-}
-
-VK_LAYER_EXPORT VkResult VKAPI vkDbgSetMessageFilter(VkDevice device, int32_t msgCode, VK_DBG_MSG_FILTER filter)
-{
-
-    VkResult result = nextTable.DbgSetMessageFilter(device, msgCode, filter);
-    return result;
-}
-
-VK_LAYER_EXPORT VkResult VKAPI vkDbgSetObjectTag(VkDevice device, VkObject object, size_t tagSize, const void* pTag)
-{
-
-    VkResult result = nextTable.DbgSetObjectTag(device, object, tagSize, pTag);
-    return result;
-}
-
-VK_LAYER_EXPORT VkResult VKAPI vkDbgSetGlobalOption(VkInstance instance, VK_DBG_GLOBAL_OPTION dbgOption, size_t dataSize, const void* pData)
-{
-
-    VkResult result = nextInstanceTable.DbgSetGlobalOption(instance, dbgOption, dataSize, pData);
-    return result;
-}
-
-VK_LAYER_EXPORT VkResult VKAPI vkDbgSetDeviceOption(VkDevice device, VK_DBG_DEVICE_OPTION dbgOption, size_t dataSize, const void* pData)
-{
-
-    VkResult result = nextTable.DbgSetDeviceOption(device, dbgOption, dataSize, pData);
-    return result;
+    return layer_create_msg_callback(instance, &nextInstanceTable, msgFlags, pfnMsgCallback, pUserData, pMsgCallback);
 }
 
 VK_LAYER_EXPORT void VKAPI vkCmdDbgMarkerBegin(VkCmdBuffer cmdBuffer, const char* pMarker)
@@ -2170,14 +2074,6 @@
         return (void*) vkCmdBeginRenderPass;
     if (!strcmp(name, "CmdEndRenderPass"))
         return (void*) vkCmdEndRenderPass;
-    if (!strcmp(name, "DbgSetValidationLevel"))
-        return (void*) vkDbgSetValidationLevel;
-    if (!strcmp(name, "DbgSetMessageFilter"))
-        return (void*) vkDbgSetMessageFilter;
-    if (!strcmp(name, "DbgSetObjectTag"))
-        return (void*) vkDbgSetObjectTag;
-    if (!strcmp(name, "DbgSetDeviceOption"))
-        return (void*) vkDbgSetDeviceOption;
     if (!strcmp(name, "CmdDbgMarkerBegin"))
         return (void*) vkCmdDbgMarkerBegin;
     if (!strcmp(name, "CmdDbgMarkerEnd"))
@@ -2216,16 +2112,8 @@
         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;
 }
diff --git a/layers/shader_checker.cpp b/layers/shader_checker.cpp
index 1ff9a69..9484cd0 100644
--- a/layers/shader_checker.cpp
+++ b/layers/shader_checker.cpp
@@ -109,7 +109,7 @@
         is_spirv(true) {
 
         if (words.size() < 5 || words[0] != spv::MagicNumber || words[1] != spv::Version) {
-            layerCbMsg(VK_DBG_MSG_WARNING, VK_VALIDATION_LEVEL_0, NULL, 0, SHADER_CHECKER_NON_SPIRV_SHADER, "SC",
+            layerCbMsg(VK_DBG_REPORT_WARN_BIT, (VkObjectType) 0, NULL, 0, SHADER_CHECKER_NON_SPIRV_SHADER, "SC",
                        "Shader is not SPIR-V, most checks will not be possible");
             is_spirv = false;
             return;
@@ -129,7 +129,7 @@
 {
     const char *strOpt;
     // initialize ShaderChecker options
-    getLayerOptionEnum("ShaderCheckerReportLevel", (uint32_t *) &g_reportingLevel);
+    getLayerOptionEnum("ShaderCheckerReportLevel", (uint32_t *) &g_reportFlags);
     g_actionIsDefault = getLayerOptionEnum("ShaderCheckerDebugAction", (uint32_t *) &g_debugAction);
 
     if (g_debugAction & VK_DBG_LAYER_ACTION_LOG_MSG)
@@ -198,25 +198,25 @@
 }
 
 
-struct extProps {
-    uint32_t version;
-    const char * const name;
-};
 #define SHADER_CHECKER_LAYER_EXT_ARRAY_SIZE 2
-static const struct extProps shaderCheckerExts[SHADER_CHECKER_LAYER_EXT_ARRAY_SIZE] = {
-    // TODO what is the version?
-    0x10, "ShaderChecker",
-    0x10, "Validation",
+static const VkExtensionProperties shaderCheckerExts[SHADER_CHECKER_LAYER_EXT_ARRAY_SIZE] = {
+    {
+        VK_STRUCTURE_TYPE_EXTENSION_PROPERTIES,
+        "ShaderChecker",
+        0x10,
+        "Sample layer: ShaderChecker",
+//        0,
+//        NULL,
+    }
 };
 
 VK_LAYER_EXPORT VkResult VKAPI vkGetGlobalExtensionInfo(
-                                               VkExtensionInfoType infoType,
-                                               uint32_t extensionIndex,
-                                               size_t*  pDataSize,
-                                               void*    pData)
+        VkExtensionInfoType infoType,
+        uint32_t extensionIndex,
+        size_t*  pDataSize,
+        void*    pData)
 {
     /* This entrypoint is NOT going to init it's own dispatch table since loader calls here early */
-    VkExtensionProperties *ext_props;
     uint32_t *count;
 
     if (pDataSize == NULL)
@@ -236,11 +236,7 @@
                 return VK_SUCCESS;
             if (extensionIndex >= SHADER_CHECKER_LAYER_EXT_ARRAY_SIZE)
                 return VK_ERROR_INVALID_VALUE;
-            ext_props = (VkExtensionProperties *) pData;
-            ext_props->version = shaderCheckerExts[extensionIndex].version;
-            strncpy(ext_props->extName, shaderCheckerExts[extensionIndex].name,
-                                        VK_MAX_EXTENSION_NAME);
-            ext_props->extName[VK_MAX_EXTENSION_NAME - 1] = '\0';
+            memcpy((VkExtensionProperties *) pData, &shaderCheckerExts[extensionIndex], sizeof(VkExtensionProperties));
             break;
         default:
             return VK_ERROR_INVALID_VALUE;
@@ -464,7 +460,7 @@
                 char str[1024];
                 sprintf(str, "var %d (type %d) in %s interface has no Location or Builtin decoration\n",
                        code[word+2], code[word+1], storage_class_name(sinterface));
-                layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, SHADER_CHECKER_INCONSISTENT_SPIRV, "SC", str);
+                layerCbMsg(VK_DBG_REPORT_WARN_BIT, (VkObjectType) 0, NULL, 0, SHADER_CHECKER_INCONSISTENT_SPIRV, "SC", str);
             }
             else if (location != -1) {
                 /* A user-defined interface variable, with a location. */
@@ -530,13 +526,13 @@
         if (b_at_end || a_first < b_first) {
             sprintf(str, "%s writes to output location %d which is not consumed by %s\n",
                    producer_name, a_first, consumer_name);
-            layerCbMsg(VK_DBG_MSG_WARNING, VK_VALIDATION_LEVEL_0, NULL, 0, SHADER_CHECKER_OUTPUT_NOT_CONSUMED, "SC", str);
+            layerCbMsg(VK_DBG_REPORT_WARN_BIT, (VkObjectType) 0, NULL, 0, SHADER_CHECKER_OUTPUT_NOT_CONSUMED, "SC", str);
             a_it++;
         }
         else if (a_at_end || a_first > b_first) {
             sprintf(str, "%s consumes input location %d which is not written by %s\n",
                    consumer_name, b_first, producer_name);
-            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, SHADER_CHECKER_OUTPUT_NOT_CONSUMED, "SC", str);
+            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, SHADER_CHECKER_OUTPUT_NOT_CONSUMED, "SC", str);
             pass = false;
             b_it++;
         }
@@ -552,7 +548,7 @@
 
                 sprintf(str, "Type mismatch on location %d: '%s' vs '%s'\n", a_it->first,
                        producer_type, consumer_type);
-                layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, SHADER_CHECKER_INTERFACE_TYPE_MISMATCH, "SC", str);
+                layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, SHADER_CHECKER_INTERFACE_TYPE_MISMATCH, "SC", str);
                 pass = false;
             }
             a_it++;
@@ -664,7 +660,7 @@
         auto & binding = bindings[desc->binding];
         if (binding) {
             sprintf(str, "Duplicate vertex input binding descriptions for binding %d", desc->binding);
-            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, SHADER_CHECKER_INCONSISTENT_VI, "SC", str);
+            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, SHADER_CHECKER_INCONSISTENT_VI, "SC", str);
             pass = false;
         }
         else {
@@ -706,12 +702,12 @@
         auto b_first = b_at_end ? 0 : it_b->first;
         if (b_at_end || a_first < b_first) {
             sprintf(str, "Vertex attribute at location %d not consumed by VS", a_first);
-            layerCbMsg(VK_DBG_MSG_WARNING, VK_VALIDATION_LEVEL_0, NULL, 0, SHADER_CHECKER_OUTPUT_NOT_CONSUMED, "SC", str);
+            layerCbMsg(VK_DBG_REPORT_WARN_BIT, (VkObjectType) 0, NULL, 0, SHADER_CHECKER_OUTPUT_NOT_CONSUMED, "SC", str);
             it_a++;
         }
         else if (a_at_end || b_first < a_first) {
             sprintf(str, "VS consumes input at location %d but not provided", b_first);
-            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, SHADER_CHECKER_INPUT_NOT_PRODUCED, "SC", str);
+            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, SHADER_CHECKER_INPUT_NOT_PRODUCED, "SC", str);
             pass = false;
             it_b++;
         }
@@ -725,7 +721,7 @@
                 describe_type(vs_type, vs, it_b->second.type_id);
                 sprintf(str, "Attribute type of `%s` at location %d does not match VS input type of `%s`",
                         string_VkFormat(it_a->second->format), a_first, vs_type);
-                layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, SHADER_CHECKER_INTERFACE_TYPE_MISMATCH, "SC", str);
+                layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, SHADER_CHECKER_INTERFACE_TYPE_MISMATCH, "SC", str);
                 pass = false;
             }
 
@@ -756,7 +752,7 @@
      */
     if (builtin_outputs.find(spv::BuiltInFragColor) != builtin_outputs.end()) {
         if (outputs.size()) {
-            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, SHADER_CHECKER_FS_MIXED_BROADCAST, "SC",
+            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, SHADER_CHECKER_FS_MIXED_BROADCAST, "SC",
                        "Should not have user-defined FS outputs when using broadcast");
             pass = false;
         }
@@ -764,7 +760,7 @@
         for (unsigned i = 0; i < cb->attachmentCount; i++) {
             unsigned attachmentType = get_format_type(cb->pAttachments[i].format);
             if (attachmentType == FORMAT_TYPE_SINT || attachmentType == FORMAT_TYPE_UINT) {
-                layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, SHADER_CHECKER_INTERFACE_TYPE_MISMATCH, "SC",
+                layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, SHADER_CHECKER_INTERFACE_TYPE_MISMATCH, "SC",
                            "CB format should not be SINT or UINT when using broadcast");
                 pass = false;
             }
@@ -783,12 +779,12 @@
     while ((outputs.size() > 0 && it != outputs.end()) || attachment < cb->attachmentCount) {
         if (attachment == cb->attachmentCount || ( it != outputs.end() && it->first < attachment)) {
             sprintf(str, "FS writes to output location %d with no matching attachment", it->first);
-            layerCbMsg(VK_DBG_MSG_WARNING, VK_VALIDATION_LEVEL_0, NULL, 0, SHADER_CHECKER_OUTPUT_NOT_CONSUMED, "SC", str);
+            layerCbMsg(VK_DBG_REPORT_WARN_BIT, (VkObjectType) 0, NULL, 0, SHADER_CHECKER_OUTPUT_NOT_CONSUMED, "SC", str);
             it++;
         }
         else if (it == outputs.end() || it->first > attachment) {
             sprintf(str, "Attachment %d not written by FS", attachment);
-            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, SHADER_CHECKER_INPUT_NOT_PRODUCED, "SC", str);
+            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, SHADER_CHECKER_INPUT_NOT_PRODUCED, "SC", str);
             attachment++;
             pass = false;
         }
@@ -802,7 +798,7 @@
                 describe_type(fs_type, fs, it->second.type_id);
                 sprintf(str, "Attachment %d of type `%s` does not match FS output type of `%s`",
                         attachment, string_VkFormat(cb->pAttachments[attachment].format), fs_type);
-                layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, SHADER_CHECKER_INTERFACE_TYPE_MISMATCH, "SC", str);
+                layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, SHADER_CHECKER_INTERFACE_TYPE_MISMATCH, "SC", str);
                 pass = false;
             }
 
@@ -853,7 +849,7 @@
 
             if (shader_stage->shader.stage < VK_SHADER_STAGE_VERTEX || shader_stage->shader.stage > VK_SHADER_STAGE_FRAGMENT) {
                 sprintf(str, "Unknown shader stage %d\n", shader_stage->shader.stage);
-                layerCbMsg(VK_DBG_MSG_WARNING, VK_VALIDATION_LEVEL_0, NULL, 0, SHADER_CHECKER_UNKNOWN_STAGE, "SC", str);
+                layerCbMsg(VK_DBG_REPORT_WARN_BIT, (VkObjectType) 0, NULL, 0, SHADER_CHECKER_UNKNOWN_STAGE, "SC", str);
             }
             else {
                 shaders[shader_stage->shader.stage] = shader_map[(void *)(shader_stage->shader.shader)];
@@ -947,60 +943,6 @@
 }
 
 
-VK_LAYER_EXPORT VkResult VKAPI vkDbgRegisterMsgCallback(
-    VkInstance                    instance,
-    VK_DBG_MSG_CALLBACK_FUNCTION  pfnMsgCallback,
-    void                         *pUserData)
-{
-    // This layer intercepts callbacks
-    VK_LAYER_DBG_FUNCTION_NODE *pNewDbgFuncNode = (VK_LAYER_DBG_FUNCTION_NODE*)malloc(sizeof(VK_LAYER_DBG_FUNCTION_NODE));
-    if (!pNewDbgFuncNode)
-        return VK_ERROR_OUT_OF_HOST_MEMORY;
-    pNewDbgFuncNode->pfnMsgCallback = pfnMsgCallback;
-    pNewDbgFuncNode->pUserData = pUserData;
-    pNewDbgFuncNode->pNext = g_pDbgFunctionHead;
-    g_pDbgFunctionHead = pNewDbgFuncNode;
-    // force callbacks if DebugAction hasn't been set already other than initial value
-    if (g_actionIsDefault) {
-        g_debugAction = VK_DBG_LAYER_ACTION_CALLBACK;
-    }
-    // NOT CORRECT WITH MULTIPLE DEVICES OR INSTANCES, BUT THIS IS ALL GOING AWAY SOON ANYWAY
-    VkLayerInstanceDispatchTable *pTable = tableInstanceMap[pCurObj];
-    VkResult result = pTable->DbgRegisterMsgCallback(instance, pfnMsgCallback, pUserData);
-    return result;
-}
-
-VK_LAYER_EXPORT VkResult VKAPI vkDbgUnregisterMsgCallback(
-    VkInstance                   instance,
-    VK_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback)
-{
-    VK_LAYER_DBG_FUNCTION_NODE *pInfo = g_pDbgFunctionHead;
-    VK_LAYER_DBG_FUNCTION_NODE *pPrev = pInfo;
-    while (pInfo) {
-        if (pInfo->pfnMsgCallback == pfnMsgCallback) {
-            pPrev->pNext = pInfo->pNext;
-            if (g_pDbgFunctionHead == pInfo) {
-                g_pDbgFunctionHead = pInfo->pNext;
-            }
-            free(pInfo);
-            break;
-        }
-        pPrev = pInfo;
-        pInfo = pInfo->pNext;
-    }
-    if (g_pDbgFunctionHead == NULL) {
-        if (g_actionIsDefault) {
-            g_debugAction = VK_DBG_LAYER_ACTION_LOG_MSG;
-        } else {
-            g_debugAction = (VK_LAYER_DBG_ACTION)(g_debugAction & ~((uint32_t)VK_DBG_LAYER_ACTION_CALLBACK));
-        }
-    }
-    // NOT CORRECT WITH MULTIPLE DEVICES OR INSTANCES, BUT THIS IS ALL GOING AWAY SOON ANYWAY
-    VkLayerInstanceDispatchTable *pTable = tableInstanceMap[pCurObj];
-    VkResult result = pTable->DbgUnregisterMsgCallback(instance, pfnMsgCallback);
-    return result;
-}
-
 /* hook DextroyDevice to remove tableMap entry */
 VK_LAYER_EXPORT VkResult VKAPI vkDestroyDevice(VkDevice device)
 {
diff --git a/layers/shader_checker.h b/layers/shader_checker.h
index 4ec8dea..a952ac7 100644
--- a/layers/shader_checker.h
+++ b/layers/shader_checker.h
@@ -22,6 +22,7 @@
  * DEALINGS IN THE SOFTWARE.
  */
 #include "vkLayer.h"
+#include "vk_debug_report_lunarg.h"
 
 
 /* Shader checker error codes */
diff --git a/loader/CMakeLists.txt b/loader/CMakeLists.txt
index b334af3..0006d87 100644
--- a/loader/CMakeLists.txt
+++ b/loader/CMakeLists.txt
@@ -10,16 +10,16 @@
 if (WIN32)
     set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DVK_PROTOTYPES -D_CRT_SECURE_NO_WARNINGS -DXCB_NVIDIA")
 
-    add_library(vulkan SHARED loader.c loader.h loader_platform.h dirent_on_windows.c trampoline.c  wsi_lunarg.c wsi_lunarg.h table_ops.h gpa_helper.h vulkan.def)
+    add_library(vulkan SHARED loader.c loader.h loader_platform.h dirent_on_windows.c trampoline.c  wsi_lunarg.c wsi_lunarg.h debug_report.c debug_report.h table_ops.h gpa_helper.h vulkan.def)
     set_target_properties(vulkan PROPERTIES LINK_FLAGS "/DEF:${PROJECT_SOURCE_DIR}/loader/vulkan.def")
-    add_library(VKstatic STATIC loader.c loader.h dirent_on_windows.c trampoline.c wsi_lunarg.c wsi_lunarg.h table_ops.h gpa_helper.h)
+    add_library(VKstatic STATIC loader.c loader.h dirent_on_windows.c trampoline.c wsi_lunarg.c wsi_lunarg.h debug_report.c debug_report.h table_ops.h gpa_helper.h)
     set_target_properties(VKstatic PROPERTIES OUTPUT_NAME VKstatic)
     target_link_libraries(vulkan)
 endif()
 if (NOT WIN32)
     set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DVK_PROTOTYPES -Wpointer-arith")
 
-    add_library(vulkan SHARED loader.c trampoline.c wsi_lunarg.c wsi_lunarg.h loader.h loader_platform.h table_ops.h gpa_helper.h)
+    add_library(vulkan SHARED loader.c trampoline.c wsi_lunarg.c wsi_lunarg.h debug_report.c debug_report.h loader.h loader_platform.h table_ops.h gpa_helper.h)
     set_target_properties(vulkan PROPERTIES SOVERSION 0)
     target_link_libraries(vulkan -ldl -lpthread)
 endif()
diff --git a/loader/debug_report.c b/loader/debug_report.c
new file mode 100644
index 0000000..950c394
--- /dev/null
+++ b/loader/debug_report.c
@@ -0,0 +1,287 @@
+/*
+ * Vulkan
+ *
+ * Copyright (C) 2015 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *   Jon Ashburn <jon@lunarg.com>
+ *   Courtney Goeltzenleuchter <courtney@lunarg.com>
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include "debug_report.h"
+#include "vkLayer.h"
+
+static const struct loader_extension_property debug_report_extension_info = {
+    .info =  {
+        .sType = VK_STRUCTURE_TYPE_EXTENSION_PROPERTIES,
+        .name = DEBUG_REPORT_EXTENSION_NAME,
+        .version = VK_DEBUG_REPORT_EXTENSION_VERSION,
+        .description = "loader: debug report extension",
+//        .dependencyCount = 0,
+//        .pDependencyList = NULL,
+        },
+    .origin = VK_EXTENSION_ORIGIN_LOADER,
+    .hosted = true,
+};
+
+void debug_report_add_instance_extensions(
+        struct loader_extension_list *ext_list)
+{
+    loader_add_to_ext_list(ext_list, 1, &debug_report_extension_info);
+}
+
+void debug_report_create_instance(
+        struct loader_instance *ptr_instance)
+{
+    ptr_instance->debug_report_enabled = has_vk_extension_property(
+                                             &debug_report_extension_info.info,
+                                             &ptr_instance->enabled_instance_extensions);
+}
+
+static VkResult debug_report_DbgCreateMsgCallback(
+        VkInstance instance,
+        VkFlags msgFlags,
+        const PFN_vkDbgMsgCallback pfnMsgCallback,
+        void* pUserData,
+        VkDbgMsgCallback* pMsgCallback)
+{
+    VkLayerDbgFunctionNode *pNewDbgFuncNode = (VkLayerDbgFunctionNode *) malloc(sizeof(VkLayerDbgFunctionNode));
+    if (!pNewDbgFuncNode)
+        return VK_ERROR_OUT_OF_HOST_MEMORY;
+
+    struct loader_instance *inst = (struct loader_instance *) instance;
+    VkResult result = inst->disp->DbgCreateMsgCallback(instance, msgFlags, pfnMsgCallback, pUserData, pMsgCallback);
+    if (result == VK_SUCCESS) {
+        pNewDbgFuncNode->msgCallback = *pMsgCallback;
+        pNewDbgFuncNode->pfnMsgCallback = pfnMsgCallback;
+        pNewDbgFuncNode->msgFlags = msgFlags;
+        pNewDbgFuncNode->pUserData = pUserData;
+        pNewDbgFuncNode->pNext = inst->DbgFunctionHead;
+        inst->DbgFunctionHead = pNewDbgFuncNode;
+    } else {
+        free(pNewDbgFuncNode);
+    }
+    return result;
+}
+
+static VkResult debug_report_DbgDestroyMsgCallback(
+        VkInstance instance,
+        VkLayerDispatchTable nextTable,
+        VkDbgMsgCallback msg_callback)
+{
+    struct loader_instance *inst = (struct loader_instance *) instance;
+    VkLayerDbgFunctionNode *pTrav = inst->DbgFunctionHead;
+    VkLayerDbgFunctionNode *pPrev = pTrav;
+
+    VkResult result = nextTable.DbgDestroyMsgCallback(instance, msg_callback);
+
+    while (pTrav) {
+        if (pTrav->msgCallback == msg_callback) {
+            pPrev->pNext = pTrav->pNext;
+            if (inst->DbgFunctionHead == pTrav)
+                inst->DbgFunctionHead = pTrav->pNext;
+            free(pTrav);
+            break;
+        }
+        pPrev = pTrav;
+        pTrav = pTrav->pNext;
+    }
+
+    return result;
+}
+
+
+/*
+ * This is the instance chain terminator function
+ * for DbgCreateMsgCallback
+ */
+VkResult loader_DbgCreateMsgCallback(
+        VkInstance                          instance,
+        VkFlags                             msgFlags,
+        const PFN_vkDbgMsgCallback          pfnMsgCallback,
+        const void*                         pUserData,
+        VkDbgMsgCallback*                   pMsgCallback)
+{
+    VkDbgMsgCallback *icd_info;
+    const struct loader_icd *icd;
+    struct loader_instance *inst;
+    VkResult res;
+    uint32_t storage_idx;
+
+    if (instance == VK_NULL_HANDLE)
+        return VK_ERROR_INVALID_HANDLE;
+
+    assert(loader.icds_scanned);
+
+    for (inst = loader.instances; inst; inst = inst->next) {
+        if ((VkInstance) inst == instance)
+            break;
+    }
+
+    if (inst == VK_NULL_HANDLE)
+        return VK_ERROR_INVALID_HANDLE;
+
+    icd_info = calloc(sizeof(VkDbgMsgCallback), inst->total_icd_count);
+    if (!icd_info) {
+        return VK_ERROR_OUT_OF_HOST_MEMORY;
+    }
+
+    storage_idx = 0;
+    for (icd = inst->icds; icd; icd = icd->next) {
+        if (!icd->DbgCreateMsgCallback) {
+            continue;
+        }
+
+        res = icd->DbgCreateMsgCallback(
+                  icd->instance,
+                  msgFlags,
+                  pfnMsgCallback,
+                  pUserData,
+                  &icd_info[storage_idx]);
+
+        if (res != VK_SUCCESS) {
+            break;
+        }
+        storage_idx++;
+    }
+
+    /* roll back on errors */
+    if (icd) {
+        storage_idx = 0;
+        for (icd = inst->icds; icd; icd = icd->next) {
+            if (icd_info[storage_idx]) {
+                icd->DbgDestroyMsgCallback(
+                      icd->instance,
+                      icd_info[storage_idx]);
+            }
+            storage_idx++;
+        }
+
+        return res;
+    }
+
+    *pMsgCallback = (VkDbgMsgCallback) icd_info;
+
+    return VK_SUCCESS;
+}
+
+/*
+ * This is the instance chain terminator function
+ * for DbgDestroyMsgCallback
+ */
+VkResult loader_DbgDestroyMsgCallback(
+        VkInstance instance,
+        VkDbgMsgCallback msgCallback)
+{
+    uint32_t storage_idx;
+    VkDbgMsgCallback *icd_info;
+    const struct loader_icd *icd;
+    VkResult res = VK_SUCCESS;
+    struct loader_instance *inst;
+
+    if (instance == VK_NULL_HANDLE)
+        return VK_ERROR_INVALID_HANDLE;
+
+    assert(loader.icds_scanned);
+
+    for (inst = loader.instances; inst; inst = inst->next) {
+        if ((VkInstance) inst == instance)
+            break;
+    }
+
+    if (inst == VK_NULL_HANDLE)
+        return VK_ERROR_INVALID_HANDLE;
+
+    icd_info = (VkDbgMsgCallback *) msgCallback;
+    storage_idx = 0;
+    for (icd = inst->icds; icd; icd = icd->next) {
+        if (icd_info[storage_idx]) {
+            icd->DbgDestroyMsgCallback(
+                  icd->scanned_icds->instance,
+                  icd_info[storage_idx]);
+        }
+        storage_idx++;
+    }
+    return res;
+}
+
+// DebugReport utility callback functions
+static void VKAPI StringCallback(
+    VkFlags                             msgFlags,
+    VkObjectType                        objType,
+    VkObject                            srcObject,
+    size_t                              location,
+    int32_t                             msgCode,
+    const char*                         pLayerPrefix,
+    const char*                         pMsg,
+    void*                               pUserData)
+{
+
+}
+
+static void VKAPI StdioCallback(
+    VkFlags                             msgFlags,
+    VkObjectType                        objType,
+    VkObject                            srcObject,
+    size_t                              location,
+    int32_t                             msgCode,
+    const char*                         pLayerPrefix,
+    const char*                         pMsg,
+    void*                               pUserData)
+{
+
+}
+
+static void VKAPI BreakCallback(
+    VkFlags                             msgFlags,
+    VkObjectType                        objType,
+    VkObject                            srcObject,
+    size_t                              location,
+    int32_t                             msgCode,
+    const char*                         pLayerPrefix,
+    const char*                         pMsg,
+    void*                               pUserData)
+{
+
+}
+
+void *debug_report_instance_gpa(
+        struct loader_instance *ptr_instance,
+        const char* name)
+{
+    if (ptr_instance == VK_NULL_HANDLE || !ptr_instance->debug_report_enabled)
+        return NULL;
+
+    if (!strcmp("vkDbgCreateMsgCallback", name))
+        return (void *) debug_report_DbgCreateMsgCallback;
+    else if (!strcmp("vkDbgDestroyMsgCallback", name))
+        return (void *) debug_report_DbgDestroyMsgCallback;
+    else if (!strcmp("vkStringCallback", name))
+        return (void *) StringCallback;
+    else if (!strcmp("vkStdioCallback", name))
+        return (void *) StdioCallback;
+    else if (!strcmp("vkBreakCallback", name))
+        return (void *) BreakCallback;
+
+    return NULL;
+}
diff --git a/loader/debug_report.h b/loader/debug_report.h
new file mode 100644
index 0000000..4c8551c
--- /dev/null
+++ b/loader/debug_report.h
@@ -0,0 +1,52 @@
+/*
+ * Vulkan
+ *
+ * Copyright (C) 2015 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *   Jon Ashburn <jon@lunarg.com>
+ *   Courtney Goeltzenleuchter <courtney@lunarg.com>
+ */
+
+#include "loader_platform.h"
+#include "loader.h"
+#include "vk_debug_report_lunarg.h"
+
+void debug_report_add_instance_extensions(
+        struct loader_extension_list *ext_list);
+
+void debug_report_create_instance(
+        struct loader_instance *ptr_instance);
+
+void *debug_report_instance_gpa(
+        struct loader_instance *ptr_instance,
+        const char* name);
+
+VkResult loader_DbgCreateMsgCallback(
+    VkInstance                          instance,
+    VkFlags                             msgFlags,
+    const PFN_vkDbgMsgCallback          pfnMsgCallback,
+    const void*                         pUserData,
+    VkDbgMsgCallback*                   pMsgCallback);
+
+VkResult loader_DbgDestroyMsgCallback(
+    VkInstance                          instance,
+    VkDbgMsgCallback                    msgCallback);
diff --git a/loader/gpa_helper.h b/loader/gpa_helper.h
index 6e831bd..4fe8d38 100644
--- a/loader/gpa_helper.h
+++ b/loader/gpa_helper.h
@@ -23,6 +23,7 @@
  */
 
 #include <string.h>
+#include "wsi_lunarg.h"
 
 static inline void* globalGetProcAddr(const char *name)
 {
@@ -50,8 +51,6 @@
         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"))
@@ -258,24 +257,6 @@
         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;
 
     return NULL;
 }
@@ -306,18 +287,12 @@
         return (void*) vkCreateDevice;
     if (!strcmp(name, "GetGlobalExtensionInfo"))
         return (void*) vkGetGlobalExtensionInfo;
-    if (!strcmp(name, "EnumerateLayers"))
-        return (void*) vkEnumerateLayers;
     if (!strcmp(name, "GetDeviceQueue"))
         return (void*) vkGetDeviceQueue;
     if (!strcmp(name, "CreateCommandBuffer"))
         return (void*) vkCreateCommandBuffer;
-    if (!strcmp(name, "DbgRegisterMsgCallback"))
-        return (void*) vkDbgRegisterMsgCallback;
-    if (!strcmp(name, "DbgUnregisterMsgCallback"))
-        return (void*) vkDbgUnregisterMsgCallback;
-    if (!strcmp(name, "DbgSetGlobalOption"))
-        return (void*) vkDbgSetGlobalOption;
+    if (!strcmp(name, "CreateSwapChainWSI"))
+        return (void*) wsi_lunarg_CreateSwapChainWSI;
 
     return NULL;
 }
diff --git a/loader/loader.c b/loader/loader.c
index 1f7adc1..10c65cd 100644
--- a/loader/loader.c
+++ b/loader/loader.c
@@ -45,32 +45,27 @@
 #include "wsi_lunarg.h"
 #include "gpa_helper.h"
 #include "table_ops.h"
+#include "debug_report.h"
 #include "vkIcd.h"
 // The following is #included again to catch certain OS-specific functions
 // being used:
 #include "loader_platform.h"
 
-struct layer_name_pair {
-    char *layer_name;
-    const char *lib_name;
+void loader_add_to_ext_list(
+        struct loader_extension_list *ext_list,
+        uint32_t prop_list_count,
+        const struct loader_extension_property *prop_list);
+
+static void loader_deactivate_instance_layers(struct loader_instance *instance);
+
+enum intel_ext_type {
+    LOADER_EXT_DEBUG_REPORT,
+
+    LOADER_EXT_COUNT,
+    LOADER_EXT_INVALID = LOADER_EXT_COUNT,
 };
 
-struct extension_property {
-    char extName[VK_MAX_EXTENSION_NAME];
-    uint32_t version;
-    bool hosted;            // does the extension reside in one driver/layer
-};
-
-struct loader_scanned_icds {
-    loader_platform_dl_handle handle;
-
-    PFN_vkCreateInstance CreateInstance;
-    PFN_vkGetGlobalExtensionInfo GetGlobalExtensionInfo;
-    struct loader_scanned_icds *next;
-    uint32_t extension_count;
-    struct extension_property *extensions;
-};
-
+/* TODO: do we need to lock around access to linked lists and such? */
 struct loader_struct loader = {0};
 
 VkLayerInstanceDispatchTable instance_disp = {
@@ -82,12 +77,10 @@
     .CreateDevice = loader_CreateDevice,
     .GetGlobalExtensionInfo = vkGetGlobalExtensionInfo,
     .GetPhysicalDeviceExtensionInfo = loader_GetPhysicalDeviceExtensionInfo,
-    .EnumerateLayers = loader_EnumerateLayers,
     .GetMultiDeviceCompatibility = loader_GetMultiDeviceCompatibility,
-    .DbgRegisterMsgCallback = loader_DbgRegisterMsgCallback,
-    .DbgUnregisterMsgCallback = loader_DbgUnregisterMsgCallback,
-    .DbgSetGlobalOption = loader_DbgSetGlobalOption,
-    .GetDisplayInfoWSI = loader_GetDisplayInfoWSI
+    .GetDisplayInfoWSI = loader_GetDisplayInfoWSI,
+    .DbgCreateMsgCallback = loader_DbgCreateMsgCallback,
+    .DbgDestroyMsgCallback = loader_DbgDestroyMsgCallback,
 };
 
 LOADER_PLATFORM_THREAD_ONCE_DECLARATION(once_icd);
@@ -196,7 +189,7 @@
 #endif // WIN32
 
 
-static void loader_log(VK_DBG_MSG_TYPE msg_type, int32_t msg_code,
+static void loader_log(VkFlags msg_type, int32_t msg_code,
                        const char *format, ...)
 {
     char msg[256];
@@ -218,127 +211,214 @@
 
 }
 
-static bool has_extension(struct extension_property *exts, uint32_t count,
-                          const char *name, bool must_be_hosted)
+bool compare_vk_extension_properties(const VkExtensionProperties *op1, const VkExtensionProperties *op2)
+{
+    return memcmp(op1, op2, sizeof(VkExtensionProperties)) == 0 ? true : false;
+}
+
+/*
+ * Used to look for an extension with a specific name.
+ * Ignores all other extension info (i.e. version, origin & dependencies)
+ */
+static bool has_extension_name(
+        uint32_t count,
+        struct loader_extension_property *exts,
+        const char *target_ext_name,
+        bool must_be_hosted)
 {
     uint32_t i;
     for (i = 0; i < count; i++) {
-        if (!strcmp(name, exts[i].extName) && (!must_be_hosted || exts[i].hosted))
+        if (!strcmp(exts[i].info.name, target_ext_name) && (!must_be_hosted || exts[i].hosted))
             return true;
     }
     return false;
 }
 
-static void get_global_extensions(PFN_vkGetGlobalExtensionInfo fp_get,
-                                  uint32_t *count_out,
-                                  struct extension_property **props_out)
+static bool has_extension(
+        uint32_t count,
+        struct loader_extension_property *exts,
+        const VkExtensionProperties *target_ext,
+        bool must_be_hosted)
 {
-    uint32_t i, count, cur;
+    uint32_t i;
+    for (i = 0; i < count; i++) {
+        if (compare_vk_extension_properties(&exts[i].info, target_ext) && (!must_be_hosted || exts[i].hosted))
+            return true;
+    }
+    return false;
+}
+
+/*
+ * Search the given ext_list for an extension
+ * matching the given vk_ext_prop
+ */
+bool has_vk_extension_property(
+        const VkExtensionProperties *vk_ext_prop,
+        const struct loader_extension_list *ext_list)
+{
+    for (uint32_t i = 0; i < ext_list->count; i++) {
+        if (compare_vk_extension_properties(&ext_list->list[i].info, vk_ext_prop))
+            return true;
+    }
+    return false;
+}
+
+/*
+ * Search the given ext_list for an extension
+ * matching the given vk_ext_prop
+ */
+static struct loader_extension_property *get_extension_property_from_vkext(
+        const VkExtensionProperties *vk_ext_prop,
+        const struct loader_extension_list *ext_list)
+{
+    for (uint32_t i = 0; i < ext_list->count; i++) {
+        if (compare_vk_extension_properties(&ext_list->list[i].info, vk_ext_prop))
+            return &ext_list->list[i];
+    }
+    return NULL;
+}
+
+static void get_global_extensions(
+        const PFN_vkGetGlobalExtensionInfo fp_get,
+        const char *lib_name,
+        const enum extension_origin origin,
+        struct loader_extension_list *ext_list)
+{
+    uint32_t i, count;
     size_t siz = sizeof(count);
-    struct extension_property *ext_props;
-    VkExtensionProperties vk_prop;
+    struct loader_extension_property ext_props;
     VkResult res;
 
-    *count_out = 0;
-    *props_out = NULL;
     res = fp_get(VK_EXTENSION_INFO_TYPE_COUNT, 0, &siz, &count);
     if (res != VK_SUCCESS) {
-        loader_log(VK_DBG_MSG_WARNING, 0, "Error getting global extension count from ICD");
-        return;
-    }
-    ext_props = (struct extension_property *) malloc(sizeof(struct extension_property) * count);
-    if (ext_props == NULL) {
-        loader_log(VK_DBG_MSG_WARNING, 0, "Out of memory didn't get global extensions from ICD");
+        loader_log(VK_DBG_REPORT_WARN_BIT, 0, "Error getting global extension count from ICD");
         return;
     }
     siz = sizeof(VkExtensionProperties);
-    cur = 0;
     for (i = 0; i < count; i++) {
-        res = fp_get(VK_EXTENSION_INFO_TYPE_PROPERTIES, i, &siz, &vk_prop);
+        memset(&ext_props, 1, sizeof(ext_props));
+        res = fp_get(VK_EXTENSION_INFO_TYPE_PROPERTIES, i, &siz, &ext_props.info);
         if (res == VK_SUCCESS) {
-            (ext_props + cur)->hosted = false;
-            (ext_props + cur)->version = vk_prop.version;
-            strncpy((ext_props + cur)->extName, vk_prop.extName, VK_MAX_EXTENSION_NAME);
-            (ext_props + cur)->extName[VK_MAX_EXTENSION_NAME - 1] = '\0';
-            cur++;
+            ext_props.hosted = false;
+            ext_props.origin = origin;
+            ext_props.lib_name = lib_name;
+            loader_add_to_ext_list(ext_list, 1, &ext_props);
         }
-        *count_out = cur;
-        *props_out = ext_props;
     }
+
     return;
 }
 
-static void loader_init_ext_list()
+static bool loader_init_ext_list(struct loader_extension_list *ext_info)
 {
-    loader.scanned_ext_list_capacity = 256 * sizeof(struct extension_property *);
-    loader.scanned_ext_list = malloc(loader.scanned_ext_list_capacity);
-    memset(loader.scanned_ext_list, 0, loader.scanned_ext_list_capacity);
-    loader.scanned_ext_list_count = 0;
+    ext_info->capacity = 32 * sizeof(struct loader_extension_property);
+    ext_info->list = malloc(ext_info->capacity);
+    if (ext_info->list == NULL) {
+        return false;
+    }
+    memset(ext_info->list, 0, ext_info->capacity);
+    ext_info->count = 0;
+    return true;
 }
 
-#if 0 // currently no place to call this
-static void loader_destroy_ext_list()
+static void loader_destroy_ext_list(struct loader_extension_list *ext_info)
 {
-    free(loader.scanned_ext_list);
-    loader.scanned_ext_list_capacity = 0;
-    loader.scanned_ext_list_count = 0;
+    free(ext_info->list);
+    ext_info->count = 0;
+    ext_info->capacity = 0;
 }
-#endif
 
-static void loader_add_to_ext_list(uint32_t count,
-                                   struct extension_property *prop_list,
-                                   bool is_layer_ext)
+static void loader_add_vk_ext_to_ext_list(
+        struct loader_extension_list *ext_list,
+        uint32_t prop_list_count,
+        const VkExtensionProperties *props,
+        const struct loader_extension_list *search_list)
 {
-    uint32_t i, j;
-    bool duplicate;
-    struct extension_property *cur_ext;
+    struct loader_extension_property *ext_prop;
 
-    if (loader.scanned_ext_list == NULL || loader.scanned_ext_list_capacity == 0)
-        loader_init_ext_list();
-
-    if (loader.scanned_ext_list == NULL)
-        return;
-
-    struct extension_property *ext_list, **ext_list_addr;
-
-    for (i = 0; i < count; i++) {
-        cur_ext = prop_list + i;
-
-        // look for duplicates or not
-        duplicate = false;
-        for (j = 0; j < loader.scanned_ext_list_count; j++) {
-            ext_list = loader.scanned_ext_list[j];
-            if (!strcmp(cur_ext->extName, ext_list->extName)) {
-                duplicate = true;
-                ext_list->hosted = false;
-                break;
-            }
+    for (uint32_t i = 0; i < prop_list_count; i++) {
+        // look for duplicates
+        if (has_vk_extension_property(&props[i], ext_list)) {
+            continue;
         }
 
-        // add to list at end
-        if (!duplicate) {
-            // check for enough capacity
-            if (loader.scanned_ext_list_count * sizeof(struct extension_property *)
-                            >= loader.scanned_ext_list_capacity) {
-                // double capacity
-                loader.scanned_ext_list_capacity *= 2;
-                loader.scanned_ext_list = realloc(loader.scanned_ext_list,
-                        loader.scanned_ext_list_capacity);
-            }
-            ext_list_addr = &(loader.scanned_ext_list[loader.scanned_ext_list_count++]);
-            *ext_list_addr = cur_ext;
-            cur_ext->hosted = true;
+        ext_prop = get_extension_property_from_vkext(&props[i], search_list);
+        if (!ext_prop) {
+            loader_log(VK_DBG_REPORT_WARN_BIT, 0, "Unable to find extension %s", props[i].name);
+            continue;
         }
 
+        loader_add_to_ext_list(ext_list, 1, ext_prop);
     }
 }
 
-bool loader_is_extension_scanned(const char *name)
+/*
+ * Append non-duplicate extension properties defined in prop_list
+ * to the given ext_info list
+ */
+void loader_add_to_ext_list(
+        struct loader_extension_list *ext_list,
+        uint32_t prop_list_count,
+        const struct loader_extension_property *props)
+{
+    uint32_t i;
+    struct loader_extension_property *cur_ext;
+
+    if (ext_list->list == NULL || ext_list->capacity == 0) {
+        loader_init_ext_list(ext_list);
+    }
+
+    if (ext_list->list == NULL)
+        return;
+
+    for (i = 0; i < prop_list_count; i++) {
+        cur_ext = (struct loader_extension_property *) &props[i];
+
+        // look for duplicates
+        if (has_vk_extension_property(&cur_ext->info, ext_list)) {
+            continue;
+        }
+
+        // add to list at end
+        // check for enough capacity
+        if (ext_list->count * sizeof(struct loader_extension_property)
+                        >= ext_list->capacity) {
+            // double capacity
+            ext_list->capacity *= 2;
+            ext_list->list = realloc(ext_list->list, ext_list->capacity);
+        }
+        memcpy(&ext_list->list[ext_list->count], cur_ext, sizeof(struct loader_extension_property));
+        ext_list->count++;
+    }
+}
+
+/*
+ * Search the search_list for any extension with
+ * a name that matches the given ext_name.
+ * Add all matching extensions to the found_list
+ * Do not add if found VkExtensionProperties is already
+ * on the found_list
+ */
+static void loader_search_ext_list_for_name(
+        const char *ext_name,
+        const struct loader_extension_list *search_list,
+        struct loader_extension_list *found_list)
+{
+    for (uint32_t i = 0; i < search_list->count; i++) {
+        struct loader_extension_property *ext_prop = &search_list->list[i];
+        if (0 == strcmp(ext_prop->info.name, ext_name)) {
+            /* Found an extension with the same name, add to found_list */
+            loader_add_to_ext_list(found_list, 1, &search_list->list[i]);
+        }
+    }
+}
+
+bool loader_is_extension_scanned(const VkExtensionProperties *ext_prop)
 {
     uint32_t i;
 
-    for (i = 0; i < loader.scanned_ext_list_count; i++) {
-        if (!strcmp(name, loader.scanned_ext_list[i]->extName))
+    for (i = 0; i < loader.global_extensions.count; i++) {
+        if (compare_vk_extension_properties(&loader.global_extensions.list[i].info, ext_prop))
             return true;
     }
     return false;
@@ -351,20 +431,30 @@
 
     // traverse scanned icd list adding non-duplicate extensions to the list
     while (icd_list != NULL) {
-        loader_add_to_ext_list(icd_list->extension_count, icd_list->extensions, false);
+        /* TODO: convert to use ext_list */
+        loader_add_to_ext_list(&loader.global_extensions,
+                               icd_list->global_extension_list.count,
+                               icd_list->global_extension_list.list);
         icd_list = icd_list->next;
     };
 
     //Traverse layers list adding non-duplicate extensions to the list
     for (i = 0; i < loader.scanned_layer_count; i++) {
-        loader_add_to_ext_list(loader.scanned_layers[i].extension_count,
-                loader.scanned_layers[i].extensions, true);
+        loader_add_to_ext_list(&loader.global_extensions,
+                               loader.scanned_layers[i].global_extension_list.count,
+                               loader.scanned_layers[i].global_extension_list.list);
     }
+
+    // Traverse loader's extensions, adding non-duplicate extensions to the list
+    debug_report_add_instance_extensions(&loader.global_extensions);
 }
 
-static void loader_icd_destroy(struct loader_icd *icd)
+static void loader_icd_destroy(
+        struct loader_instance *ptr_inst,
+        struct loader_icd *icd)
 {
     loader_platform_close_library(icd->scanned_icds->handle);
+    ptr_inst->total_icd_count--;
     free(icd);
 }
 
@@ -383,8 +473,9 @@
     return icd;
 }
 
-static struct loader_icd *loader_icd_add(struct loader_instance *ptr_inst,
-                                     const struct loader_scanned_icds *scanned)
+static struct loader_icd *loader_icd_add(
+        struct loader_instance *ptr_inst,
+        const struct loader_scanned_icds *scanned)
 {
     struct loader_icd *icd;
 
@@ -395,6 +486,7 @@
     /* prepend to the list */
     icd->next = ptr_inst->icds;
     ptr_inst->icds = icd;
+    ptr_inst->total_icd_count++;
 
     return icd;
 }
@@ -409,14 +501,14 @@
     // Used to call: dlopen(filename, RTLD_LAZY);
     handle = loader_platform_open_library(filename);
     if (!handle) {
-        loader_log(VK_DBG_MSG_WARNING, 0, loader_platform_open_library_error(filename));
+        loader_log(VK_DBG_REPORT_WARN_BIT, 0, loader_platform_open_library_error(filename));
         return;
     }
 
 #define LOOKUP(func_ptr, func) do {                            \
     func_ptr = (PFN_vk ##func) loader_platform_get_proc_address(handle, "vk" #func); \
     if (!func_ptr) {                                           \
-        loader_log(VK_DBG_MSG_WARNING, 0, loader_platform_get_proc_address_error("vk" #func)); \
+        loader_log(VK_DBG_REPORT_WARN_BIT, 0, loader_platform_get_proc_address_error("vk" #func)); \
         return;                                                \
     }                                                          \
 } while (0)
@@ -425,28 +517,33 @@
     LOOKUP(fp_get_global_ext_info, GetGlobalExtensionInfo);
 #undef LOOKUP
 
-    new_node = (struct loader_scanned_icds *) malloc(sizeof(struct loader_scanned_icds));
+    new_node = (struct loader_scanned_icds *) malloc(sizeof(struct loader_scanned_icds)
+                                                     + strlen(filename) + 1);
     if (!new_node) {
-        loader_log(VK_DBG_MSG_WARNING, 0, "Out of memory can't add icd");
+        loader_log(VK_DBG_REPORT_WARN_BIT, 0, "Out of memory can't add icd");
         return;
     }
 
     new_node->handle = handle;
     new_node->CreateInstance = fp_create_inst;
     new_node->GetGlobalExtensionInfo = fp_get_global_ext_info;
-    new_node->extension_count = 0;
-    new_node->extensions = NULL;
+    loader_init_ext_list(&new_node->global_extension_list);
     new_node->next = loader.scanned_icd_list;
 
+    new_node->lib_name = (char *) (new_node + 1);
+    if (!new_node->lib_name) {
+        loader_log(VK_DBG_REPORT_WARN_BIT, 0, "Out of memory can't add icd");
+        return;
+    }
+    strcpy(new_node->lib_name, filename);
+
     loader.scanned_icd_list = new_node;
 
-    if (fp_get_global_ext_info) {
-        get_global_extensions((PFN_vkGetGlobalExtensionInfo) fp_get_global_ext_info,
-                       &new_node->extension_count,
-                       &new_node->extensions);
-    } else {
-        loader_log(VK_DBG_MSG_WARNING, 0, "Couldn't get global extensions from ICD");
-    }
+    get_global_extensions(
+                (PFN_vkGetGlobalExtensionInfo) fp_get_global_ext_info,
+                new_node->lib_name,
+                VK_EXTENSION_ORIGIN_ICD,
+                &new_node->global_extension_list);
 }
 
 static void loader_icd_init_entrys(struct loader_icd *icd,
@@ -457,7 +554,7 @@
     #define LOOKUP(func) do {                                 \
     icd->func = (PFN_vk ##func) loader_platform_get_proc_address(scanned_icds->handle, "vk" #func); \
     if (!icd->func) {                                           \
-        loader_log(VK_DBG_MSG_WARNING, 0, loader_platform_get_proc_address_error("vk" #func)); \
+        loader_log(VK_DBG_REPORT_WARN_BIT, 0, loader_platform_get_proc_address_error("vk" #func)); \
         return;                                                \
     }                                                          \
     } while (0)
@@ -469,12 +566,10 @@
     LOOKUP(GetPhysicalDeviceInfo);
     LOOKUP(CreateDevice);
     LOOKUP(GetPhysicalDeviceExtensionInfo);
-    LOOKUP(EnumerateLayers);
     LOOKUP(GetMultiDeviceCompatibility);
-    LOOKUP(DbgRegisterMsgCallback);
-    LOOKUP(DbgUnregisterMsgCallback);
-    LOOKUP(DbgSetGlobalOption);
     LOOKUP(GetDisplayInfoWSI);
+    LOOKUP(DbgCreateMsgCallback);
+    LOOKUP(DbgDestroyMsgCallback);
 #undef LOOKUP
 
     return;
@@ -614,8 +709,7 @@
         free(libPaths);
         return;
     }
-    // Alloc passed, so we know there is enough space to hold the string, don't
-    // need strncpy
+    // Alloc passed, so we know there is enough space to hold the string
     strcpy(loader.layer_dirs, libPaths);
 #if defined(WIN32)
     // Free any allocated memory:
@@ -628,12 +722,10 @@
 
     /* cleanup any previously scanned libraries */
     for (i = 0; i < loader.scanned_layer_count; i++) {
-        if (loader.scanned_layers[i].name != NULL)
-            free(loader.scanned_layers[i].name);
-        if (loader.scanned_layers[i].extensions != NULL)
-            free(loader.scanned_layers[i].extensions);
-        loader.scanned_layers[i].name = NULL;
-        loader.scanned_layers[i].extensions = NULL;
+        if (loader.scanned_layers[i].lib_name != NULL)
+            free(loader.scanned_layers[i].lib_name);
+        loader_destroy_ext_list(&loader.scanned_layers[i].global_extension_list);
+        loader.scanned_layers[i].lib_name = NULL;
     }
     loader.scanned_layer_count = 0;
     count = 0;
@@ -674,8 +766,9 @@
                          dent = readdir(curdir);
                          continue;
                      }
+                     /* TODO: Remove fixed count */
                      if (count == MAX_LAYER_LIBRARIES) {
-                         loader_log(VK_DBG_MSG_ERROR, 0,
+                         loader_log(VK_DBG_REPORT_ERROR_BIT, 0,
                                     "%s ignored: max layer libraries exceed",
                                     temp_str);
                          break;
@@ -684,7 +777,7 @@
                                                "vkGetGlobalExtensionInfo");
 
                      if (!fp_get_ext) {
-                        loader_log(VK_DBG_MSG_WARNING, 0,
+                        loader_log(VK_DBG_REPORT_WARN_BIT, 0,
                               "Couldn't dlsym vkGetGlobalExtensionInfo from library %s",
                                temp_str);
                         dent = readdir(curdir);
@@ -692,21 +785,23 @@
                         continue;
                      }
 
-                     loader.scanned_layers[count].name =
+                     loader.scanned_layers[count].lib_name =
                                                    malloc(strlen(temp_str) + 1);
-                     if (loader.scanned_layers[count].name == NULL) {
-                         loader_log(VK_DBG_MSG_ERROR, 0, "%s ignored: out of memory", temp_str);
+                     if (loader.scanned_layers[count].lib_name == NULL) {
+                         loader_log(VK_DBG_REPORT_ERROR_BIT, 0, "%s ignored: out of memory", temp_str);
                          break;
                      }
 
-                     get_global_extensions(fp_get_ext,
-                             &loader.scanned_layers[count].extension_count,
-                             &loader.scanned_layers[count].extensions);
+                     strcpy(loader.scanned_layers[count].lib_name, temp_str);
 
+                     get_global_extensions(
+                                 fp_get_ext,
+                                 loader.scanned_layers[count].lib_name,
+                                 VK_EXTENSION_ORIGIN_LAYER,
+                                 &loader.scanned_layers[count].global_extension_list);
 
-                    strcpy(loader.scanned_layers[count].name, temp_str);
-                    count++;
-                    loader_platform_close_library(handle);
+                     count++;
+                     loader_platform_close_library(handle);
                  }
              }
 
@@ -719,7 +814,7 @@
     } // for (libpaths)
 
     loader.scanned_layer_count = count;
-    loader.layer_scanned = true;
+    loader.layers_scanned = true;
 }
 
 static void* VKAPI loader_gpa_instance_internal(VkInstance inst, const char * pName)
@@ -734,14 +829,20 @@
     if (disp_table == NULL)
         return NULL;
 
+//    addr = debug_report_instance_gpa((struct loader_instance *) inst, pName);
+//    if (addr) {
+//        return addr;
+//    }
+
     addr = loader_lookup_instance_dispatch_table(disp_table, pName);
-    if (addr)
+    if (addr) {
         return addr;
-    else  {
-        if (disp_table->GetInstanceProcAddr == NULL)
-            return NULL;
-        return disp_table->GetInstanceProcAddr(inst, pName);
     }
+
+    if (disp_table->GetInstanceProcAddr == NULL) {
+        return NULL;
+    }
+    return disp_table->GetInstanceProcAddr(inst, pName);
 }
 
 struct loader_icd * loader_get_icd(const VkBaseLayerObject *gpu, uint32_t *gpu_index)
@@ -771,144 +872,111 @@
         return false;
 }
 
-static void loader_init_device_layer_libs(struct loader_icd *icd, uint32_t gpu_index,
-                                   struct layer_name_pair * pLayerNames,
-                                   uint32_t count)
+static loader_platform_dl_handle loader_add_layer_lib(
+        struct loader_instance *inst,
+        struct loader_extension_property *ext_prop)
 {
-    if (!icd)
+    struct loader_lib_info *new_layer_lib_list, *my_lib;
+
+    /* Only loader layer libraries here */
+    if (ext_prop->origin != VK_EXTENSION_ORIGIN_LAYER) {
+        return NULL;
+    }
+
+    for (uint32_t i = 0; i < loader.loaded_layer_lib_count; i++) {
+        if (strcmp(loader.loaded_layer_lib_list[i].lib_name, ext_prop->lib_name) == 0) {
+            /* Have already loaded this library, just increment ref count */
+            loader.loaded_layer_lib_list[i].ref_count++;
+            return loader.loaded_layer_lib_list[i].lib_handle;
+        }
+    }
+
+    /* Haven't seen this library so load it */
+    new_layer_lib_list = realloc(loader.loaded_layer_lib_list,
+                      (loader.loaded_layer_lib_count + 1) * sizeof(struct loader_lib_info));
+    if (!new_layer_lib_list) {
+        loader_log(VK_DBG_REPORT_ERROR_BIT, 0, "loader: malloc failed");
+        return NULL;
+    }
+
+    my_lib = &new_layer_lib_list[loader.loaded_layer_lib_count];
+
+    /* NOTE: We require that the extension property to be immutable */
+    my_lib->lib_name = ext_prop->lib_name;
+    my_lib->ref_count = 0;
+    my_lib->lib_handle = NULL;
+
+    if ((my_lib->lib_handle = loader_platform_open_library(my_lib->lib_name)) == NULL) {
+        loader_log(VK_DBG_REPORT_ERROR_BIT, 0,
+                   loader_platform_open_library_error(my_lib->lib_name));
+        return NULL;
+    } else {
+        loader_log(VK_DBG_REPORT_INFO_BIT, 0,
+                   "Inserting instance layer %s from library %s",
+                   ext_prop->info.name, ext_prop->lib_name);
+    }
+    loader.loaded_layer_lib_count++;
+    loader.loaded_layer_lib_list = new_layer_lib_list;
+    my_lib->ref_count++;
+
+    return my_lib->lib_handle;
+}
+
+static void loader_remove_layer_lib(
+        struct loader_instance *inst,
+        struct loader_extension_property *ext_prop)
+{
+    uint32_t idx;
+    struct loader_lib_info *new_layer_lib_list, *my_lib;
+
+    /* Only loader layer libraries here */
+    if (ext_prop->origin != VK_EXTENSION_ORIGIN_LAYER) {
         return;
+    }
 
-    struct loader_layers *obj;
-    bool foundLib;
-    for (uint32_t i = 0; i < count; i++) {
-        foundLib = false;
-        for (uint32_t j = 0; j < icd->layer_count[gpu_index]; j++) {
-            if (icd->layer_libs[gpu_index][j].lib_handle &&
-                !strcmp(icd->layer_libs[gpu_index][j].name,
-                (char *) pLayerNames[i].layer_name) &&
-                strcmp("Validation", (char *) pLayerNames[i].layer_name)) {
-                foundLib = true;
-                break;
-            }
-        }
-        if (!foundLib) {
-            obj = &(icd->layer_libs[gpu_index][i]);
-            strncpy(obj->name, (char *) pLayerNames[i].layer_name, sizeof(obj->name) - 1);
-            obj->name[sizeof(obj->name) - 1] = '\0';
-            // Used to call: dlopen(pLayerNames[i].lib_name, RTLD_LAZY | RTLD_DEEPBIND)
-            if ((obj->lib_handle = loader_platform_open_library(pLayerNames[i].lib_name)) == NULL) {
-                loader_log(VK_DBG_MSG_ERROR, 0, loader_platform_open_library_error(pLayerNames[i].lib_name));
-                continue;
-            } else {
-                loader_log(VK_DBG_MSG_UNKNOWN, 0, "Inserting device layer %s from library %s",
-                           pLayerNames[i].layer_name, pLayerNames[i].lib_name);
-            }
-            free(pLayerNames[i].layer_name);
-            icd->layer_count[gpu_index]++;
+    for (uint32_t i = 0; i < loader.loaded_layer_lib_count; i++) {
+        if (strcmp(loader.loaded_layer_lib_list[i].lib_name, ext_prop->lib_name) == 0) {
+            /* found matching library */
+            idx = i;
+            my_lib = &loader.loaded_layer_lib_list[i];
+            break;
         }
     }
-}
 
-static void loader_init_instance_layer_libs(struct loader_instance *inst,
-                                   struct layer_name_pair * pLayerNames,
-                                   uint32_t count)
-{
-    if (!inst)
+    my_lib->ref_count--;
+    inst->layer_count--;
+    if (my_lib->ref_count > 0) {
         return;
-
-    struct loader_layers *obj;
-    bool foundLib;
-    for (uint32_t i = 0; i < count; i++) {
-        foundLib = false;
-        for (uint32_t j = 0; j < inst->layer_count; j++) {
-            if (inst->layer_libs[j].lib_handle &&
-                    !strcmp(inst->layer_libs[j].name,
-                    (char *) pLayerNames[i].layer_name) &&
-                    strcmp("Validation", (char *) pLayerNames[i].layer_name)) {
-                foundLib = true;
-                break;
-            }
-        }
-        if (!foundLib) {
-            obj = &(inst->layer_libs[i]);
-            strncpy(obj->name, (char *) pLayerNames[i].layer_name, sizeof(obj->name) - 1);
-            obj->name[sizeof(obj->name) - 1] = '\0';
-            // Used to call: dlopen(pLayerNames[i].lib_name, RTLD_LAZY | RTLD_DEEPBIND)
-            if ((obj->lib_handle = loader_platform_open_library(pLayerNames[i].lib_name)) == NULL) {
-                loader_log(VK_DBG_MSG_ERROR, 0, loader_platform_open_library_error(pLayerNames[i].lib_name));
-                continue;
-            } else {
-                loader_log(VK_DBG_MSG_UNKNOWN, 0, "Inserting instance layer %s from library %s",
-                           pLayerNames[i].layer_name, pLayerNames[i].lib_name);
-            }
-            free(pLayerNames[i].layer_name);
-            inst->layer_count++;
-        }
-    }
-}
-
-static bool find_layer_extension(const char *pExtName, uint32_t *out_count,
-                                 char *lib_name[MAX_LAYER_LIBRARIES])
-{
-    char *search_name;
-    uint32_t j, found_count = 0;
-    bool must_be_hosted;
-    bool found = false;
-
-    /*
-     * The loader provides the abstraction that make layers and extensions work via
-     * the currently defined extension mechanism. That is, when app queries for an extension
-     * via vkGetGlobalExtensionInfo, the loader will call both the driver as well as any layers
-     * to see who implements that extension. Then, if the app enables the extension during
-     * vkCreateInstance the loader will find and load any layers that implement that extension.
-     */
-
-    // TODO: what about GetPhysicalDeviceExtension for device specific layers/extensions
-
-    for (j = 0; j < loader.scanned_layer_count; j++) {
-
-        if (!strcmp("Validation", pExtName))
-            must_be_hosted = false;
-        else
-            must_be_hosted = true;
-        if (has_extension(loader.scanned_layers[j].extensions,
-                          loader.scanned_layers[j].extension_count, pExtName,
-                          must_be_hosted)) {
-
-            found = true;
-            lib_name[found_count] = loader.scanned_layers[j].name;
-            found_count++;
-        } else {
-            // Extension not found in list for the layer, so test the layer name
-            // as if it is an extension name. Use default layer name based on
-            // library name VK_LAYER_LIBRARY_PREFIX<name>.VK_LIBRARY_SUFFIX
-            char *pEnd;
-            size_t siz;
-
-            search_name = loader.scanned_layers[j].name;
-            search_name = basename(search_name);
-            search_name += strlen(VK_LAYER_LIBRARY_PREFIX);
-            pEnd = strrchr(search_name, '.');
-            siz = (int) (pEnd - search_name);
-            if (siz != strlen(pExtName))
-                continue;
-
-            if (strncmp(search_name, pExtName, siz) == 0) {
-                found = true;
-                lib_name[found_count] = loader.scanned_layers[j].name;
-                found_count++;
-            }
-        }
     }
 
-    *out_count = found_count;
-    return found;
+    /* Need to remove unused library from list */
+    new_layer_lib_list = malloc((loader.loaded_layer_lib_count - 1) * sizeof(struct loader_lib_info));
+    if (!new_layer_lib_list) {
+        loader_log(VK_DBG_REPORT_ERROR_BIT, 0, "loader: malloc failed");
+        return;
+    }
+
+    if (idx > 0) {
+        /* Copy records before idx */
+        memcpy(new_layer_lib_list, &loader.loaded_layer_lib_list[0],
+               sizeof(struct loader_lib_info) * idx);
+    }
+    if (idx < (loader.loaded_layer_lib_count - 1)) {
+        /* Copy records after idx */
+        memcpy(&new_layer_lib_list[idx], &loader.loaded_layer_lib_list[idx+1],
+                sizeof(struct loader_lib_info) * (loader.loaded_layer_lib_count - idx - 1));
+    }
+    free(loader.loaded_layer_lib_list);
+    loader.loaded_layer_lib_count--;
+    loader.loaded_layer_lib_list = new_layer_lib_list;
 }
 
-static uint32_t loader_get_layer_env(struct layer_name_pair *pLayerNames)
+static void loader_add_layer_env(
+        struct loader_extension_list *ext_list,
+        const struct loader_extension_list *search_list)
 {
     char *layerEnv;
-    uint32_t i, len, found_count, count = 0;
+    uint32_t len;
     char *p, *pOrig, *next, *name;
 
 #if defined(WIN32)
@@ -918,14 +986,14 @@
     layerEnv = getenv(LAYER_NAMES_ENV);
 #endif // WIN32
     if (layerEnv == NULL) {
-        return 0;
+        return;
     }
     p = malloc(strlen(layerEnv) + 1);
     if (p == NULL) {
 #if defined(WIN32)
         free(layerEnv);
 #endif // WIN32
-        return 0;
+        return;
     }
     strcpy(p, layerEnv);
 #if defined(WIN32)
@@ -933,8 +1001,7 @@
 #endif // WIN32
     pOrig = p;
 
-    while (p && *p && count < MAX_LAYER_LIBRARIES) {
-        char *lib_name[MAX_LAYER_LIBRARIES];
+    while (p && *p ) {
         //memset(&lib_name[0], 0, sizeof(const char *) * MAX_LAYER_LIBRARIES);
         next = strchr(p, PATH_SEPERATOR);
         if (next == NULL) {
@@ -946,112 +1013,59 @@
             next++;
         }
         name = basename(p);
-        if (!find_layer_extension(name, &found_count, lib_name)) {
-            p = next;
-            continue;
-        }
-
-        for (i = 0; i < found_count; i++) {
-            len = (uint32_t) strlen(name);
-            pLayerNames[count].layer_name = malloc(len + 1);
-            if (!pLayerNames[count].layer_name) {
-                free(pOrig);
-                return count;
-            }
-            strncpy((char *) pLayerNames[count].layer_name, name, len);
-            pLayerNames[count].layer_name[len] = '\0';
-            pLayerNames[count].lib_name = lib_name[i];
-            count++;
-        }
+        loader_search_ext_list_for_name(name, search_list, ext_list);
         p = next;
-
     }
 
     free(pOrig);
-    return count;
+    return;
 }
 
-static uint32_t loader_get_layer_libs(uint32_t ext_count, const char *const* ext_names, struct layer_name_pair **ppLayerNames)
-{
-    static struct layer_name_pair layerNames[MAX_LAYER_LIBRARIES];
-    char *lib_name[MAX_LAYER_LIBRARIES];
-    uint32_t found_count, count = 0;
-    bool skip;
-
-    *ppLayerNames =  &layerNames[0];
-    /* Load any layers specified in the environment first */
-    count = loader_get_layer_env(layerNames);
-
-    for (uint32_t i = 0; i < ext_count; i++) {
-        const char *pExtName = ext_names[i];
-
-        skip = false;
-        for (uint32_t j = 0; j < count; j++) {
-            if (!strcmp(pExtName, layerNames[j].layer_name) ) {
-                // Extension / Layer already on the list skip it
-                skip = true;
-                break;
-            }
-        }
-
-        if (!skip && find_layer_extension(pExtName, &found_count, lib_name)) {
-
-            for (uint32_t j = 0; j < found_count; j++) {
-                uint32_t len;
-                len = (uint32_t) strlen(pExtName);
-
-
-                layerNames[count].layer_name = malloc(len + 1);
-                if (!layerNames[count].layer_name)
-                    return count;
-                strncpy((char *) layerNames[count].layer_name, pExtName, len);
-                layerNames[count].layer_name[len] = '\0';
-                layerNames[count].lib_name = lib_name[j];
-                count++;
-            }
-        }
-    }
-
-    return count;
-}
 
 //TODO static void loader_deactivate_device_layer(device)
 
-static void loader_deactivate_instance_layer(const struct loader_instance *instance)
+static void loader_deactivate_instance_layers(struct loader_instance *instance)
 {
-    struct loader_icd *icd;
-    struct loader_layers *libs;
+    if (!instance->layer_count) {
+        return;
+    }
 
-    for (icd = instance->icds; icd; icd = icd->next) {
-        if (icd->gpus)
-            free(icd->gpus);
-        icd->gpus = NULL;
-        if (icd->loader_dispatch)
-            free(icd->loader_dispatch);
-        icd->loader_dispatch = NULL;
-        for (uint32_t j = 0; j < icd->gpu_count; j++) {
-            if (icd->layer_count[j] > 0) {
-                for (uint32_t i = 0; i < icd->layer_count[j]; i++) {
-                    libs = &(icd->layer_libs[j][i]);
-                    if (libs->lib_handle)
-                        loader_platform_close_library(libs->lib_handle);
-                    libs->lib_handle = NULL;
-                }
-                if (icd->wrappedGpus[j])
-                    free(icd->wrappedGpus[j]);
-            }
-            icd->layer_count[j] = 0;
+    /* Create instance chain of enabled layers */
+    for (uint32_t i = 0; i < instance->enabled_instance_extensions.count; i++) {
+        struct loader_extension_property *ext_prop = &instance->enabled_instance_extensions.list[i];
+
+        if (ext_prop->origin == VK_EXTENSION_ORIGIN_ICD) {
+            continue;
         }
-        icd->gpu_count = 0;
+
+        loader_remove_layer_lib(instance, ext_prop);
+
+        instance->layer_count--;
     }
 
     free(instance->wrappedInstance);
 }
 
+void loader_enable_instance_layers(struct loader_instance *inst)
+{
+    if (inst == NULL)
+        return;
+
+    /* Add any layers specified in the environment first */
+    loader_add_layer_env(&inst->enabled_instance_extensions, &loader.global_extensions);
+
+    /* Add layers / extensions specified by the application */
+    loader_add_vk_ext_to_ext_list(
+                &inst->enabled_instance_extensions,
+                inst->app_extension_count,
+                inst->app_extension_props,
+                &loader.global_extensions);
+}
+
 uint32_t loader_activate_instance_layers(struct loader_instance *inst)
 {
-    uint32_t count;
-    struct layer_name_pair *pLayerNames;
+    uint32_t layer_idx;
+
     if (inst == NULL)
         return 0;
 
@@ -1061,45 +1075,103 @@
     VkBaseLayerObject *nextInstObj;
     PFN_vkGetInstanceProcAddr nextGPA = loader_gpa_instance_internal;
 
-    count = loader_get_layer_libs(inst->extension_count, (const char *const*) inst->extension_names, &pLayerNames);
-    if (!count)
-        return 0;
-    loader_init_instance_layer_libs(inst, pLayerNames, count);
+    /*
+     * Figure out how many actual layers will need to be wrapped.
+     */
+    inst->layer_count = 0;
+    for (uint32_t i = 0; i < inst->enabled_instance_extensions.count; i++) {
+        struct loader_extension_property *ext_prop = &inst->enabled_instance_extensions.list[i];
+        if (ext_prop->origin == VK_EXTENSION_ORIGIN_LAYER) {
+            inst->layer_count++;
+        }
+    }
 
-    inst->wrappedInstance = malloc(sizeof(VkBaseLayerObject) * count);
-    if (! inst->wrappedInstance) {
-        loader_log(VK_DBG_MSG_ERROR, 0, "Failed to malloc Instance objects for layer");
+    if (!inst->layer_count) {
         return 0;
     }
-    for (int32_t i = count - 1; i >= 0; i--) {
-        nextInstObj = (inst->wrappedInstance + i);
+
+    inst->wrappedInstance = malloc(sizeof(VkBaseLayerObject)
+                                   * inst->layer_count);
+    if (!inst->wrappedInstance) {
+        loader_log(VK_DBG_REPORT_ERROR_BIT, 0, "Failed to malloc Instance objects for layer");
+        return 0;
+    }
+
+    /* Create instance chain of enabled layers */
+    layer_idx = inst->layer_count - 1;
+    for (int32_t i = inst->enabled_instance_extensions.count - 1; i >= 0; i--) {
+        struct loader_extension_property *ext_prop = &inst->enabled_instance_extensions.list[i];
+        loader_platform_dl_handle lib_handle;
+
+        /*
+         * TODO: Need to figure out how to hook in extensions implemented
+         * within the loader.
+         * What GetProcAddr do we use?
+         * How do we make the loader call first in the chain? It may not be first
+         * in the list. Does it have to be first?
+         * How does the chain for DbgCreateMsgCallback get made?
+         * Do we need to add the function pointer to the VkLayerInstanceDispatchTable?
+         * Seems like we will.
+         * What happens with more than one loader implemented extension?
+         * Issue: Process of building instance chain requires that we call GetInstanceProcAddr
+         * on the various extension components. However, if we are asking for an extension
+         * entry point we won't get it because we haven't enabled the extension yet.
+         * Must not call GPA on extensions at this time.
+         */
+        if (ext_prop->origin != VK_EXTENSION_ORIGIN_LAYER) {
+            continue;
+        }
+
+        nextInstObj = (inst->wrappedInstance + layer_idx);
         nextInstObj->pGPA = nextGPA;
         nextInstObj->baseObject = baseObj;
         nextInstObj->nextObject = nextObj;
         nextObj = (VkObject) nextInstObj;
 
         char funcStr[256];
-        snprintf(funcStr, 256, "%sGetInstanceProcAddr",inst->layer_libs[i].name);
-        if ((nextGPA = (PFN_vkGetInstanceProcAddr) loader_platform_get_proc_address(inst->layer_libs[i].lib_handle, funcStr)) == NULL)
-            nextGPA = (PFN_vkGetInstanceProcAddr) loader_platform_get_proc_address(inst->layer_libs[i].lib_handle, "vkGetInstanceProcAddr");
+        snprintf(funcStr, 256, "%sGetInstanceProcAddr", ext_prop->info.name);
+        lib_handle = loader_add_layer_lib(inst, ext_prop);
+        if ((nextGPA = (PFN_vkGetInstanceProcAddr) loader_platform_get_proc_address(lib_handle, funcStr)) == NULL)
+            nextGPA = (PFN_vkGetInstanceProcAddr) loader_platform_get_proc_address(lib_handle, "vkGetInstanceProcAddr");
         if (!nextGPA) {
-            loader_log(VK_DBG_MSG_ERROR, 0, "Failed to find vkGetInstanceProcAddr in layer %s", inst->layer_libs[i].name);
+            loader_log(VK_DBG_REPORT_ERROR_BIT, 0, "Failed to find vkGetInstanceProcAddr in layer %s", ext_prop->lib_name);
             continue;
         }
 
-        if (i == 0) {
-            loader_init_instance_dispatch_table(inst->disp, nextGPA, (VkInstance) nextObj);
-        }
-
+        layer_idx--;
     }
 
+    loader_init_instance_core_dispatch_table(inst->disp, nextGPA, (VkInstance) nextObj);
+
     return inst->layer_count;
 }
 
-uint32_t loader_activate_device_layers(VkDevice device, struct loader_icd *icd, uint32_t gpu_index, uint32_t ext_count, const char *const* ext_names)
+void loader_enable_device_layers(struct loader_icd *icd, uint32_t gpu_index)
+{
+    if (icd == NULL)
+        return;
+
+    /* Add any layers specified in the environment first */
+    loader_add_layer_env(&icd->enabled_device_extensions[gpu_index], &loader.global_extensions);
+
+    /* Add layers / extensions specified by the application */
+    loader_add_vk_ext_to_ext_list(
+                &icd->enabled_device_extensions[gpu_index],
+                icd->app_extension_count[gpu_index],
+                icd->app_extension_props[gpu_index],
+                &loader.global_extensions);
+}
+
+extern uint32_t loader_activate_device_layers(
+            VkDevice device,
+            struct loader_icd *icd,
+            uint32_t gpu_index,
+            uint32_t ext_count,
+            const VkExtensionProperties *ext_props)
 {
     uint32_t count;
-    struct layer_name_pair *pLayerNames;
+    uint32_t layer_idx;
+
     if (!icd)
         return 0;
     assert(gpu_index < MAX_GPUS_FOR_LAYER);
@@ -1111,17 +1183,32 @@
         VkBaseLayerObject *nextGpuObj;
         PFN_vkGetDeviceProcAddr nextGPA = icd->GetDeviceProcAddr;
 
-        count = loader_get_layer_libs(ext_count, ext_names, &pLayerNames);
+        count = 0;
+        for (uint32_t i = 0; i < icd->enabled_device_extensions[gpu_index].count; i++) {
+            struct loader_extension_property *ext_prop = &icd->enabled_device_extensions[gpu_index].list[i];
+            if (ext_prop->origin == VK_EXTENSION_ORIGIN_LAYER) {
+                count++;
+            }
+        }
         if (!count)
             return 0;
-        loader_init_device_layer_libs(icd, gpu_index, pLayerNames, count);
+
+        icd->layer_count[gpu_index] = count;
 
         icd->wrappedGpus[gpu_index] = malloc(sizeof(VkBaseLayerObject) * icd->layer_count[gpu_index]);
         if (! icd->wrappedGpus[gpu_index]) {
-                loader_log(VK_DBG_MSG_ERROR, 0, "Failed to malloc Gpu objects for layer");
+                loader_log(VK_DBG_REPORT_ERROR_BIT, 0, "Failed to malloc Gpu objects for layer");
                 return 0;
         }
+        layer_idx = count - 1;
         for (int32_t i = icd->layer_count[gpu_index] - 1; i >= 0; i--) {
+            struct loader_extension_property *ext_prop = &icd->enabled_device_extensions[gpu_index].list[i];
+            loader_platform_dl_handle lib_handle;
+
+            if (ext_prop->origin != VK_EXTENSION_ORIGIN_LAYER) {
+                continue;
+            }
+
             nextGpuObj = (icd->wrappedGpus[gpu_index] + i);
             nextGpuObj->pGPA = nextGPA;
             nextGpuObj->baseObject = baseObj;
@@ -1129,43 +1216,33 @@
             nextObj = (VkObject) nextGpuObj;
 
             char funcStr[256];
-            snprintf(funcStr, 256, "%sGetDeviceProcAddr",icd->layer_libs[gpu_index][i].name);
-            if ((nextGPA = (PFN_vkGetDeviceProcAddr) loader_platform_get_proc_address(icd->layer_libs[gpu_index][i].lib_handle, funcStr)) == NULL)
-                nextGPA = (PFN_vkGetDeviceProcAddr) loader_platform_get_proc_address(icd->layer_libs[gpu_index][i].lib_handle, "vkGetDeviceProcAddr");
+            snprintf(funcStr, 256, "%sGetDeviceProcAddr", ext_prop->info.name);
+            lib_handle = loader_add_layer_lib((struct loader_instance *) (icd->instance), ext_prop);
+            if ((nextGPA = (PFN_vkGetDeviceProcAddr) loader_platform_get_proc_address(lib_handle, funcStr)) == NULL)
+                nextGPA = (PFN_vkGetDeviceProcAddr) loader_platform_get_proc_address(lib_handle, "vkGetDeviceProcAddr");
             if (!nextGPA) {
-                loader_log(VK_DBG_MSG_ERROR, 0, "Failed to find vkGetDeviceProcAddr in layer %s", icd->layer_libs[gpu_index][i].name);
+                loader_log(VK_DBG_REPORT_ERROR_BIT, 0, "Failed to find vkGetDeviceProcAddr in layer %s", ext_prop->info.name);
                 continue;
             }
 
-            if (i == 0) {
-                loader_init_device_dispatch_table(icd->loader_dispatch + gpu_index, nextGPA, (VkPhysicalDevice) nextObj);
-                //Insert the new wrapped objects into the list with loader object at head
-                nextGpuObj = icd->wrappedGpus[gpu_index] + icd->layer_count[gpu_index] - 1;
-                nextGpuObj->nextObject = baseObj;
-                nextGpuObj->pGPA = icd->GetDeviceProcAddr;
-            }
+            layer_idx--;
+        }
 
-        }
-    }
-    else {
-        //make sure requested Layers matches currently activated Layers
-        count = loader_get_layer_libs(ext_count, ext_names, &pLayerNames);
-        for (uint32_t i = 0; i < count; i++) {
-            if (strcmp(icd->layer_libs[gpu_index][i].name, pLayerNames[i].layer_name)) {
-                loader_log(VK_DBG_MSG_ERROR, 0, "Layers activated != Layers requested");
-                break;
-            }
-        }
-        if (count != icd->layer_count[gpu_index]) {
-            loader_log(VK_DBG_MSG_ERROR, 0, "Number of Layers activated != number requested");
-        }
+        loader_init_device_dispatch_table(icd->loader_dispatch + gpu_index, nextGPA, (VkPhysicalDevice) nextObj);
+        //Insert the new wrapped objects into the list with loader object at head
+        nextGpuObj = icd->wrappedGpus[gpu_index] + icd->layer_count[gpu_index] - 1;
+        nextGpuObj->nextObject = baseObj;
+        nextGpuObj->pGPA = icd->GetDeviceProcAddr;
+
+    } else {
+        // TODO: Check that active layers match requested?
     }
     return icd->layer_count[gpu_index];
 }
 
 VkResult loader_CreateInstance(
-        const VkInstanceCreateInfo*         pCreateInfo,
-        VkInstance*                           pInstance)
+        const VkInstanceCreateInfo*     pCreateInfo,
+        VkInstance*                     pInstance)
 {
     struct loader_instance *ptr_instance = *(struct loader_instance **) pInstance;
     struct loader_scanned_icds *scanned_icds;
@@ -1181,9 +1258,9 @@
             if (res != VK_SUCCESS)
             {
                 ptr_instance->icds = ptr_instance->icds->next;
-                loader_icd_destroy(icd);
+                loader_icd_destroy(ptr_instance, icd);
                 icd->instance = VK_NULL_HANDLE;
-                loader_log(VK_DBG_MSG_WARNING, 0,
+                loader_log(VK_DBG_REPORT_WARN_BIT, 0,
                         "ICD ignored: failed to CreateInstance on device");
             } else
             {
@@ -1197,7 +1274,7 @@
         return VK_ERROR_INCOMPATIBLE_DRIVER;
     }
 
-    return VK_SUCCESS;
+    return res;
 }
 
 VkResult loader_DestroyInstance(
@@ -1206,7 +1283,6 @@
     struct loader_instance *ptr_instance = (struct loader_instance *) instance;
     struct loader_icd *icds = ptr_instance->icds;
     VkResult res;
-    uint32_t i;
 
     // Remove this instance from the list of instances:
     struct loader_instance *prev = NULL;
@@ -1214,10 +1290,7 @@
     while (next != NULL) {
         if (next == ptr_instance) {
             // Remove this instance from the list:
-            for (i = 0; i < ptr_instance->extension_count; i++) {
-                free(ptr_instance->extension_names[i]);
-            }
-            free(ptr_instance->disp);
+            free(ptr_instance->app_extension_props);
             if (prev)
                 prev->next = next->next;
             else
@@ -1232,13 +1305,14 @@
         return VK_ERROR_INVALID_HANDLE;
     }
 
-    loader_deactivate_instance_layer(ptr_instance);
+    loader_deactivate_instance_layers(ptr_instance);
+    loader_destroy_ext_list(&ptr_instance->enabled_instance_extensions);
 
     while (icds) {
         if (icds->instance) {
             res = icds->DestroyInstance(icds->instance);
             if (res != VK_SUCCESS)
-                loader_log(VK_DBG_MSG_WARNING, 0,
+                loader_log(VK_DBG_REPORT_WARN_BIT, 0,
                             "ICD ignored: failed to DestroyInstance on device");
         }
         icds->instance = VK_NULL_HANDLE;
@@ -1264,9 +1338,7 @@
     icd = ptr_instance->icds;
     if (pPhysicalDevices == NULL) {
         while (icd) {
-            res = icd->EnumeratePhysicalDevices(
-                                                icd->instance,
-                                                &n, NULL);
+            res = icd->EnumeratePhysicalDevices(icd->instance, &n, NULL);
             if (res != VK_SUCCESS)
                 return res;
             icd->gpu_count = n;
@@ -1351,20 +1423,37 @@
     uint32_t gpu_index;
     struct loader_icd *icd = loader_get_icd((const VkBaseLayerObject *) gpu, &gpu_index);
     VkResult res = VK_ERROR_INITIALIZATION_FAILED;
-    struct loader_instance *ptr_instance;
 
-    ptr_instance = loader.instances;
     if (icd->CreateDevice) {
         res = icd->CreateDevice(gpu, pCreateInfo, pDevice);
-        if (res == VK_SUCCESS) {
-            VkLayerDispatchTable *dev_disp = icd->loader_dispatch + gpu_index;
-            loader_init_dispatch(*pDevice, dev_disp);
+        if (res != VK_SUCCESS) {
+            return res;
         }
+
+        VkLayerDispatchTable *dev_disp = icd->loader_dispatch + gpu_index;
+        loader_init_dispatch(*pDevice, dev_disp);
+
+        icd->app_extension_count[gpu_index] = pCreateInfo->extensionCount;
+        icd->app_extension_props[gpu_index] = (VkExtensionProperties *) malloc(sizeof(VkExtensionProperties) * pCreateInfo->extensionCount);
+        if (icd->app_extension_props[gpu_index] == NULL && (icd->app_extension_count[gpu_index] > 0)) {
+            return VK_ERROR_OUT_OF_HOST_MEMORY;
+        }
+
+        /* Make local copy of extension list */
+        if (icd->app_extension_count[gpu_index] > 0 && icd->app_extension_props[gpu_index] != NULL) {
+            memcpy(icd->app_extension_props[gpu_index], pCreateInfo->pEnabledExtensions, sizeof(VkExtensionProperties) * pCreateInfo->extensionCount);
+        }
+
+        // TODO: Add dependency check here.
+
+        loader_enable_device_layers(icd, gpu_index);
+
         //TODO fix this extension parameters once support GetDeviceExtensionInfo()
         // don't know which instance we are on with this call
 
-        loader_activate_device_layers(*pDevice, icd, gpu_index, ptr_instance->extension_count,
-                            (const char *const*) ptr_instance->extension_names);
+        loader_activate_device_layers(*pDevice, icd, gpu_index,
+                                      icd->app_extension_count[gpu_index],
+                                      icd->app_extension_props[gpu_index]);
     }
 
     return res;
@@ -1374,17 +1463,24 @@
 {
     if (instance == VK_NULL_HANDLE)
         return NULL;
+
     void *addr;
     /* get entrypoint addresses that are global (in the loader)*/
     addr = globalGetProcAddr(pName);
     if (addr)
         return addr;
 
+    struct loader_instance *ptr_instance = (struct loader_instance *) instance;
+
+    addr = debug_report_instance_gpa(ptr_instance, pName);
+    if (addr) {
+        return addr;
+    }
+
     /* return any extension global entrypoints */
-    bool wsi_enabled;
-    addr = wsi_lunarg_GetInstanceProcAddr(instance, pName, &wsi_enabled);
+    addr = wsi_lunarg_GetInstanceProcAddr(instance, pName);
     if (addr)
-        return (wsi_enabled) ? addr : NULL;
+        return (ptr_instance->wsi_lunarg_enabled) ? addr : NULL;
 
     /* return the instance dispatch table entrypoint for extensions */
     const VkLayerInstanceDispatchTable *disp_table = * (VkLayerInstanceDispatchTable **) instance;
@@ -1414,10 +1510,10 @@
     }
 
     /* return any extension device entrypoints the loader knows about */
-    bool wsi_enabled;
-    addr = wsi_lunarg_GetDeviceProcAddr(device, pName, &wsi_enabled);
+    addr = wsi_lunarg_GetDeviceProcAddr(device, pName);
+    /* TODO: Where does device wsi_enabled go? */
     if (addr)
-        return (wsi_enabled) ? addr : NULL;
+        return addr;
 
     /* return the dispatch table entrypoint for the fastest case */
     const VkLayerDispatchTable *disp_table = * (VkLayerDispatchTable **) device;
@@ -1446,7 +1542,6 @@
                                                size_t*  pDataSize,
                                                void*    pData)
 {
-    VkExtensionProperties *ext_props;
     uint32_t *count;
     /* Scan/discover all ICD libraries in a single-threaded manner */
     loader_platform_thread_once(&once_icd, loader_icd_scan);
@@ -1467,22 +1562,20 @@
             if (pData == NULL)
                 return VK_SUCCESS;
             count = (uint32_t *) pData;
-            *count = loader.scanned_ext_list_count;
+            *count = loader.global_extensions.count;
             break;
         case VK_EXTENSION_INFO_TYPE_PROPERTIES:
             *pDataSize = sizeof(VkExtensionProperties);
             if (pData == NULL)
                 return VK_SUCCESS;
-            if (extensionIndex >= loader.scanned_ext_list_count)
+            if (extensionIndex >= loader.global_extensions.count)
                 return VK_ERROR_INVALID_VALUE;
-            ext_props = (VkExtensionProperties *) pData;
-            ext_props->version = loader.scanned_ext_list[extensionIndex]->version;
-            strncpy(ext_props->extName, loader.scanned_ext_list[extensionIndex]->extName
-                                            , VK_MAX_EXTENSION_NAME);
-            ext_props->extName[VK_MAX_EXTENSION_NAME - 1] = '\0';
+            memcpy((VkExtensionProperties *) pData,
+                   &loader.global_extensions.list[extensionIndex],
+                   sizeof(VkExtensionProperties));
             break;
         default:
-            loader_log(VK_DBG_MSG_WARNING, 0, "Invalid infoType in vkGetGlobalExtensionInfo");
+            loader_log(VK_DBG_REPORT_WARN_BIT, 0, "Invalid infoType in vkGetGlobalExtensionInfo");
             return VK_ERROR_INVALID_VALUE;
     };
 
@@ -1506,87 +1599,6 @@
     return res;
 }
 
-VkResult loader_EnumerateLayers(
-        VkPhysicalDevice                        gpu,
-        size_t                                  maxStringSize,
-        size_t*                                 pLayerCount,
-        char* const*                            pOutLayers,
-        void*                                   pReserved)
-{
-    size_t maxLayerCount;
-    uint32_t gpu_index;
-    size_t count = 0;
-    char *lib_name;
-    struct loader_icd *icd = loader_get_icd((const VkBaseLayerObject *) gpu, &gpu_index);
-    loader_platform_dl_handle handle;
-    PFN_vkEnumerateLayers fpEnumerateLayers;
-    char layer_buf[16][256];
-    char * layers[16];
-
-    if (pLayerCount == NULL || pOutLayers == NULL)
-        return VK_ERROR_INVALID_POINTER;
-
-    maxLayerCount = *pLayerCount;
-
-    if (!icd)
-        return VK_ERROR_UNAVAILABLE;
-
-    for (int i = 0; i < 16; i++)
-         layers[i] = &layer_buf[i][0];
-
-    for (unsigned int j = 0; j < loader.scanned_layer_count && count < maxLayerCount; j++) {
-        lib_name = loader.scanned_layers[j].name;
-        // Used to call: dlopen(*lib_name, RTLD_LAZY)
-        if ((handle = loader_platform_open_library(lib_name)) == NULL)
-            continue;
-        if ((fpEnumerateLayers = loader_platform_get_proc_address(handle, "vkEnumerateLayers")) == NULL) {
-            //use default layer name based on library name VK_LAYER_LIBRARY_PREFIX<name>.VK_LIBRARY_SUFFIX
-            char *pEnd, *cpyStr;
-            size_t siz;
-            loader_platform_close_library(handle);
-            lib_name = basename(lib_name);
-            pEnd = strrchr(lib_name, '.');
-            siz = (int) (pEnd - lib_name - strlen(VK_LAYER_LIBRARY_PREFIX) + 1);
-            if (pEnd == NULL || siz <= 0)
-                continue;
-            cpyStr = malloc(siz);
-            if (cpyStr == NULL) {
-                free(cpyStr);
-                continue;
-            }
-            strncpy(cpyStr, lib_name + strlen(VK_LAYER_LIBRARY_PREFIX), siz);
-            cpyStr[siz - 1] = '\0';
-            if (siz > maxStringSize)
-                siz = (int) maxStringSize;
-            strncpy((char *) (pOutLayers[count]), cpyStr, siz);
-            pOutLayers[count][siz - 1] = '\0';
-            count++;
-            free(cpyStr);
-        } else {
-            size_t cnt = 16; /* only allow 16 layers, for now */
-            uint32_t n;
-            VkResult res;
-            n = (uint32_t) ((maxStringSize < 256) ? maxStringSize : 256);
-            res = fpEnumerateLayers((VkPhysicalDevice) NULL, n, &cnt, layers, (char *) icd->gpus + gpu_index);
-            loader_platform_close_library(handle);
-            if (res != VK_SUCCESS)
-                continue;
-            if (cnt + count > maxLayerCount)
-                cnt = maxLayerCount - count;
-            for (uint32_t i = (uint32_t) count; i < cnt + count; i++) {
-                strncpy((char *) (pOutLayers[i]), (char *) layers[i - count], n);
-                if (n > 0)
-                    pOutLayers[i - count][n - 1] = '\0';
-            }
-            count += cnt;
-        }
-    }
-
-    *pLayerCount = count;
-
-    return VK_SUCCESS;
-}
-
 VkResult loader_GetMultiDeviceCompatibility(
         VkPhysicalDevice                        gpu0,
         VkPhysicalDevice                        gpu1,
@@ -1601,109 +1613,3 @@
 
     return res;
 }
-
-VkResult loader_DbgRegisterMsgCallback(VkInstance instance, VK_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback, void* pUserData)
-{
-    const struct loader_icd *icd;
-    struct loader_instance *inst;
-    VkResult res;
-
-    if (instance == VK_NULL_HANDLE)
-        return VK_ERROR_INVALID_HANDLE;
-
-    assert(loader.icds_scanned);
-
-    for (inst = loader.instances; inst; inst = inst->next) {
-        if ((VkInstance) inst == instance)
-            break;
-    }
-
-    if (inst == VK_NULL_HANDLE)
-        return VK_ERROR_INVALID_HANDLE;
-
-    for (icd = inst->icds; icd; icd = icd->next) {
-        if (!icd->DbgRegisterMsgCallback)
-            continue;
-        res = icd->DbgRegisterMsgCallback(icd->instance,
-                                                   pfnMsgCallback, pUserData);
-        if (res != VK_SUCCESS)
-            break;
-    }
-
-
-    /* roll back on errors */
-    if (icd) {
-        for (const struct loader_icd *tmp = inst->icds; tmp != icd;
-                                                      tmp = tmp->next) {
-            if (!tmp->DbgUnregisterMsgCallback)
-                continue;
-            tmp->DbgUnregisterMsgCallback(tmp->instance,
-                                                        pfnMsgCallback);
-        }
-
-        return res;
-    }
-
-    return VK_SUCCESS;
-}
-
-VkResult loader_DbgUnregisterMsgCallback(VkInstance instance, VK_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback)
-{
-    VkResult res = VK_SUCCESS;
-    struct loader_instance *inst;
-    if (instance == VK_NULL_HANDLE)
-        return VK_ERROR_INVALID_HANDLE;
-
-    assert(loader.icds_scanned);
-
-    for (inst = loader.instances; inst; inst = inst->next) {
-        if ((VkInstance) inst == instance)
-            break;
-    }
-
-    if (inst == VK_NULL_HANDLE)
-        return VK_ERROR_INVALID_HANDLE;
-
-    for (const struct loader_icd * icd = inst->icds; icd; icd = icd->next) {
-        VkResult r;
-        if (!icd->DbgUnregisterMsgCallback)
-            continue;
-        r = icd->DbgUnregisterMsgCallback(icd->instance, pfnMsgCallback);
-        if (r != VK_SUCCESS) {
-            res = r;
-        }
-    }
-    return res;
-}
-
-VkResult loader_DbgSetGlobalOption(VkInstance instance, VK_DBG_GLOBAL_OPTION dbgOption, size_t dataSize, const void* pData)
-{
-    VkResult res = VK_SUCCESS;
-    struct loader_instance *inst;
-    if (instance == VK_NULL_HANDLE)
-        return VK_ERROR_INVALID_HANDLE;
-
-    assert(loader.icds_scanned);
-
-    for (inst = loader.instances; inst; inst = inst->next) {
-        if ((VkInstance) inst == instance)
-            break;
-    }
-
-    if (inst == VK_NULL_HANDLE)
-        return VK_ERROR_INVALID_HANDLE;
-    for (const struct loader_icd * icd = inst->icds; icd; icd = icd->next) {
-            VkResult r;
-            if (!icd->DbgSetGlobalOption)
-                continue;
-            r = icd->DbgSetGlobalOption(icd->instance, dbgOption,
-                                                           dataSize, pData);
-            /* unfortunately we cannot roll back */
-            if (r != VK_SUCCESS) {
-               res = r;
-            }
-    }
-
-    return res;
-}
-
diff --git a/loader/loader.h b/loader/loader.h
index e7a4618..73b780f 100644
--- a/loader/loader.h
+++ b/loader/loader.h
@@ -29,7 +29,7 @@
 #define LOADER_H
 
 #include <vulkan.h>
-#include <vkDbg.h>
+#include <vk_debug_report_lunarg.h>
 #include <vk_wsi_lunarg.h>
 #include <vkLayer.h>
 #include <vkIcd.h>
@@ -46,15 +46,39 @@
 #define MAX_LAYER_LIBRARIES 64
 #define MAX_GPUS_FOR_LAYER 16
 
-struct loader_scanned_layers {
-    char *name;
-    uint32_t extension_count;
-    struct extension_property *extensions;
+enum extension_origin {
+    VK_EXTENSION_ORIGIN_ICD,
+    VK_EXTENSION_ORIGIN_LAYER,
+    VK_EXTENSION_ORIGIN_LOADER
 };
 
-struct loader_layers {
-    loader_platform_dl_handle lib_handle;
-    char name[256];
+struct loader_extension_property {
+    VkExtensionProperties info;
+    const char *lib_name;
+    enum extension_origin origin;
+    bool hosted;        // does the extension reside in one driver/layer
+};
+
+struct loader_extension_list {
+    size_t capacity;
+    uint32_t count;
+    struct loader_extension_property *list;
+};
+
+struct loader_scanned_layers {
+    char *lib_name;
+
+    /* cache of global extensions for a specific layer */
+//    uint32_t global_extension_count;
+//    struct loader_extension_property *global_extensions;
+    struct loader_extension_list global_extension_list;
+
+    /*
+     * cache of device extensions for a specific layer,
+     * filled in at CreateInstance time
+     */
+    uint32_t device_ext_count;
+    struct loader_extension_property *device_ext_list;
 };
 
 struct loader_icd {
@@ -62,7 +86,6 @@
 
     VkLayerDispatchTable *loader_dispatch;
     uint32_t layer_count[MAX_GPUS_FOR_LAYER];
-    struct loader_layers layer_libs[MAX_GPUS_FOR_LAYER][MAX_LAYER_LIBRARIES];
     VkBaseLayerObject *wrappedGpus[MAX_GPUS_FOR_LAYER];
     uint32_t gpu_count;
     VkBaseLayerObject *gpus;
@@ -73,39 +96,150 @@
     PFN_vkGetPhysicalDeviceInfo GetPhysicalDeviceInfo;
     PFN_vkCreateDevice CreateDevice;
     PFN_vkGetPhysicalDeviceExtensionInfo GetPhysicalDeviceExtensionInfo;
-    PFN_vkEnumerateLayers EnumerateLayers;
     PFN_vkGetMultiDeviceCompatibility GetMultiDeviceCompatibility;
-    PFN_vkDbgRegisterMsgCallback DbgRegisterMsgCallback;
-    PFN_vkDbgUnregisterMsgCallback DbgUnregisterMsgCallback;
-    PFN_vkDbgSetGlobalOption DbgSetGlobalOption;
     PFN_vkGetDisplayInfoWSI GetDisplayInfoWSI;
+    PFN_vkDbgCreateMsgCallback DbgCreateMsgCallback;
+    PFN_vkDbgDestroyMsgCallback DbgDestroyMsgCallback;
     struct loader_icd *next;
+
+    uint32_t  app_extension_count[MAX_GPUS_FOR_LAYER];
+    VkExtensionProperties *app_extension_props[MAX_GPUS_FOR_LAYER];
+
+    struct loader_extension_list enabled_device_extensions[MAX_GPUS_FOR_LAYER];
 };
 
 struct loader_instance {
     VkLayerInstanceDispatchTable *disp; // must be first entry in structure
 
     uint32_t layer_count;
-    struct loader_layers layer_libs[MAX_LAYER_LIBRARIES];
+//    struct loader_layers layer_libs[MAX_LAYER_LIBRARIES];
     VkBaseLayerObject *wrappedInstance;
     uint32_t total_gpu_count;
+    uint32_t total_icd_count;
     struct loader_icd *icds;
     struct loader_instance *next;
-    uint32_t  extension_count;
-    char **extension_names;
+
+    /* TODO: Should keep track of application provided allocation functions */
+
+    /*
+     * CreateMsgCallback is global and needs to be
+     * applied to all layers and ICDs.
+     * What happens if a layer is enabled on both the instance chain
+     * as well as the device chain and a call to CreateMsgCallback is made?
+     * Do we need to make sure that each layer / driver only gets called once?
+     * Should a layer implementing support for CreateMsgCallback only be allowed (?)
+     * to live on one chain? Or maybe make it the application's responsibility.
+     * If the app enables DRAW_STATE on at both CreateInstance time and CreateDevice
+     * time, CreateMsgCallback will call the DRAW_STATE layer twice. Once via
+     * the instance chain and once via the device chain.
+     * The loader should only return the DEBUG_REPORT extension as supported
+     * for the GetGlobalExtensionSupport call. That should help eliminate one
+     * duplication.
+     * Since the instance chain requires us iterating over the available ICDs
+     * and each ICD will have it's own unique MsgCallback object we need to
+     * track those objects to give back the right one.
+     * This also implies that the loader has to intercept vkDestroyObject and
+     * if the extension is enabled and the object type is a MsgCallback then
+     * we must translate the object into the proper ICD specific ones.
+     * DestroyObject works on a device chain. Should not be what's destroying
+     * the MsgCallback object. That needs to be an instance thing. So, since
+     * we used an instance to create it, we need a custom Destroy that also
+     * takes an instance. That way we can iterate over the ICDs properly.
+     * Example use:
+     * CreateInstance: DEBUG_REPORT
+     *   Loader will create instance chain with enabled extensions.
+     *   TODO: Should validation layers be enabled here? If not, they will not be in the instance chain.
+     * fn = GetProcAddr(INSTANCE, "vkCreateMsgCallback") -> point to loader's vkCreateMsgCallback
+     * App creates a callback object: fn(..., &MsgCallbackObject1)
+     * Have only established the instance chain so far. Loader will call the instance chain.
+     * Each layer in the instance chain will call down to the next layer, terminating with
+     * the CreateMsgCallback loader terminator function that creates the actual MsgCallbackObject1 object.
+     * The loader CreateMsgCallback terminator will iterate over the ICDs.
+     * Calling each ICD that supports vkCreateMsgCallback and collect answers in icd_msg_callback_map here.
+     * As result is sent back up the chain each layer has opportunity to record the callback operation and
+     * appropriate MsgCallback object.
+     * ...
+     * Any reports matching the flags set in MsgCallbackObject1 will generate the defined callback behavior
+     * in the layer / ICD that initiated that report.
+     * ...
+     * CreateDevice: MemTracker:...
+     * App does not include DEBUG_REPORT as that is a global extension.
+     * TODO: GetExtensionSupport must not report DEBUG_REPORT when using instance.
+     * App MUST include any desired validation layers or they will not participate in the device call chain.
+     * App creates a callback object: fn(..., &MsgCallbackObject2)
+     * Loader's vkCreateMsgCallback is called.
+     * Loader sends call down instance chain - this is a global extension - any validation layer that was
+     * enabled at CreateInstance will be able to register the callback. Loader will iterate over the ICDs and
+     * will record the ICD's version of the MsgCallback2 object here.
+     * ...
+     * Any report will go to the layer's report function and it will check the flags for MsgCallbackObject1
+     * and MsgCallbackObject2 and take the appropriate action as indicated by the app.
+     * ...
+     * App calls vkDestroyMsgCallback( MsgCallbackObject1 )
+     * Loader's DestroyMsgCallback is where call starts. DestroyMsgCallback will be sent down instance chain
+     * ending in the loader's DestroyMsgCallback terminator which will iterate over the ICD's destroying each
+     * ICD version of that MsgCallback object and then destroy the loader's version of the object.
+     * Any reports generated after this will only have MsgCallbackObject2 available.
+     */
+    struct loader_msg_callback_map_entry *icd_msg_callback_map;
+
+    struct loader_extension_list enabled_instance_extensions;
+
+    uint32_t  app_extension_count;
+    VkExtensionProperties *app_extension_props;
+
+    bool debug_report_enabled;
+    bool wsi_lunarg_enabled;
+    VkLayerDbgFunctionNode *DbgFunctionHead;
+};
+
+struct loader_lib_info {
+    const char *lib_name;
+    uint32_t ref_count;
+    loader_platform_dl_handle lib_handle;
 };
 
 struct loader_struct {
     struct loader_instance *instances;
     bool icds_scanned;
     struct loader_scanned_icds *scanned_icd_list;
-    bool layer_scanned;
+    bool layers_scanned;
+
+    unsigned int loaded_layer_lib_count;
+    struct loader_lib_info *loaded_layer_lib_list;
+
     char *layer_dirs;
-    unsigned int scanned_layer_count;
-    struct loader_scanned_layers scanned_layers[MAX_LAYER_LIBRARIES];
+
+    /* TODO: eliminate fixed limit */
+    unsigned int scanned_layer_count;   // indicate number of scanned layers
     size_t scanned_ext_list_capacity;
-    uint32_t scanned_ext_list_count;      // coalesced from all layers/drivers
-    struct extension_property **scanned_ext_list;
+    struct loader_scanned_layers scanned_layers[MAX_LAYER_LIBRARIES];
+
+    /* Keep track of all the extensions available via GetGlobalExtensionInfo */
+    struct loader_extension_list global_extensions;
+};
+
+struct loader_scanned_icds {
+    char *lib_name;
+    loader_platform_dl_handle handle;
+
+    PFN_vkCreateInstance CreateInstance;
+    PFN_vkDestroyInstance DestroyInstance;
+    PFN_vkEnumeratePhysicalDevices EnumeratePhysicalDevices;
+    PFN_vkGetGlobalExtensionInfo GetGlobalExtensionInfo;
+    PFN_vkGetPhysicalDeviceExtensionInfo GetPhysicalDeviceExtensionInfo;
+    VkInstance instance;
+    struct loader_scanned_icds *next;
+
+    /* cache of global extensions for specific ICD */
+    struct loader_extension_list global_extension_list;
+
+    /*
+     * cache of device extensions for specific ICD,
+     * filled in at CreateInstance time
+     */
+    uint32_t device_extension_count;
+    struct loader_extension_property *device_extensions;
 };
 
 static inline void loader_set_dispatch(VkObject obj, const void *data)
@@ -140,6 +274,15 @@
 extern LOADER_PLATFORM_THREAD_ONCE_DEFINITION(once_exts);
 extern VkLayerInstanceDispatchTable instance_disp;
 
+struct loader_msg_callback_map_entry {
+    VkDbgMsgCallback icd_obj;
+    VkDbgMsgCallback loader_obj;
+};
+
+bool compare_vk_extension_properties(
+        const VkExtensionProperties*            op1,
+        const VkExtensionProperties*            op2);
+
 /* instance layer chain termination entrypoint definitions */
 VkResult loader_CreateInstance(
         const VkInstanceCreateInfo*             pCreateInfo,
@@ -190,28 +333,23 @@
         VkPhysicalDevice                        gpu1,
         VkPhysicalDeviceCompatibilityInfo*      pInfo);
 
-VkResult loader_DbgRegisterMsgCallback(
-        VkInstance                              instance,
-        VK_DBG_MSG_CALLBACK_FUNCTION            pfnMsgCallback,
-        void*                                   pUserData);
+/* helper function definitions */
+bool has_vk_extension_property(
+        const VkExtensionProperties *vk_ext_prop,
+        const struct loader_extension_list *ext_list);
 
-VkResult loader_DbgUnregisterMsgCallback(
-        VkInstance                              instance,
-        VK_DBG_MSG_CALLBACK_FUNCTION            pfnMsgCallback);
+void loader_add_to_ext_list(
+        struct loader_extension_list *ext_list,
+        uint32_t prop_list_count,
+        const struct loader_extension_property *props);
 
-VkResult loader_DbgSetGlobalOption(
-        VkInstance                              instance,
-        VK_DBG_GLOBAL_OPTION                    dbgOption,
-        size_t                                  dataSize,
-        const void*                             pData);
+void loader_enable_instance_layers(struct loader_instance *inst);
 
-
-
-/* function definitions */
-bool loader_is_extension_scanned(const char *name);
+bool loader_is_extension_scanned(const VkExtensionProperties *ext_prop);
 void loader_icd_scan(void);
 void layer_lib_scan(void);
 void loader_coalesce_extensions(void);
+
 struct loader_icd * loader_get_icd(const VkBaseLayerObject *gpu,
                                    uint32_t *gpu_index);
 uint32_t loader_activate_instance_layers(struct loader_instance *inst);
diff --git a/loader/table_ops.h b/loader/table_ops.h
index adcc42a..10fadb2 100644
--- a/loader/table_ops.h
+++ b/loader/table_ops.h
@@ -136,10 +136,7 @@
     table->CreateRenderPass = (PFN_vkCreateRenderPass) gpa(dev, "vkCreateRenderPass");
     table->CmdBeginRenderPass = (PFN_vkCmdBeginRenderPass) gpa(dev, "vkCmdBeginRenderPass");
     table->CmdEndRenderPass = (PFN_vkCmdEndRenderPass) gpa(dev, "vkCmdEndRenderPass");
-    table->DbgSetValidationLevel = (PFN_vkDbgSetValidationLevel) gpa(dev, "vkDbgSetValidationLevel");
-    table->DbgSetMessageFilter = (PFN_vkDbgSetMessageFilter) gpa(dev, "vkDbgSetMessageFilter");
     table->DbgSetObjectTag = (PFN_vkDbgSetObjectTag) gpa(dev, "vkDbgSetObjectTag");
-    table->DbgSetDeviceOption = (PFN_vkDbgSetDeviceOption) gpa(dev, "vkDbgSetDeviceOption");
     table->CmdDbgMarkerBegin = (PFN_vkCmdDbgMarkerBegin) gpa(dev, "vkCmdDbgMarkerBegin");
     table->CmdDbgMarkerEnd = (PFN_vkCmdDbgMarkerEnd) gpa(dev, "vkCmdDbgMarkerEnd");
 //TODO move into it's own table
@@ -365,14 +362,8 @@
         return (void *) table->CmdBeginRenderPass;
     if (!strcmp(name, "CmdEndRenderPass"))
         return (void *) table->CmdEndRenderPass;
-    if (!strcmp(name, "DbgSetValidationLevel"))
-        return (void *) table->DbgSetValidationLevel;
-    if (!strcmp(name, "DbgSetMessageFilter"))
-        return (void *) table->DbgSetMessageFilter;
     if (!strcmp(name, "DbgSetObjectTag"))
         return (void *) table->DbgSetObjectTag;
-    if (!strcmp(name, "DbgSetDeviceOption"))
-        return (void *) table->DbgSetDeviceOption;
     if (!strcmp(name, "CmdDbgMarkerBegin"))
         return (void *) table->CmdDbgMarkerBegin;
     if (!strcmp(name, "CmdDbgMarkerEnd"))
@@ -390,7 +381,7 @@
     return NULL;
 }
 
-static inline void loader_init_instance_dispatch_table(VkLayerInstanceDispatchTable *table,
+static inline void loader_init_instance_core_dispatch_table(VkLayerInstanceDispatchTable *table,
                                                 PFN_vkGetInstanceProcAddr gpa,
                                                 VkInstance inst)
 {
@@ -402,13 +393,11 @@
     table->CreateDevice = (PFN_vkCreateDevice) gpa(inst, "vkCreateDevice");
     table->GetGlobalExtensionInfo = (PFN_vkGetGlobalExtensionInfo) gpa(inst,"vkGetGlobalExtensionInfo");
     table->GetPhysicalDeviceExtensionInfo = (PFN_vkGetPhysicalDeviceExtensionInfo) gpa(inst, "vkGetPhysicalDeviceExtensionInfo");
-    table->EnumerateLayers = (PFN_vkEnumerateLayers) gpa(inst, "vkEnumerateLayers");
     table->GetMultiDeviceCompatibility = (PFN_vkGetMultiDeviceCompatibility) gpa(inst, "vkGetMultiDeviceCompatibility");
-    table->DbgRegisterMsgCallback = (PFN_vkDbgRegisterMsgCallback) gpa(inst, "vkDbgRegisterMsgCallback");
-    table->DbgUnregisterMsgCallback = (PFN_vkDbgUnregisterMsgCallback) gpa(inst, "vkDbgUnregisterMsgCallback");
-    table->DbgSetGlobalOption = (PFN_vkDbgSetGlobalOption) gpa(inst, "vkDbgSetGlobalOption");
-//TODO put in it's own table
     table->GetDisplayInfoWSI = (PFN_vkGetDisplayInfoWSI) gpa(inst, "vkGetDisplayInfoWSI");
+
+    table->DbgCreateMsgCallback = (PFN_vkDbgCreateMsgCallback) gpa(inst, "vkDbgCreateMsgCallback");
+    table->DbgDestroyMsgCallback = (PFN_vkDbgDestroyMsgCallback) gpa(inst, "vkDbgDestroyMsgCallback");
 }
 
 static inline void *loader_lookup_instance_dispatch_table(
@@ -435,18 +424,14 @@
         return (void *) table->GetGlobalExtensionInfo;
     if (!strcmp(name, "GetPhysicalDeviceExtensionInfo"))
         return (void *) table->GetPhysicalDeviceExtensionInfo;
-    if (!strcmp(name, "EnumerateLayers"))
-        return (void *) table->EnumerateLayers;
     if (!strcmp(name, "GetMultiDeviceCompatibility"))
         return (void *) table->GetMultiDeviceCompatibility;
-    if (!strcmp(name, "DbgRegisterMsgCallback"))
-        return (void *) table->DbgRegisterMsgCallback;
-    if (!strcmp(name, "DbgUnregisterMsgCallback"))
-        return (void *) table->DbgUnregisterMsgCallback;
-    if (!strcmp(name, "DbgSetGlobalOption"))
-        return (void *) table->DbgSetGlobalOption;
-    //TODO eventually extensions are in their own table
     if (!strcmp(name, "GetDisplayInfoWSI"))
         return (void *) table->GetDisplayInfoWSI;
+    if (!strcmp(name, "DbgCreateMsgCallback"))
+        return (void *) table->DbgCreateMsgCallback;
+    if (!strcmp(name, "DbgDestroyMsgCallback"))
+        return (void *) table->DbgDestroyMsgCallback;
+
     return NULL;
 }
diff --git a/loader/trampoline.c b/loader/trampoline.c
index c5186e3..2a54345 100644
--- a/loader/trampoline.c
+++ b/loader/trampoline.c
@@ -27,6 +27,7 @@
 #include "loader_platform.h"
 #include "loader.h"
 #include "wsi_lunarg.h"
+#include "debug_report.h"
 
 #if defined(WIN32)
 // On Windows need to disable global optimization for function entrypoints or
@@ -42,7 +43,6 @@
     struct loader_instance *ptr_instance = NULL;
 
     VkResult res = VK_ERROR_INITIALIZATION_FAILED;
-    uint32_t i;
 
     /* Scan/discover all ICD libraries in a single-threaded manner */
     loader_platform_thread_once(&once_icd, loader_icd_scan);
@@ -58,19 +58,49 @@
         return VK_ERROR_OUT_OF_HOST_MEMORY;
     }
     memset(ptr_instance, 0, sizeof(struct loader_instance));
-    ptr_instance->extension_count = pCreateInfo->extensionCount;
-    ptr_instance->extension_names = (ptr_instance->extension_count > 0) ?
-                malloc(sizeof (char *) * ptr_instance->extension_count) : NULL;
-    if (ptr_instance->extension_names == NULL && (ptr_instance->extension_count > 0))
+    ptr_instance->app_extension_count = pCreateInfo->extensionCount;
+    ptr_instance->app_extension_props = (ptr_instance->app_extension_count > 0) ?
+                malloc(sizeof (VkExtensionProperties) * ptr_instance->app_extension_count) : NULL;
+    if (ptr_instance->app_extension_props == NULL && (ptr_instance->app_extension_count > 0))
         return VK_ERROR_OUT_OF_HOST_MEMORY;
-    for (i = 0; i < ptr_instance->extension_count; i++) {
-        if (!loader_is_extension_scanned(pCreateInfo->ppEnabledExtensionNames[i]))
-            return VK_ERROR_INVALID_EXTENSION;
-        ptr_instance->extension_names[i] = malloc(strlen(pCreateInfo->ppEnabledExtensionNames[i]) + 1);
-        if (ptr_instance->extension_names[i] == NULL)
-            return VK_ERROR_OUT_OF_HOST_MEMORY;
-        strcpy(ptr_instance->extension_names[i], pCreateInfo->ppEnabledExtensionNames[i]);
+
+    /*
+     * Make local copy of extension properties indicated by application.
+     */
+    if (ptr_instance->app_extension_props) {
+        memcpy(ptr_instance->app_extension_props,
+               pCreateInfo->pEnabledExtensions,
+               sizeof(VkExtensionProperties) * ptr_instance->app_extension_count);
     }
+
+#if 0
+    /*
+     * Now that we have list of enabled extensions, verify that their dependencies
+     * have been satisfied.
+     * If A depends on B, then B should come after A in the list.
+     */
+    for (i = 0; i < ptr_instance->app_extension_count; i++) {
+        if (ptr_instance->app_extension_props[i].dependencyCount == 0)
+            continue;
+
+        const VkExtensionProperties *dependencies = ptr_instance->app_extension_props[i].pDependencyList;
+        const VkExtensionProperties *enabled_extensions = &ptr_instance->app_extension_props[i+1];
+        uint32_t dependency_extensions_count = ptr_instance->app_extension_count - i - 1;
+        for (dependency = 0; dependency < ptr_instance->app_extension_props[i].dependencyCount; dependency++) {
+            bool found = false;
+            for (j = 0; j < dependency_extensions_count; j++) {
+                if (compare_vk_extension_properties(&dependencies[j], &enabled_extensions[j])) {
+                    found = true;
+                }
+            }
+            if (!found) {
+                /* TODO: Log message about extension dependency not found */
+                return VK_ERROR_INVALID_EXTENSION;
+            }
+        }
+    }
+#endif
+
     ptr_instance->disp = malloc(sizeof(VkLayerInstanceDispatchTable));
     if (ptr_instance->disp == NULL)
         return VK_ERROR_OUT_OF_HOST_MEMORY;
@@ -78,7 +108,10 @@
     ptr_instance->next = loader.instances;
     loader.instances = ptr_instance;
 
-    wsi_lunarg_register_extensions(pCreateInfo);
+    loader_enable_instance_layers(ptr_instance);
+
+    debug_report_create_instance(ptr_instance);
+    wsi_lunarg_create_instance(ptr_instance);
 
     /* enable any layers on instance chain */
     loader_activate_instance_layers(ptr_instance);
@@ -96,6 +129,9 @@
     const VkLayerInstanceDispatchTable *disp;
 
     disp = loader_get_instance_dispatch(instance);
+
+    /* TODO: Need to free memory allocated in trampoline's CreateInstance call */
+
     return disp->DestroyInstance(instance);
 }
 
@@ -188,20 +224,6 @@
     return disp->GetPhysicalDeviceExtensionInfo(gpu, infoType, extensionIndex, pDataSize, pData);
 }
 
-LOADER_EXPORT VkResult VKAPI vkEnumerateLayers(
-                                                VkPhysicalDevice gpu,
-                                                size_t maxStringSize,
-                                                size_t* pLayerCount,
-                                                char* const* pOutLayers,
-                                                void* pReserved)
-{
-    const VkLayerInstanceDispatchTable *disp;
-
-    disp = loader_get_instance_dispatch(gpu);
-
-    return disp->EnumerateLayers(gpu, maxStringSize, pLayerCount,pOutLayers, pReserved);
-}
-
 LOADER_EXPORT VkResult VKAPI vkGetDeviceQueue(VkDevice device, uint32_t queueNodeIndex, uint32_t queueIndex, VkQueue* pQueue)
 {
     const VkLayerDispatchTable *disp;
@@ -1141,69 +1163,6 @@
     disp->CmdEndRenderPass(cmdBuffer, renderPass);
 }
 
-LOADER_EXPORT VkResult VKAPI vkDbgRegisterMsgCallback(VkInstance instance, VK_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback, void* pUserData)
-{
-   const VkLayerInstanceDispatchTable *disp;
-
-    disp = loader_get_instance_dispatch(instance);
-
-    return disp->DbgRegisterMsgCallback(instance, pfnMsgCallback, pUserData);
-}
-
-LOADER_EXPORT VkResult VKAPI vkDbgUnregisterMsgCallback(VkInstance instance, VK_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback)
-{
-   const VkLayerInstanceDispatchTable *disp;
-
-    disp = loader_get_instance_dispatch(instance);
-
-    return disp->DbgUnregisterMsgCallback(instance, pfnMsgCallback);
-}
-
-LOADER_EXPORT VkResult VKAPI vkDbgSetGlobalOption(VkInstance instance, VK_DBG_GLOBAL_OPTION dbgOption, size_t dataSize, const void* pData)
-{
-   const VkLayerInstanceDispatchTable *disp;
-
-    disp = loader_get_instance_dispatch(instance);
-
-    return disp->DbgSetGlobalOption(instance, dbgOption, dataSize, pData);
-}
-
-LOADER_EXPORT VkResult VKAPI vkDbgSetValidationLevel(VkDevice device, VkValidationLevel validationLevel)
-{
-    const VkLayerDispatchTable *disp;
-
-    disp = loader_get_dispatch(device);
-
-    return disp->DbgSetValidationLevel(device, validationLevel);
-}
-
-LOADER_EXPORT VkResult VKAPI vkDbgSetMessageFilter(VkDevice device, int32_t msgCode, VK_DBG_MSG_FILTER filter)
-{
-    const VkLayerDispatchTable *disp;
-
-    disp = loader_get_dispatch(device);
-
-    return disp->DbgSetMessageFilter(device, msgCode, filter);
-}
-
-LOADER_EXPORT VkResult VKAPI vkDbgSetObjectTag(VkDevice device, VkObject object, size_t tagSize, const void* pTag)
-{
-    const VkLayerDispatchTable *disp;
-
-    disp = loader_get_dispatch(device);
-
-    return disp->DbgSetObjectTag(device, object, tagSize, pTag);
-}
-
-LOADER_EXPORT VkResult VKAPI vkDbgSetDeviceOption(VkDevice device, VK_DBG_DEVICE_OPTION dbgOption, size_t dataSize, const void* pData)
-{
-    const VkLayerDispatchTable *disp;
-
-    disp = loader_get_dispatch(device);
-
-    return disp->DbgSetDeviceOption(device, dbgOption, dataSize, pData);
-}
-
 LOADER_EXPORT void VKAPI vkCmdDbgMarkerBegin(VkCmdBuffer cmdBuffer, const char* pMarker)
 {
     const VkLayerDispatchTable *disp;
diff --git a/loader/wsi_lunarg.c b/loader/wsi_lunarg.c
index 31f6985..91be812 100644
--- a/loader/wsi_lunarg.c
+++ b/loader/wsi_lunarg.c
@@ -124,46 +124,35 @@
 
 
 /************ extension enablement ***************/
-static bool wsi_enabled = false;
-
-struct ext_props {
-    uint32_t version;
-    const char * const name;
-};
-
 #define WSI_LUNARG_EXT_ARRAY_SIZE 1
-static const struct ext_props wsi_lunarg_exts[WSI_LUNARG_EXT_ARRAY_SIZE] = {
-    {VK_WSI_LUNARG_REVISION, VK_WSI_LUNARG_EXTENSION_NAME},
+static const struct loader_extension_property wsi_lunarg_extension_info = {
+    .info =  {
+        .sType = VK_STRUCTURE_TYPE_EXTENSION_PROPERTIES,
+        .name = VK_WSI_LUNARG_EXTENSION_NAME,
+        .version = VK_WSI_LUNARG_REVISION,
+        .description = "loader: LunarG WSI extension",
+//        .dependencyCount = 0,
+//        .pDependencyList = NULL,
+        },
+    .origin = VK_EXTENSION_ORIGIN_LOADER,
+    .hosted = true,
 };
 
-void wsi_lunarg_register_extensions(
-        const VkInstanceCreateInfo*             pCreateInfo)
+void wsi_lunarg_create_instance(
+        struct loader_instance *ptr_instance)
 {
-    uint32_t i, ext_idx;
-
-    for (i = 0; i < pCreateInfo->extensionCount; i++) {
-        for (ext_idx = 0; ext_idx < WSI_LUNARG_EXT_ARRAY_SIZE; ext_idx++) {
-            /* TODO: Should we include version number as well as extension name? */
-            if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], wsi_lunarg_exts[ext_idx].name) == 0) {
-                /* Found a matching extension name, mark it enabled */
-                wsi_enabled = true;
-            }
-
-        }
-    }
-
+    ptr_instance->wsi_lunarg_enabled = has_vk_extension_property(
+                                             &wsi_lunarg_extension_info.info,
+                                             &ptr_instance->enabled_instance_extensions);
 }
 
 void *wsi_lunarg_GetInstanceProcAddr(
         VkInstance                              instance,
-        const char*                             pName,
-        bool                                    *enabled)
+        const char*                             pName)
 {
     if (instance == VK_NULL_HANDLE)
         return NULL;
 
-    *enabled = wsi_enabled;
-
     /* since two of these entrypoints must be loader handled will report all */
     if (!strcmp(pName, "vkGetDisplayInfoWSI"))
         return (void*) wsi_lunarg_GetDisplayInfoWSI;
@@ -181,14 +170,11 @@
 
 void *wsi_lunarg_GetDeviceProcAddr(
         VkDevice                                device,
-        const char*                             name,
-        bool                                    *enabled)
+        const char*                             name)
 {
     if (device == VK_NULL_HANDLE)
         return NULL;
 
-    *enabled = wsi_enabled;
-
     /* only handle device entrypoints that are loader special cases */
     if (!strcmp(name, "vkCreateSwapChainWSI"))
         return (void*) wsi_lunarg_CreateSwapChainWSI;
diff --git a/loader/wsi_lunarg.h b/loader/wsi_lunarg.h
index 02ff37e..57c2e62 100644
--- a/loader/wsi_lunarg.h
+++ b/loader/wsi_lunarg.h
@@ -34,15 +34,18 @@
         size_t*                                 pDataSize,
         void*                                   pData);
 
-void wsi_lunarg_register_extensions(
-        const VkInstanceCreateInfo*             pCreateInfo);
+void wsi_lunarg_create_instance(
+        struct loader_instance *ptr_instance);
 
 void *wsi_lunarg_GetInstanceProcAddr(
         VkInstance                              instance,
-        const char*                             pName,
-        bool*                                   enabled);
+        const char*                             pName);
 
 void *wsi_lunarg_GetDeviceProcAddr(
         VkDevice                                device,
-        const char*                             pName,
-        bool*                                   enabled);
+        const char*                             pName);
+
+VkResult wsi_lunarg_CreateSwapChainWSI(
+        VkDevice                                device,
+        const VkSwapChainCreateInfoWSI*         pCreateInfo,
+        VkSwapChainWSI*                         pSwapChain);
diff --git a/tests/image_tests.cpp b/tests/image_tests.cpp
index 9e66155..4ec2676 100644
--- a/tests/image_tests.cpp
+++ b/tests/image_tests.cpp
@@ -100,7 +100,7 @@
         inst_info.pAppInfo = &app_info;
         inst_info.pAllocCb = NULL;
         inst_info.extensionCount = 0;
-        inst_info.ppEnabledExtensionNames = NULL;
+        inst_info.pEnabledExtensions = NULL;
         err = vkCreateInstance(&inst_info, &this->inst);
         ASSERT_VK_SUCCESS(err);
         err = vkEnumeratePhysicalDevices(this->inst, &this->gpu_count, NULL);
diff --git a/tests/init.cpp b/tests/init.cpp
index 6e5db19..b755d76 100644
--- a/tests/init.cpp
+++ b/tests/init.cpp
@@ -106,7 +106,7 @@
         inst_info.pAppInfo = &app_info;
         inst_info.pAllocCb = NULL;
         inst_info.extensionCount = 0;
-        inst_info.ppEnabledExtensionNames = NULL;
+        inst_info.pEnabledExtensions = NULL;
         err = vkCreateInstance(&inst_info, &inst);
         ASSERT_VK_SUCCESS(err);
         err = vkEnumeratePhysicalDevices(inst, &this->gpu_count, NULL);
diff --git a/tests/layer_validation_tests.cpp b/tests/layer_validation_tests.cpp
index f65b307..5c69e3c 100644
--- a/tests/layer_validation_tests.cpp
+++ b/tests/layer_validation_tests.cpp
@@ -1,5 +1,5 @@
 #include <vulkan.h>
-#include <vkDbg.h>
+#include "vk_debug_report_lunarg.h"
 #include "gtest-1.7.0/include/gtest/gtest.h"
 #include "vkrenderframework.h"
 #include "layers_config.h"
@@ -60,14 +60,15 @@
         "   uFragColor = vec4(0,1,0,1);\n"
         "}\n";
 
-void VKAPI myDbgFunc(
-    VK_DBG_MSG_TYPE     msgType,
-    VkValidationLevel validationLevel,
-    VkObject             srcObject,
-    size_t               location,
-    int32_t              msgCode,
-    const char*          pMsg,
-    void*                pUserData);
+static void myDbgFunc(
+    VkFlags                    msgFlags,
+    VkObjectType                        objType,
+    VkObject                            srcObject,
+    size_t                              location,
+    int32_t                             msgCode,
+    const char*                         pLayerPrefix,
+    const char*                         pMsg,
+    void*                               pUserData);
 
 class ErrorMonitor {
 public:
@@ -77,31 +78,31 @@
         pthread_mutexattr_init(&attr);
         pthread_mutex_init(&m_mutex, &attr);
         pthread_mutex_lock(&m_mutex);
-        m_msgType = VK_DBG_MSG_UNKNOWN;
+        m_msgFlags = VK_DBG_REPORT_INFO_BIT;
         m_bailout = NULL;
         pthread_mutex_unlock(&m_mutex);
     }
     void ClearState()
     {
         pthread_mutex_lock(&m_mutex);
-        m_msgType = VK_DBG_MSG_UNKNOWN;
+        m_msgFlags = VK_DBG_REPORT_INFO_BIT;
         m_msgString.clear();
         pthread_mutex_unlock(&m_mutex);
     }
-    VK_DBG_MSG_TYPE GetState(std::string *msgString)
+    VkFlags GetState(std::string *msgString)
     {
         pthread_mutex_lock(&m_mutex);
         *msgString = m_msgString;
         pthread_mutex_unlock(&m_mutex);
-        return m_msgType;
+        return m_msgFlags;
     }
-    void SetState(VK_DBG_MSG_TYPE msgType, const char *msgString)
+    void SetState(VkFlags msgFlags, const char *msgString)
     {
         pthread_mutex_lock(&m_mutex);
         if (m_bailout != NULL) {
             *m_bailout = true;
         }
-        m_msgType = msgType;
+        m_msgFlags = msgFlags;
         m_msgString.reserve(strlen(msgString));
         m_msgString = msgString;
         pthread_mutex_unlock(&m_mutex);
@@ -112,24 +113,25 @@
     }
 
 private:
-    VK_DBG_MSG_TYPE        m_msgType;
+    VkFlags                m_msgFlags;
     std::string            m_msgString;
     pthread_mutex_t        m_mutex;
     bool*                  m_bailout;
 };
 
-void VKAPI myDbgFunc(
-    VK_DBG_MSG_TYPE      msgType,
-    VkValidationLevel    validationLevel,
-    VkObject             srcObject,
-    size_t               location,
-    int32_t              msgCode,
-    const char*          pMsg,
-    void*                pUserData)
+static void myDbgFunc(
+    VkFlags                    msgFlags,
+    VkObjectType               objType,
+    VkObject                   srcObject,
+    size_t                     location,
+    int32_t                    msgCode,
+    const char*                pLayerPrefix,
+    const char*                pMsg,
+    void*                      pUserData)
 {
-    if (msgType == VK_DBG_MSG_WARNING || msgType == VK_DBG_MSG_ERROR) {
+    if (msgFlags & (VK_DBG_REPORT_WARN_BIT | VK_DBG_REPORT_ERROR_BIT)) {
         ErrorMonitor *errMonitor = (ErrorMonitor *)pUserData;
-        errMonitor->SetState(msgType, pMsg);
+        errMonitor->SetState(msgFlags, pMsg);
     }
 }
 
@@ -146,32 +148,10 @@
         ErrorMonitor               *m_errorMonitor;
 
     virtual void SetUp() {
-        const char *extension_names[] = {"MemTracker", "ObjectTracker", "Threading", "DrawState", "ShaderChecker"};
-        const std::vector<const char *> extensions(extension_names,
-                                        extension_names + sizeof(extension_names)/sizeof(extension_names[0]));
+        std::vector<const char *> instance_extension_names;
+        std::vector<const char *> device_extension_names;
 
-        size_t extSize = sizeof(uint32_t);
-        uint32_t extCount = 0;
-        VkResult U_ASSERT_ONLY err;
-        err = vkGetGlobalExtensionInfo(VK_EXTENSION_INFO_TYPE_COUNT, 0, &extSize, &extCount);
-        assert(!err);
-
-        VkExtensionProperties extProp;
-        extSize = sizeof(VkExtensionProperties);
-        bool32_t extFound;
-
-        for (uint32_t i = 0; i < extensions.size(); i++) {
-            extFound = 0;
-            for (uint32_t j = 0; j < extCount; j++) {
-                err = vkGetGlobalExtensionInfo(VK_EXTENSION_INFO_TYPE_PROPERTIES, j, &extSize, &extProp);
-                assert(!err);
-                if (!strcmp(extensions[i], extProp.extName)) {
-                   extFound = 1;
-                   break;
-                }
-            }
-            ASSERT_EQ(extFound, 1) << "ERROR: Cannot find extension named " << extensions[i] << " which is necessary to pass this test";
-        }
+        instance_extension_names.push_back(DEBUG_REPORT_EXTENSION_NAME);
 
         // Force layer output level to be >= WARNING so that we catch those messages but ignore others
         setLayerOptionEnum("MemTrackerReportLevel",    "VK_DBG_LAYER_LEVEL_WARNING");
@@ -189,8 +169,7 @@
         this->app_info.apiVersion = VK_API_VERSION;
 
         m_errorMonitor = new ErrorMonitor;
-        InitFramework(extensions, myDbgFunc, m_errorMonitor);
-
+        InitFramework(instance_extension_names, device_extension_names, myDbgFunc, m_errorMonitor);
     }
 
     virtual void TearDown() {
@@ -330,7 +309,7 @@
 TEST_F(VkLayerTest, CallResetCmdBufferBeforeCompletion)
 {
     vk_testing::Fence testFence;
-    VK_DBG_MSG_TYPE msgType;
+    VkFlags msgFlags;
     std::string msgString;
 
     VkFenceCreateInfo fenceInfo = {};
@@ -360,8 +339,8 @@
     // Introduce failure by calling begin again before checking fence
     vkResetCommandBuffer(cmdBuffer.obj());
 
-    msgType = m_errorMonitor->GetState(&msgString);
-    ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an err after calling ResetCommandBuffer on an active Command Buffer";
+    msgFlags = m_errorMonitor->GetState(&msgString);
+    ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive an err after calling ResetCommandBuffer on an active Command Buffer";
     if (!strstr(msgString.c_str(),"Resetting CB")) {
         FAIL() << "Error received was not 'Resetting CB (0xaddress) before it has completed. You must check CB flag before'";
     }
@@ -370,7 +349,7 @@
 TEST_F(VkLayerTest, CallBeginCmdBufferBeforeCompletion)
 {
     vk_testing::Fence testFence;
-    VK_DBG_MSG_TYPE msgType;
+    VkFlags msgFlags;
     std::string msgString;
 
     VkFenceCreateInfo fenceInfo = {};
@@ -400,8 +379,8 @@
     // Introduce failure by calling begin again before checking fence
     BeginCommandBuffer(cmdBuffer);
 
-    msgType = m_errorMonitor->GetState(&msgString);
-    ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an err after calling BeginCommandBuffer on an active Command Buffer";
+    msgFlags = m_errorMonitor->GetState(&msgString);
+    ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive an err after calling BeginCommandBuffer on an active Command Buffer";
     if (!strstr(msgString.c_str(),"Calling vkBeginCommandBuffer() on active CB")) {
         FAIL() << "Error received was not 'Calling vkBeginCommandBuffer() on an active CB (0xaddress) before it has completed'";
     }
@@ -409,7 +388,7 @@
 
 TEST_F(VkLayerTest, MapMemWithoutHostVisibleBit)
 {
-    VK_DBG_MSG_TYPE msgType;
+    VkFlags         msgFlags;
     std::string     msgString;
     VkResult        err;
 
@@ -473,8 +452,8 @@
     void *mappedAddress = NULL;
     err = vkMapMemory(m_device->device(), mem, 0, 0, 0, &mappedAddress);
 
-    msgType = m_errorMonitor->GetState(&msgString);
-    ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error while tring to map memory not visible to CPU";
+    msgFlags = m_errorMonitor->GetState(&msgString);
+    ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive an error while tring to map memory not visible to CPU";
     if (!strstr(msgString.c_str(),"Mapping Memory without VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT")) {
         FAIL() << "Error received did not match expected error message from vkMapMemory in MemTracker";
     }
@@ -482,7 +461,7 @@
 
 TEST_F(VkLayerTest, BindInvalidMemory)
 {
-    VK_DBG_MSG_TYPE msgType;
+    VkFlags         msgFlags;
     std::string     msgString;
     VkResult        err;
 
@@ -545,8 +524,8 @@
     err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
     ASSERT_VK_SUCCESS(err);
 
-    msgType = m_errorMonitor->GetState(&msgString);
-    ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error while tring to bind a freed memory object";
+    msgFlags = m_errorMonitor->GetState(&msgString);
+    ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive an error while tring to bind a freed memory object";
     if (!strstr(msgString.c_str(),"couldn't find info for mem obj")) {
         FAIL() << "Error received did not match expected error message from BindObjectMemory in MemTracker";
     }
@@ -554,7 +533,7 @@
 
 TEST_F(VkLayerTest, FreeBoundMemory)
 {
-    VK_DBG_MSG_TYPE msgType;
+    VkFlags         msgFlags;
     std::string     msgString;
     VkResult        err;
 
@@ -617,8 +596,8 @@
     vkFreeMemory(m_device->device(), mem);
     ASSERT_VK_SUCCESS(err);
 
-    msgType = m_errorMonitor->GetState(&msgString);
-    ASSERT_EQ(msgType, VK_DBG_MSG_WARNING) << "Did not receive an warning while tring to free bound memory";
+    msgFlags = m_errorMonitor->GetState(&msgString);
+    ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT) << "Did not receive an warning while tring to free bound memory";
     if (!strstr(msgString.c_str(),"Freeing memory object while it still has references")) {
         FAIL() << "Warning received did not match expected message from freeMemObjInfo  in MemTracker";
     }
@@ -626,7 +605,7 @@
 
 TEST_F(VkLayerTest, RebindMemory)
 {
-    VK_DBG_MSG_TYPE msgType;
+    VkFlags         msgFlags;
     std::string     msgString;
     VkResult        err;
 
@@ -692,8 +671,8 @@
     err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem2, 0);
     ASSERT_VK_SUCCESS(err);
 
-    msgType = m_errorMonitor->GetState(&msgString);
-    ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error while tring to rebind an object";
+    msgFlags = m_errorMonitor->GetState(&msgString);
+    ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive an error while tring to rebind an object";
     if (!strstr(msgString.c_str(),"which has already been bound to mem object")) {
         FAIL() << "Error received did not match expected message when rebinding memory to an object";
     }
@@ -701,7 +680,7 @@
 
 TEST_F(VkLayerTest, BindMemoryToDestroyedObject)
 {
-    VK_DBG_MSG_TYPE msgType;
+    VkFlags         msgFlags;
     std::string     msgString;
     VkResult        err;
 
@@ -764,8 +743,8 @@
     err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
     ASSERT_VK_SUCCESS(err);
 
-    msgType = m_errorMonitor->GetState(&msgString);
-    ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error while binding memory to a destroyed object";
+    msgFlags = m_errorMonitor->GetState(&msgString);
+    ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive an error while binding memory to a destroyed object";
     if (!strstr(msgString.c_str(),"that's not in global list")) {
         FAIL() << "Error received did not match expected error message from updateObjectBinding in MemTracker";
     }
@@ -774,7 +753,7 @@
 TEST_F(VkLayerTest, SubmitSignaledFence)
 {
     vk_testing::Fence testFence;
-    VK_DBG_MSG_TYPE msgType;
+    VkFlags msgFlags;
     std::string msgString;
 
     VkFenceCreateInfo fenceInfo = {};
@@ -796,8 +775,8 @@
     testFence.init(*m_device, fenceInfo);
     m_errorMonitor->ClearState();
     cmdBuffer.QueueCommandBuffer(testFence.obj());
-    msgType = m_errorMonitor->GetState(&msgString);
-    ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an err from using a fence in SIGNALED state in call to vkQueueSubmit";
+    msgFlags = m_errorMonitor->GetState(&msgString);
+    ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive an err from using a fence in SIGNALED state in call to vkQueueSubmit";
     if (!strstr(msgString.c_str(),"submitted in SIGNALED state.  Fences must be reset before being submitted")) {
         FAIL() << "Error received was not 'VkQueueSubmit with fence in SIGNALED_STATE'";
     }
@@ -807,7 +786,7 @@
 TEST_F(VkLayerTest, ResetUnsignaledFence)
 {
     vk_testing::Fence testFence;
-    VK_DBG_MSG_TYPE msgType;
+    VkFlags msgFlags;
     std::string msgString;
     VkFenceCreateInfo fenceInfo = {};
     fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
@@ -818,8 +797,8 @@
     m_errorMonitor->ClearState();
     VkFence fences[1] = {testFence.obj()};
     vkResetFences(m_device->device(), 1, fences);
-    msgType = m_errorMonitor->GetState(&msgString);
-    ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error from submitting fence with UNSIGNALED state to vkResetFences";
+    msgFlags = m_errorMonitor->GetState(&msgString);
+    ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive an error from submitting fence with UNSIGNALED state to vkResetFences";
     if (!strstr(msgString.c_str(),"submitted to VkResetFences in UNSIGNALED STATE")) {
         FAIL() << "Error received was not 'VkResetFences with fence in UNSIGNALED_STATE'";
     }
@@ -830,7 +809,7 @@
 TEST_F(VkLayerTest, WaitForUnsubmittedFence)
 {
     vk_testing::Fence testFence;
-    VK_DBG_MSG_TYPE msgType;
+    VkFlags msgFlags;
     std::string msgString;
     VkFenceCreateInfo fenceInfo = {};
     fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
@@ -840,8 +819,8 @@
     testFence.init(*m_device, fenceInfo);
     m_errorMonitor->ClearState();
     vkGetFenceStatus(m_device->device(),testFence.obj());
-    msgType = m_errorMonitor->GetState(&msgString);
-    ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error asking for status of unsubmitted fence";
+    msgFlags = m_errorMonitor->GetState(&msgString);
+    ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive an error asking for status of unsubmitted fence";
     if (!strstr(msgString.c_str(),"Status Requested for Unsubmitted Fence")) {
         FAIL() << "Error received was not Status Requested for Unsubmitted Fence";
     }
@@ -849,8 +828,8 @@
     VkFence fences[1] = {testFence.obj()};
     m_errorMonitor->ClearState();
     vkWaitForFences(m_device->device(), 1, fences, VK_TRUE, 0);
-    msgType = m_errorMonitor->GetState(&msgString);
-    ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error for waiting for unsubmitted fence";
+    msgFlags = m_errorMonitor->GetState(&msgString);
+    ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive an error for waiting for unsubmitted fence";
     if (!strstr(msgString.c_str(),"Waiting for Unsubmitted Fence")) {
         FAIL() << "Error received was not 'Waiting for Unsubmitted Fence'";
     }
@@ -862,7 +841,7 @@
     VkEvent event;
     VkMemoryRequirements mem_req;
     size_t data_size = sizeof(mem_req);
-    VK_DBG_MSG_TYPE msgType;
+    VkFlags msgFlags;
     std::string msgString;
     VkResult err;
 
@@ -875,8 +854,8 @@
     m_errorMonitor->ClearState();
     err = vkGetObjectInfo(device(), VK_OBJECT_TYPE_IMAGE, event, VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
                            &data_size, &mem_req);
-    msgType = m_errorMonitor->GetState(&msgString);
-    ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error from mismatched types in vkGetObjectInfo";
+    msgFlags = m_errorMonitor->GetState(&msgString);
+    ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive an error from mismatched types in vkGetObjectInfo";
     if (!strstr(msgString.c_str(),"does not match designated type")) {
         FAIL() << "Error received was not 'does not match designated type'";
     }
@@ -884,15 +863,15 @@
 
 TEST_F(VkLayerTest, RasterStateNotBound)
 {
-    VK_DBG_MSG_TYPE msgType;
+    VkFlags msgFlags;
     std::string msgString;
 
     TEST_DESCRIPTION("Simple Draw Call that validates failure when a raster state object is not bound beforehand");
 
     VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailRaster);
 
-    msgType = m_errorMonitor->GetState(&msgString);
-    ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error from Not Binding a Raster State Object";
+    msgFlags = m_errorMonitor->GetState(&msgString);
+    ASSERT_EQ(msgFlags, VK_DBG_MSG_ERROR) << "Did not receive an error from Not Binding a Raster State Object";
     if (!strstr(msgString.c_str(),"Raster object not bound to this command buffer")) {
         FAIL() << "Error received was not 'Raster object not bound to this command buffer'";
     }
@@ -900,14 +879,14 @@
 
 TEST_F(VkLayerTest, ViewportStateNotBound)
 {
-    VK_DBG_MSG_TYPE msgType;
+    VkFlags msgFlags;
     std::string msgString;
     TEST_DESCRIPTION("Simple Draw Call that validates failure when a viewport state object is not bound beforehand");
 
     VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailViewport);
 
-    msgType = m_errorMonitor->GetState(&msgString);
-    ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error from Not Binding a Viewport State Object";
+    msgFlags = m_errorMonitor->GetState(&msgString);
+    ASSERT_EQ(msgFlags, VK_DBG_MSG_ERROR) << "Did not receive an error from Not Binding a Viewport State Object";
     if (!strstr(msgString.c_str(),"Viewport object not bound to this command buffer")) {
         FAIL() << "Error received was not 'Viewport object not bound to this command buffer'";
     }
@@ -915,15 +894,15 @@
 
 TEST_F(VkLayerTest, ColorBlendStateNotBound)
 {
-    VK_DBG_MSG_TYPE msgType;
+    VkFlags msgFlags;
     std::string msgString;
 
     TEST_DESCRIPTION("Simple Draw Call that validates failure when a color-blend state object is not bound beforehand");
 
     VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailColorBlend);
 
-    msgType = m_errorMonitor->GetState(&msgString);
-    ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error from Not Binding a ColorBlend State Object";
+    msgFlags = m_errorMonitor->GetState(&msgString);
+    ASSERT_EQ(msgFlags, VK_DBG_MSG_ERROR) << "Did not receive an error from Not Binding a ColorBlend State Object";
     if (!strstr(msgString.c_str(),"Color-blend object not bound to this command buffer")) {
         FAIL() << "Error received was not 'Color-blend object not bound to this command buffer'";
     }
@@ -931,15 +910,15 @@
 
 TEST_F(VkLayerTest, DepthStencilStateNotBound)
 {
-    VK_DBG_MSG_TYPE msgType;
+    VkFlags msgFlags;
     std::string msgString;
 
     TEST_DESCRIPTION("Simple Draw Call that validates failure when a depth-stencil state object is not bound beforehand");
 
     VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailDepthStencil);
 
-    msgType = m_errorMonitor->GetState(&msgString);
-    ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error from Not Binding a DepthStencil State Object";
+    msgFlags = m_errorMonitor->GetState(&msgString);
+    ASSERT_EQ(msgFlags, VK_DBG_MSG_ERROR) << "Did not receive an error from Not Binding a DepthStencil State Object";
     if (!strstr(msgString.c_str(),"Depth-stencil object not bound to this command buffer")) {
         FAIL() << "Error received was not 'Depth-stencil object not bound to this command buffer'";
     }
@@ -949,7 +928,7 @@
 TEST_F(VkLayerTest, PipelineNotBound)
 {
     // Initiate Draw w/o a PSO bound
-    VK_DBG_MSG_TYPE msgType;
+    VkFlags         msgFlags;
     std::string     msgString;
 
     ASSERT_NO_FATAL_FAILURE(InitState());
@@ -958,8 +937,8 @@
     BeginCommandBuffer(cmdBuffer);
     VkPipeline badPipeline = (VkPipeline)0xbaadb1be;
     vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, badPipeline);
-    msgType = m_errorMonitor->GetState(&msgString);
-    ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after binding invalid pipeline to CmdBuffer";
+    msgFlags = m_errorMonitor->GetState(&msgString);
+    ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after binding invalid pipeline to CmdBuffer";
     if (!strstr(msgString.c_str(),"Attempt to bind Pipeline ")) {
         FAIL() << "Error received was not 'Attempt to bind Pipeline 0xbaadb1be that doesn't exist!'";
     }
@@ -970,13 +949,13 @@
     // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
     //   The DS check for this is after driver has been called to validate DS internal data struct
     // Attempt to clear DS Pool with bad object
-/*    VK_DBG_MSG_TYPE msgType;
+/*    VkFlags msgFlags;
     std::string msgString;
     VkDescriptorPool badPool = (VkDescriptorPool)0xbaad6001;
     vkResetDescriptorPool(device(), badPool);
 
-    msgType = m_errorMonitor->GetState(&msgString);
-    ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an error from Resetting an invalid DescriptorPool Object";
+    msgFlags = m_errorMonitor->GetState(&msgString);
+    ASSERT_EQ(msgFlags, VK_DBG_MSG_ERROR) << "Did not receive an error from Resetting an invalid DescriptorPool Object";
     if (!strstr(msgString.c_str(),"Unable to find pool node for pool 0xbaad6001 specified in vkResetDescriptorPool() call")) {
         FAIL() << "Error received was note 'Unable to find pool node for pool 0xbaad6001 specified in vkResetDescriptorPool() call'";
     }*/
@@ -1002,7 +981,7 @@
     //   The DS check for this is after driver has been called to validate DS internal data struct
     // Create a valid cmd buffer
     // call vkCmdBindPipeline w/ false Pipeline
-    VK_DBG_MSG_TYPE msgType;
+    VkFlags         msgFlags;
     std::string     msgString;
 
     ASSERT_NO_FATAL_FAILURE(InitState());
@@ -1011,8 +990,8 @@
     BeginCommandBuffer(cmdBuffer);
     VkPipeline badPipeline = (VkPipeline)0xbaadb1be;
     vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, badPipeline);
-    msgType = m_errorMonitor->GetState(&msgString);
-    ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after binding invalid pipeline to CmdBuffer";
+    msgFlags = m_errorMonitor->GetState(&msgString);
+    ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after binding invalid pipeline to CmdBuffer";
     if (!strstr(msgString.c_str(),"Attempt to bind Pipeline ")) {
         FAIL() << "Error received was not 'Attempt to bind Pipeline 0xbaadb1be that doesn't exist!'";
     }
@@ -1021,7 +1000,7 @@
 TEST_F(VkLayerTest, NoEndCmdBuffer)
 {
     // Create and update CmdBuffer then call QueueSubmit w/o calling End on CmdBuffer
-    VK_DBG_MSG_TYPE msgType;
+    VkFlags         msgFlags;
     std::string     msgString;
     VkResult        err;
 
@@ -1126,8 +1105,8 @@
     m_device->get_device_queue();
     vkQueueSubmit(m_device->m_queue, 1, &localCmdBuffer, NULL);
 
-    msgType = m_errorMonitor->GetState(&msgString);
-    ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after vkEndDescriptorPoolUpdate() w/o first calling vkBeginDescriptorPoolUpdate().";
+    msgFlags = m_errorMonitor->GetState(&msgString);
+    ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after vkEndDescriptorPoolUpdate() w/o first calling vkBeginDescriptorPoolUpdate().";
     if (!strstr(msgString.c_str(),"You must call vkEndCommandBuffer() on CB ")) {
         FAIL() << "Error received was not 'You must call vkEndCommandBuffer() on CB <0xblah> before this call to vkQueueSubmit()!'";
     }
@@ -1144,7 +1123,7 @@
 TEST_F(VkLayerTest, VtxBufferBadIndex)
 {
     // Bind VBO out-of-bounds for given PSO
-        VK_DBG_MSG_TYPE msgType;
+    VkFlags         msgFlags;
     std::string     msgString;
     VkResult        err;
 
@@ -1247,8 +1226,8 @@
     // Should error before calling to driver so don't care about actual data
     vkCmdBindVertexBuffers(cmdBuffer.GetBufferHandle(), 0, 1, NULL, NULL);
 
-    msgType = m_errorMonitor->GetState(&msgString);
-    ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after vkCmdBindVertexBuffers() w/o any Vtx Inputs in PSO.";
+    msgFlags = m_errorMonitor->GetState(&msgString);
+    ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after vkCmdBindVertexBuffers() w/o any Vtx Inputs in PSO.";
     if (!strstr(msgString.c_str(),"Vtx Buffer Index 0 was bound, but no vtx buffers are attached to PSO.")) {
         FAIL() << "Error received was not 'Vtx Buffer Index 0 was bound, but no vtx buffers are attached to PSO.'";
     }
@@ -1257,7 +1236,7 @@
 TEST_F(VkLayerTest, DSTypeMismatch)
 {
     // Create DS w/ layout of one type and attempt Update w/ mis-matched type
-    VK_DBG_MSG_TYPE msgType;
+    VkFlags         msgFlags;
     std::string     msgString;
     VkResult        err;
 
@@ -1334,9 +1313,9 @@
 
     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
 
-    msgType = m_errorMonitor->GetState(&msgString);
+    msgFlags = m_errorMonitor->GetState(&msgString);
     std::cout << msgString << "\n";
-    ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after updating BUFFER Descriptor w/ incorrect type of SAMPLER.";
+    ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after updating BUFFER Descriptor w/ incorrect type of SAMPLER.";
     if (!strstr(msgString.c_str(),"Descriptor update type of VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET does not match ")) {
         FAIL() << "Error received was not 'Descriptor update type of VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET does not match overlapping binding type!'";
     }
@@ -1345,7 +1324,7 @@
 TEST_F(VkLayerTest, DSUpdateOutOfBounds)
 {
     // For overlapping Update, have arrayIndex exceed that of layout
-    VK_DBG_MSG_TYPE msgType;
+    VkFlags         msgFlags;
     std::string     msgString;
     VkResult        err;
 
@@ -1423,8 +1402,8 @@
 
     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
 
-    msgType = m_errorMonitor->GetState(&msgString);
-    ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after updating Descriptor w/ index out of bounds.";
+    msgFlags = m_errorMonitor->GetState(&msgString);
+    ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after updating Descriptor w/ index out of bounds.";
     if (!strstr(msgString.c_str(),"Descriptor update type of VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET is out of bounds for matching binding")) {
         FAIL() << "Error received was not 'Descriptor update type of VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET is out of bounds for matching binding...'";
     }
@@ -1433,7 +1412,7 @@
 TEST_F(VkLayerTest, InvalidDSUpdateIndex)
 {
     // Create layout w/ count of 1 and attempt update to that layout w/ binding index 2
-    VK_DBG_MSG_TYPE msgType;
+    VkFlags         msgFlags;
     std::string     msgString;
     VkResult        err;
 
@@ -1511,8 +1490,8 @@
 
     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
 
-    msgType = m_errorMonitor->GetState(&msgString);
-    ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after updating Descriptor w/ count too large for layout.";
+    msgFlags = m_errorMonitor->GetState(&msgString);
+    ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after updating Descriptor w/ count too large for layout.";
     if (!strstr(msgString.c_str()," does not have binding to match update binding ")) {
         FAIL() << "Error received was not 'Descriptor Set <blah> does not have binding to match update binding '";
     }
@@ -1521,7 +1500,7 @@
 TEST_F(VkLayerTest, InvalidDSUpdateStruct)
 {
     // Call UpdateDS w/ struct type other than valid VK_STRUCTUR_TYPE_UPDATE_* types
-    VK_DBG_MSG_TYPE msgType;
+    VkFlags         msgFlags;
     std::string     msgString;
     VkResult        err;
 
@@ -1599,8 +1578,8 @@
 
     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
 
-    msgType = m_errorMonitor->GetState(&msgString);
-    ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after updating Descriptor w/ invalid struct type.";
+    msgFlags = m_errorMonitor->GetState(&msgString);
+    ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after updating Descriptor w/ invalid struct type.";
     if (!strstr(msgString.c_str(),"Unexpected UPDATE struct of type ")) {
         FAIL() << "Error received was not 'Unexpected UPDATE struct of type '";
     }
@@ -1609,7 +1588,7 @@
 TEST_F(VkLayerTest, NumSamplesMismatch)
 {
     // Create CmdBuffer where MSAA samples doesn't match RenderPass sampleCount
-    VK_DBG_MSG_TYPE msgType;
+    VkFlags         msgFlags;
     std::string     msgString;
     VkResult        err;
 
@@ -1722,8 +1701,8 @@
     BeginCommandBuffer(cmdBuffer);
     vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
 
-    msgType = m_errorMonitor->GetState(&msgString);
-    ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive error after binding RenderPass w/ mismatched MSAA from PSO.";
+    msgFlags = m_errorMonitor->GetState(&msgString);
+    ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after binding RenderPass w/ mismatched MSAA from PSO.";
     if (!strstr(msgString.c_str(),"Num samples mismatch! ")) {
         FAIL() << "Error received was not 'Num samples mismatch!...'";
     }
@@ -1753,7 +1732,7 @@
 
 TEST_F(VkLayerTest, ThreadCmdBufferCollision)
 {
-    VK_DBG_MSG_TYPE msgType;
+    VkFlags msgFlags;
     std::string msgString;
     pthread_t thread;
     pthread_attr_t thread_attr;
@@ -1815,8 +1794,8 @@
     pthread_join(thread, NULL);
     EndCommandBuffer(cmdBuffer);
 
-    msgType = m_errorMonitor->GetState(&msgString);
-    ASSERT_EQ(msgType, VK_DBG_MSG_ERROR) << "Did not receive an err from using one VkCommandBufferObj in two threads";
+    msgFlags = m_errorMonitor->GetState(&msgString);
+    ASSERT_TRUE(msgFlags & VK_DBG_REPORT_INFO_BIT) << "Did not receive an err from using one VkCommandBufferObj in two threads";
     if (!strstr(msgString.c_str(),"THREADING ERROR")) {
         FAIL() << "Error received was not 'THREADING ERROR'";
     }
@@ -1828,7 +1807,7 @@
 #if SHADER_CHECKER_TESTS
 TEST_F(VkLayerTest, CreatePipelineVertexOutputNotConsumed)
 {
-    VK_DBG_MSG_TYPE msgType;
+    VkFlags msgFlags;
     std::string msgString;
     ASSERT_NO_FATAL_FAILURE(InitState());
     ScopedUseGlsl useGlsl(false);
@@ -1868,9 +1847,9 @@
     m_errorMonitor->ClearState();
     pipe.CreateVKPipeline(descriptorSet);
 
-    msgType = m_errorMonitor->GetState(&msgString);
+    msgFlags = m_errorMonitor->GetState(&msgString);
 
-    ASSERT_EQ(VK_DBG_MSG_WARNING, msgType);
+    ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT);
     if (!strstr(msgString.c_str(),"not consumed by fragment shader")) {
         FAIL() << "Incorrect warning: " << msgString;
     }
@@ -1878,7 +1857,7 @@
 
 TEST_F(VkLayerTest, CreatePipelineFragmentInputNotProvided)
 {
-    VK_DBG_MSG_TYPE msgType;
+    VkFlags msgFlags;
     std::string msgString;
     ASSERT_NO_FATAL_FAILURE(InitState());
     ScopedUseGlsl useGlsl(false);
@@ -1917,9 +1896,9 @@
     m_errorMonitor->ClearState();
     pipe.CreateVKPipeline(descriptorSet);
 
-    msgType = m_errorMonitor->GetState(&msgString);
+    msgFlags = m_errorMonitor->GetState(&msgString);
 
-    ASSERT_EQ(VK_DBG_MSG_ERROR, msgType);
+    ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
     if (!strstr(msgString.c_str(),"not written by vertex shader")) {
         FAIL() << "Incorrect error: " << msgString;
     }
@@ -1927,7 +1906,7 @@
 
 TEST_F(VkLayerTest, CreatePipelineVsFsTypeMismatch)
 {
-    VK_DBG_MSG_TYPE msgType;
+    VkFlags msgFlags;
     std::string msgString;
     ASSERT_NO_FATAL_FAILURE(InitState());
     ScopedUseGlsl useGlsl(false);
@@ -1968,9 +1947,9 @@
     m_errorMonitor->ClearState();
     pipe.CreateVKPipeline(descriptorSet);
 
-    msgType = m_errorMonitor->GetState(&msgString);
+    msgFlags = m_errorMonitor->GetState(&msgString);
 
-    ASSERT_EQ(VK_DBG_MSG_ERROR, msgType);
+    ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
     if (!strstr(msgString.c_str(),"Type mismatch on location 0")) {
         FAIL() << "Incorrect error: " << msgString;
     }
@@ -1978,7 +1957,7 @@
 
 TEST_F(VkLayerTest, CreatePipelineAttribNotConsumed)
 {
-    VK_DBG_MSG_TYPE msgType;
+    VkFlags msgFlags;
     std::string msgString;
     ASSERT_NO_FATAL_FAILURE(InitState());
     ScopedUseGlsl useGlsl(false);
@@ -2026,9 +2005,9 @@
     m_errorMonitor->ClearState();
     pipe.CreateVKPipeline(descriptorSet);
 
-    msgType = m_errorMonitor->GetState(&msgString);
+    msgFlags = m_errorMonitor->GetState(&msgString);
 
-    ASSERT_EQ(VK_DBG_MSG_WARNING, msgType);
+    ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT);
     if (!strstr(msgString.c_str(),"location 0 not consumed by VS")) {
         FAIL() << "Incorrect warning: " << msgString;
     }
@@ -2036,7 +2015,7 @@
 
 TEST_F(VkLayerTest, CreatePipelineAttribNotProvided)
 {
-    VK_DBG_MSG_TYPE msgType;
+    VkFlags msgFlags;
     std::string msgString;
     ASSERT_NO_FATAL_FAILURE(InitState());
     ScopedUseGlsl useGlsl(false);
@@ -2075,9 +2054,9 @@
     m_errorMonitor->ClearState();
     pipe.CreateVKPipeline(descriptorSet);
 
-    msgType = m_errorMonitor->GetState(&msgString);
+    msgFlags = m_errorMonitor->GetState(&msgString);
 
-    ASSERT_EQ(VK_DBG_MSG_ERROR, msgType);
+    ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
     if (!strstr(msgString.c_str(),"VS consumes input at location 0 but not provided")) {
         FAIL() << "Incorrect warning: " << msgString;
     }
@@ -2085,7 +2064,7 @@
 
 TEST_F(VkLayerTest, CreatePipelineAttribTypeMismatch)
 {
-    VK_DBG_MSG_TYPE msgType;
+    VkFlags msgFlags;
     std::string msgString;
     ASSERT_NO_FATAL_FAILURE(InitState());
     ScopedUseGlsl useGlsl(false);
@@ -2134,9 +2113,9 @@
     m_errorMonitor->ClearState();
     pipe.CreateVKPipeline(descriptorSet);
 
-    msgType = m_errorMonitor->GetState(&msgString);
+    msgFlags = m_errorMonitor->GetState(&msgString);
 
-    ASSERT_EQ(VK_DBG_MSG_ERROR, msgType);
+    ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
     if (!strstr(msgString.c_str(),"location 0 does not match VS input type")) {
         FAIL() << "Incorrect error: " << msgString;
     }
@@ -2144,7 +2123,7 @@
 
 TEST_F(VkLayerTest, CreatePipelineAttribBindingConflict)
 {
-    VK_DBG_MSG_TYPE msgType;
+    VkFlags msgFlags;
     std::string msgString;
     ASSERT_NO_FATAL_FAILURE(InitState());
     ScopedUseGlsl useGlsl(false);
@@ -2194,9 +2173,9 @@
     m_errorMonitor->ClearState();
     pipe.CreateVKPipeline(descriptorSet);
 
-    msgType = m_errorMonitor->GetState(&msgString);
+    msgFlags = m_errorMonitor->GetState(&msgString);
 
-    ASSERT_EQ(VK_DBG_MSG_ERROR, msgType);
+    ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
     if (!strstr(msgString.c_str(),"Duplicate vertex input binding descriptions for binding 0")) {
         FAIL() << "Incorrect error: " << msgString;
     }
@@ -2207,7 +2186,7 @@
 
 TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotWritten)
 {
-    VK_DBG_MSG_TYPE msgType;
+    VkFlags msgFlags;
     std::string msgString;
     ASSERT_NO_FATAL_FAILURE(InitState());
     ScopedUseGlsl useGlsl(false);
@@ -2245,9 +2224,9 @@
     m_errorMonitor->ClearState();
     pipe.CreateVKPipeline(descriptorSet);
 
-    msgType = m_errorMonitor->GetState(&msgString);
+    msgFlags = m_errorMonitor->GetState(&msgString);
 
-    ASSERT_EQ(VK_DBG_MSG_ERROR, msgType);
+    ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
     if (!strstr(msgString.c_str(),"Attachment 0 not written by FS")) {
         FAIL() << "Incorrect error: " << msgString;
     }
@@ -2255,7 +2234,7 @@
 
 TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotConsumed)
 {
-    VK_DBG_MSG_TYPE msgType;
+    VkFlags msgFlags;
     std::string msgString;
     ASSERT_NO_FATAL_FAILURE(InitState());
     ScopedUseGlsl useGlsl(false);
@@ -2298,9 +2277,9 @@
     m_errorMonitor->ClearState();
     pipe.CreateVKPipeline(descriptorSet);
 
-    msgType = m_errorMonitor->GetState(&msgString);
+    msgFlags = m_errorMonitor->GetState(&msgString);
 
-    ASSERT_EQ(VK_DBG_MSG_WARNING, msgType);
+    ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT);
     if (!strstr(msgString.c_str(),"FS writes to output location 1 with no matching attachment")) {
         FAIL() << "Incorrect warning: " << msgString;
     }
@@ -2308,7 +2287,7 @@
 
 TEST_F(VkLayerTest, CreatePipelineFragmentOutputTypeMismatch)
 {
-    VK_DBG_MSG_TYPE msgType;
+    VkFlags msgFlags;
     std::string msgString;
     ASSERT_NO_FATAL_FAILURE(InitState());
     ScopedUseGlsl useGlsl(false);
@@ -2348,9 +2327,9 @@
     m_errorMonitor->ClearState();
     pipe.CreateVKPipeline(descriptorSet);
 
-    msgType = m_errorMonitor->GetState(&msgString);
+    msgFlags = m_errorMonitor->GetState(&msgString);
 
-    ASSERT_EQ(VK_DBG_MSG_ERROR, msgType);
+    ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
     if (!strstr(msgString.c_str(),"does not match FS output type")) {
         FAIL() << "Incorrect error: " << msgString;
     }
@@ -2358,7 +2337,7 @@
 
 TEST_F(VkLayerTest, CreatePipelineNonSpirvShader)
 {
-    VK_DBG_MSG_TYPE msgType;
+    VkFlags msgFlags;
     std::string msgString;
     ASSERT_NO_FATAL_FAILURE(InitState());
     /* Intentionally provided GLSL rather than compiling to SPIRV first */
@@ -2405,8 +2384,8 @@
 
     /* should have emitted a warning: the shader is not SPIRV, so we're
      * not going to be able to analyze it */
-    msgType = m_errorMonitor->GetState(&msgString);
-    ASSERT_EQ(VK_DBG_MSG_WARNING, msgType);
+    msgFlags = m_errorMonitor->GetState(&msgString);
+    ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT);
     if (!strstr(msgString.c_str(),"is not SPIR-V")) {
         FAIL() << "Incorrect warning: " << msgString;
     }
diff --git a/tests/render_tests.cpp b/tests/render_tests.cpp
index 95fdfd6..df9c5a0 100644
--- a/tests/render_tests.cpp
+++ b/tests/render_tests.cpp
@@ -68,7 +68,7 @@
 #include "../layers/object_track.h"
 #endif
 #ifdef DEBUG_CALLBACK
-#include <vkDbg.h>
+#include <vk_debug_report_lunarg.h>
 #endif
 #include "gtest-1.7.0/include/gtest/gtest.h"
 
@@ -94,7 +94,7 @@
         case VK_DBG_MSG_WARNING:
             printf("CALLBACK WARNING : %s\n", pMsg);
             break;
-        case VK_DBG_MSG_ERROR:
+        case VK_DBG_REPORT_ERROR_BIT:
             printf("CALLBACK ERROR : %s\n", pMsg);
             break;
         default:
@@ -498,7 +498,7 @@
     OBJTRACK_NODE* pObjNodeArray = (OBJTRACK_NODE*)malloc(sizeof(OBJTRACK_NODE)*numObjects);
     pObjTrackGetObjs(numObjects, pObjNodeArray);
     for (i=0; i < numObjects; i++) {
-        printf("Object %i of type %s has objID (%p) and %lu uses\n", i, string_from_vulkan_object_type(pObjNodeArray[i].objType), pObjNodeArray[i].vkObj, pObjNodeArray[i].numUses);
+        printf("Object %i of type %s has objID (%p) and %lu uses\n", i, string_VkObjectType(pObjNodeArray[i].objType), pObjNodeArray[i].pObj, pObjNodeArray[i].numUses);
     }
     free(pObjNodeArray);
 #endif
diff --git a/tests/test_environment.cpp b/tests/test_environment.cpp
index 90483ec..7ba7f69 100644
--- a/tests/test_environment.cpp
+++ b/tests/test_environment.cpp
@@ -57,7 +57,7 @@
     inst_info.pAppInfo = &app_;
     inst_info.pAllocCb = NULL;
     inst_info.extensionCount = 0;
-    inst_info.ppEnabledExtensionNames = NULL;
+    inst_info.pEnabledExtensions = NULL;
     err = vkCreateInstance(&inst_info, &inst);
     ASSERT_EQ(VK_SUCCESS, err);
     err = vkEnumeratePhysicalDevices(inst, &count, NULL);
diff --git a/tests/vkrenderframework.cpp b/tests/vkrenderframework.cpp
index 070bc74..a658bbe 100644
--- a/tests/vkrenderframework.cpp
+++ b/tests/vkrenderframework.cpp
@@ -61,22 +61,51 @@
 
 void VkRenderFramework::InitFramework()
 {
-     const std::vector<const char *> extensions;
-     InitFramework(extensions);
+    std::vector<const char*> instance_extension_names;
+    std::vector<const char*> device_extension_names;
+    InitFramework(instance_extension_names, device_extension_names);
 }
 
-void VkRenderFramework::InitFramework(const std::vector<const char *> &extensions, VK_DBG_MSG_CALLBACK_FUNCTION dbgFunction, void *userData)
+void VkRenderFramework::InitFramework(
+        std::vector<const char *> instance_extension_names,
+        std::vector<const char *> device_extension_names,
+        PFN_vkDbgMsgCallback dbgFunction,
+        void *userData)
 {
-    VkResult err;
     VkInstanceCreateInfo instInfo = {};
+    std::vector<VkExtensionProperties> instance_extensions;
+    std::vector<VkExtensionProperties> device_extensions;
+    uint32_t extCount = 0;
+    size_t extSize = sizeof(extCount);
+    VkResult U_ASSERT_ONLY err;
+    err = vkGetGlobalExtensionInfo(VK_EXTENSION_INFO_TYPE_COUNT, 0, &extSize, &extCount);
+    assert(!err);
+
+    VkExtensionProperties extProp;
+    extSize = sizeof(VkExtensionProperties);
+    bool32_t extFound;
+
+    for (uint32_t i = 0; i < instance_extension_names.size(); i++) {
+        extFound = 0;
+        for (uint32_t j = 0; j < extCount; j++) {
+            err = vkGetGlobalExtensionInfo(VK_EXTENSION_INFO_TYPE_PROPERTIES, j, &extSize, &extProp);
+            assert(!err);
+            if (!strcmp(instance_extension_names[i], extProp.name)) {
+                instance_extensions.push_back(extProp);
+                extFound = 1;
+            }
+        }
+        ASSERT_EQ(extFound, 1) << "ERROR: Cannot find extension named " << instance_extension_names[i] << " which is necessary to pass this test";
+    }
     instInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
     instInfo.pNext = NULL;
     instInfo.pAppInfo = &app_info;
     instInfo.pAllocCb = NULL;
-    instInfo.extensionCount = extensions.size();
-    instInfo.ppEnabledExtensionNames = (extensions.size()) ? &extensions[0] : NULL;;
+    instInfo.extensionCount = instance_extensions.size();
+    instInfo.pEnabledExtensions = (instance_extensions.size()) ? &instance_extensions[0] : NULL;
     err = vkCreateInstance(&instInfo, &this->inst);
     ASSERT_VK_SUCCESS(err);
+
     err = vkEnumeratePhysicalDevices(inst, &this->gpu_count, NULL);
     ASSERT_LE(this->gpu_count, ARRAY_SIZE(objs)) << "Too many gpus";
     ASSERT_VK_SUCCESS(err);
@@ -84,10 +113,42 @@
     ASSERT_VK_SUCCESS(err);
     ASSERT_GE(this->gpu_count, 1) << "No GPU available";
     if (dbgFunction) {
-        err = vkDbgRegisterMsgCallback(this->inst, dbgFunction, userData);
-        ASSERT_VK_SUCCESS(err);
+        m_dbgCreateMsgCallback = (PFN_vkDbgCreateMsgCallback) vkGetInstanceProcAddr(this->inst, "vkDbgCreateMsgCallback");
+        ASSERT_NE(m_dbgCreateMsgCallback, (PFN_vkDbgCreateMsgCallback) NULL) << "Did not get function pointer for DbgCreateMsgCallback";
+        if (m_dbgCreateMsgCallback) {
+            err = m_dbgCreateMsgCallback(this->inst,
+                                         VK_DBG_REPORT_ERROR_BIT | VK_DBG_REPORT_WARN_BIT,
+                                         dbgFunction,
+                                         userData,
+                                         &m_msgCallback);
+            ASSERT_VK_SUCCESS(err);
+        }
     }
-    m_device = new VkDeviceObj(0, objs[0]);
+
+    extSize = sizeof(extCount);
+    err = vkGetPhysicalDeviceExtensionInfo(objs[0], VK_EXTENSION_INFO_TYPE_COUNT, 0, &extSize, &extCount);
+    assert(!err);
+
+    extSize = sizeof(VkExtensionProperties);
+    for (uint32_t i = 0; i < device_extension_names.size(); i++) {
+        extFound = 0;
+        for (uint32_t j = 0; j < extCount; j++) {
+            err = vkGetPhysicalDeviceExtensionInfo(objs[0], VK_EXTENSION_INFO_TYPE_PROPERTIES, j, &extSize, &extProp);
+            assert(!err);
+            if (!strcmp(device_extension_names[i], extProp.name)) {
+                device_extensions.push_back(extProp);
+                extFound = 1;
+            }
+        }
+        ASSERT_EQ(extFound, 1) << "ERROR: Cannot find extension named " << device_extension_names[i] << " which is necessary to pass this test";
+    }
+    /* TODO: Testing unenabled extension */
+
+//    PFN_vkDbgSetObjectName obj_name = (PFN_vkDbgSetObjectName) vkGetInstanceProcAddr(this->inst,
+//                                                                                     "vkDbgSetObjectName");
+//    ASSERT_NE(obj_name, (PFN_vkDbgCreateMsgCallback) NULL) << "Did not get function pointer for DbgCreateMsgCallback";
+//    obj_name()
+    m_device = new VkDeviceObj(0, objs[0], device_extensions);
     m_device->get_device_queue();
 
     m_depthStencil = new VkDepthStencilObj();
@@ -301,6 +362,17 @@
     queue_props = &gpu().queue_properties()[0];
 }
 
+VkDeviceObj::VkDeviceObj(uint32_t id,
+        VkPhysicalDevice obj,
+        std::vector<VkExtensionProperties> extensions) :
+    vk_testing::Device(obj), id(id)
+{
+    init(extensions);
+
+    props = gpu().properties();
+    queue_props = &gpu().queue_properties()[0];
+}
+
 void VkDeviceObj::get_device_queue()
 {
     ASSERT_NE(true, graphics_queues().empty());
diff --git a/tests/vkrenderframework.h b/tests/vkrenderframework.h
index 285cd80..024bdba 100644
--- a/tests/vkrenderframework.h
+++ b/tests/vkrenderframework.h
@@ -29,13 +29,15 @@
 #define VKRENDERFRAMEWORK_H
 
 #include "vktestframework.h"
-#include <vkDbg.h>
+#include "vk_debug_report_lunarg.h"
+#include "vk_debug_marker_lunarg.h"
 
 
 class VkDeviceObj : public vk_testing::Device
 {
 public:
     VkDeviceObj(uint32_t id, VkPhysicalDevice obj);
+    VkDeviceObj(uint32_t id, VkPhysicalDevice obj, std::vector<VkExtensionProperties> extension_names);
 
     VkDevice device() { return obj(); }
     void get_device_queue();
@@ -94,7 +96,10 @@
     void InitRenderTarget(VkDepthStencilBindInfo *dsBinding);
     void InitRenderTarget(uint32_t targets, VkDepthStencilBindInfo *dsBinding);
     void InitFramework();
-    void InitFramework(const std::vector<const char *> &layers, VK_DBG_MSG_CALLBACK_FUNCTION=NULL, void *userData=NULL);
+    void InitFramework(std::vector<const char *> instance_extension_names,
+                       std::vector<const char *> device_extension_names,
+                       PFN_vkDbgMsgCallback=NULL,
+                       void *userData=NULL);
     void ShutdownFramework();
     void InitState();
 
@@ -123,6 +128,8 @@
     uint32_t                            m_stencil_clear_color;
     VkDepthStencilObj                  *m_depthStencil;
     VkMemoryRefManager                  m_mem_ref_mgr;
+    PFN_vkDbgCreateMsgCallback          m_dbgCreateMsgCallback;
+    VkDbgMsgCallback                    m_msgCallback;
 
     /*
      * SetUp and TearDown are called by the Google Test framework
diff --git a/tests/vktestbinding.cpp b/tests/vktestbinding.cpp
index 7edc74a..a9d0b21 100644
--- a/tests/vktestbinding.cpp
+++ b/tests/vktestbinding.cpp
@@ -126,34 +126,23 @@
     return get_info<VkPhysicalDeviceMemoryProperties>(gpu_, VK_PHYSICAL_DEVICE_INFO_TYPE_MEMORY_PROPERTIES, 1)[0];
 }
 
-std::vector<const char *> PhysicalGpu::layers(std::vector<char> &buf) const
+void PhysicalGpu::add_extension_dependencies(
+        uint32_t dependency_count,
+        VkExtensionProperties *depencency_props,
+        std::vector<VkExtensionProperties> &ext_list)
 {
-    const size_t max_layer_count = 16;
-    const size_t max_string_size = 256;
+    for (uint32_t i = 0; i < dependency_count; i++) {
 
-    buf.resize(max_layer_count * max_string_size);
-
-    std::vector<const char *> layers;
-    layers.reserve(max_layer_count);
-    for (size_t i = 0; i < max_layer_count; i++)
-        layers.push_back(&buf[0] + max_string_size * i);
-
-    char * const *out = const_cast<char * const *>(&layers[0]);
-    size_t count = max_layer_count; /* allow up to 16 layer names to be returned */
-    if (!EXPECT(vkEnumerateLayers(gpu_, max_string_size, &count, out, NULL) == VK_SUCCESS))
-        count = 0;
-    layers.resize(count);
-
-    return layers;
+    }
 }
 
-std::vector<const char *> PhysicalGpu::extensions() const
+std::vector<VkExtensionProperties> PhysicalGpu::extensions() const
 {
     // Extensions to enable
     static const char *known_exts[] = {
         "VK_WSI_LunarG",
     };
-    std::vector<const char *> exts;
+    std::vector<VkExtensionProperties> exts;
     size_t extSize = sizeof(uint32_t);
     uint32_t extCount = 0;
     if (!EXPECT(vkGetGlobalExtensionInfo(VK_EXTENSION_INFO_TYPE_COUNT, 0, &extSize, &extCount) == VK_SUCCESS))
@@ -166,8 +155,8 @@
         if (!EXPECT(vkGetGlobalExtensionInfo(VK_EXTENSION_INFO_TYPE_PROPERTIES, i, &extSize, &extProp) == VK_SUCCESS))
             return exts;
 
-        if (!strcmp(known_exts[0], extProp.extName))
-            exts.push_back(known_exts[i]);
+        if (!strcmp(known_exts[0], extProp.name))
+            exts.push_back(extProp);
     }
 
     return exts;
@@ -336,7 +325,7 @@
     EXPECT(vkDestroyDevice(obj()) == VK_SUCCESS);
 }
 
-void Device::init(bool enable_layers)
+void Device::init(std::vector<VkExtensionProperties> extensions)
 {
     // request all queues
     const std::vector<VkPhysicalDeviceQueueProperties> queue_props = gpu_.queue_properties();
@@ -352,27 +341,13 @@
         queue_info.push_back(qi);
     }
 
-    VkLayerCreateInfo layer_info = {};
-    layer_info.sType = VK_STRUCTURE_TYPE_LAYER_CREATE_INFO;
-
-    std::vector<const char *> layers;
-    std::vector<char> layer_buf;
-    // request all layers
-    if (enable_layers) {
-        layers = gpu_.layers(layer_buf);
-        layer_info.layerCount = layers.size();
-        layer_info.ppActiveLayerNames = &layers[0];
-    }
-
-    const std::vector<const char *> exts = gpu_.extensions();
-
     VkDeviceCreateInfo dev_info = {};
     dev_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
-    dev_info.pNext = (enable_layers) ? static_cast<void *>(&layer_info) : NULL;
+    dev_info.pNext = NULL;
     dev_info.queueRecordCount = queue_info.size();
     dev_info.pRequestedQueues = &queue_info[0];
-    dev_info.extensionCount = exts.size();
-    dev_info.ppEnabledExtensionNames = &exts[0];
+    dev_info.extensionCount = extensions.size();
+    dev_info.pEnabledExtensions = &extensions[0];
     dev_info.flags = 0;
 
     init(dev_info);
diff --git a/tests/vktestbinding.h b/tests/vktestbinding.h
index 809472f..a374cbc 100644
--- a/tests/vktestbinding.h
+++ b/tests/vktestbinding.h
@@ -78,7 +78,7 @@
 
 
     // vkGetGlobalExtensionInfo()
-    std::vector<const char *> extensions() const;
+    std::vector<VkExtensionProperties> extensions() const;
 
     // vkEnumerateLayers()
     std::vector<const char *> layers(std::vector<char> &buf) const;
@@ -87,6 +87,9 @@
     VkPhysicalDeviceCompatibilityInfo compatibility(const PhysicalGpu &other) const;
 
 private:
+    void add_extension_dependencies(uint32_t dependency_count,
+                                    VkExtensionProperties *depencency_props,
+                                    std::vector<VkExtensionProperties> &ext_list);
     VkPhysicalDevice gpu_;
 };
 
@@ -205,8 +208,8 @@
 
     // vkCreateDevice()
     void init(const VkDeviceCreateInfo &info);
-    void init(bool enable_layers); // all queues, all extensions, etc
-    void init() { init(false); };
+    void init(std::vector<VkExtensionProperties> extensions); // all queues, all extensions, etc
+    void init() { std::vector<VkExtensionProperties> extensions; init(extensions); };
 
     const PhysicalGpu &gpu() const { return gpu_; }
 
diff --git a/vk-layer-generate.py b/vk-layer-generate.py
index 43c1fc2..64b8613 100755
--- a/vk-layer-generate.py
+++ b/vk-layer-generate.py
@@ -157,96 +157,36 @@
             return ("%p", "(void*)(&%s)" % name)
         return ("%p", "(void*)(%s)" % name)
 
-    def _gen_layer_dbg_callback_register(self):
+    def _gen_create_msg_callback(self):
         r_body = []
-        r_body.append('VK_LAYER_EXPORT VkResult VKAPI vkDbgRegisterMsgCallback(VkInstance instance, VK_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback, void* pUserData)')
+        r_body.append('VK_LAYER_EXPORT VkResult VKAPI vkDbgCreateMsgCallback(VkInstance instance, VkFlags msgFlags, const PFN_vkDbgMsgCallback pfnMsgCallback, void* pUserData, VkDbgMsgCallback* pMsgCallback)')
         r_body.append('{')
-        r_body.append('    // This layer intercepts callbacks')
-        if self.layer_name == "ObjectTracker" or self.layer_name == "Threading":
-            r_body.append('    VK_LAYER_DBG_FUNCTION_NODE *pNewDbgFuncNode = new VK_LAYER_DBG_FUNCTION_NODE;')
-        else:
-            r_body.append('    VK_LAYER_DBG_FUNCTION_NODE *pNewDbgFuncNode = (VK_LAYER_DBG_FUNCTION_NODE*)malloc(sizeof(VK_LAYER_DBG_FUNCTION_NODE));')
-        r_body.append('    if (!pNewDbgFuncNode)')
-        r_body.append('        return VK_ERROR_OUT_OF_HOST_MEMORY;')
-        r_body.append('    pNewDbgFuncNode->pfnMsgCallback = pfnMsgCallback;')
-        r_body.append('    pNewDbgFuncNode->pUserData = pUserData;')
-        r_body.append('    pNewDbgFuncNode->pNext = g_pDbgFunctionHead;')
-        r_body.append('    g_pDbgFunctionHead = pNewDbgFuncNode;')
-        r_body.append('    // force callbacks if DebugAction hasn\'t been set already other than initial value')
-        r_body.append('    if (g_actionIsDefault) {')
-        r_body.append('        g_debugAction = VK_DBG_LAYER_ACTION_CALLBACK;')
-        r_body.append('    }')
-        r_body.append('    VkResult result = nextInstanceTable.DbgRegisterMsgCallback(instance, pfnMsgCallback, pUserData);')
-        r_body.append('    return result;')
+        r_body.append('    return layer_create_msg_callback(instance, &nextInstanceTable, msgFlags, pfnMsgCallback, pUserData, pMsgCallback);')
         r_body.append('}')
         return "\n".join(r_body)
 
-    def _gen_layer_dbg_callback_unregister(self):
-        ur_body = []
-        ur_body.append('VK_LAYER_EXPORT VkResult VKAPI vkDbgUnregisterMsgCallback(VkInstance instance, VK_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback)')
-        ur_body.append('{')
-        ur_body.append('    VK_LAYER_DBG_FUNCTION_NODE *pTrav = g_pDbgFunctionHead;')
-        ur_body.append('    VK_LAYER_DBG_FUNCTION_NODE *pPrev = pTrav;')
-        ur_body.append('    while (pTrav) {')
-        ur_body.append('        if (pTrav->pfnMsgCallback == pfnMsgCallback) {')
-        ur_body.append('            pPrev->pNext = pTrav->pNext;')
-        ur_body.append('            if (g_pDbgFunctionHead == pTrav)')
-        ur_body.append('                g_pDbgFunctionHead = pTrav->pNext;')
-        if self.layer_name == "ObjectTracker" or self.layer_name == "Threading":
-            ur_body.append('            delete pTrav;')
-        else:
-            ur_body.append('            free(pTrav);')
-        ur_body.append('            break;')
-        ur_body.append('        }')
-        ur_body.append('        pPrev = pTrav;')
-        ur_body.append('        pTrav = pTrav->pNext;')
-        ur_body.append('    }')
-        ur_body.append('    if (g_pDbgFunctionHead == NULL)')
-        ur_body.append('    {')
-        ur_body.append('        if (g_actionIsDefault)')
-        ur_body.append('            g_debugAction = VK_DBG_LAYER_ACTION_LOG_MSG;')
-        ur_body.append('        else')
-        ur_body.append('            g_debugAction = (VK_LAYER_DBG_ACTION)(g_debugAction & ~((uint32_t)VK_DBG_LAYER_ACTION_CALLBACK));')
-        ur_body.append('    }')
-        ur_body.append('    VkResult result = nextInstanceTable.DbgUnregisterMsgCallback(instance, pfnMsgCallback);')
-        ur_body.append('    return result;')
-        ur_body.append('}')
-        return "\n".join(ur_body)
+    def _gen_destroy_msg_callback(self):
+        r_body = []
+        r_body.append('VK_LAYER_EXPORT VkResult VKAPI vkDbgDestroyMsgCallback(VkInstance instance, VkDbgMsgCallback msgCallback)')
+        r_body.append('{')
+        r_body.append('    return layer_destroy_msg_callback(instance, &nextInstanceTable, msgCallback);')
+        r_body.append('}')
+        return "\n".join(r_body)
 
     def _gen_layer_get_global_extension_info(self, layer="Generic"):
         ggei_body = []
-        ggei_body.append('struct extProps {')
-        ggei_body.append('    uint32_t version;')
-        ggei_body.append('    const char * const name;')
+        ggei_body.append('#define LAYER_EXT_ARRAY_SIZE 1')
+        ggei_body.append('static const VkExtensionProperties layerExts[LAYER_EXT_ARRAY_SIZE] = {')
+        ggei_body.append('    {')
+        ggei_body.append('        VK_STRUCTURE_TYPE_EXTENSION_PROPERTIES,')
+        ggei_body.append('        "%s",' % layer)
+        ggei_body.append('        0x10,')
+        ggei_body.append('        "layer: %s",' % layer)
+        ggei_body.append('    }')
         ggei_body.append('};')
-        if layer == 'ObjectTracker':
-            ggei_body.append('#define LAYER_EXT_ARRAY_SIZE 6')
-            ggei_body.append('static const struct extProps layerExts[LAYER_EXT_ARRAY_SIZE] = {')
-            ggei_body.append('    // TODO what is the version?')
-            ggei_body.append('    {0x10, "%s"},' % layer)
-            ggei_body.append('    {0x10, "Validation"},')
-            ggei_body.append('    {0x10, "objTrackGetObjectsCount"},')
-            ggei_body.append('    {0x10, "objTrackGetObjects"},')
-            ggei_body.append('    {0x10, "objTrackGetObjectsOfTypeCount"},')
-            ggei_body.append('    {0x10, "objTrackGetObjectsOfType"}')
-            ggei_body.append('};')
-        elif layer == 'Threading':
-            ggei_body.append('#define LAYER_EXT_ARRAY_SIZE 2')
-            ggei_body.append('static const struct extProps layerExts[LAYER_EXT_ARRAY_SIZE] = {')
-            ggei_body.append('    // TODO what is the version?')
-            ggei_body.append('    {0x10, "%s"},' % layer)
-            ggei_body.append('    {0x10, "Validation"},')
-            ggei_body.append('};')
-        else:
-            ggei_body.append('#define LAYER_EXT_ARRAY_SIZE 1')
-            ggei_body.append('static const struct extProps layerExts[LAYER_EXT_ARRAY_SIZE] = {')
-            ggei_body.append('    // TODO what is the version?')
-            ggei_body.append('    {0x10, "%s"}' % layer)
-            ggei_body.append('};')
         ggei_body.append('')
         ggei_body.append('VK_LAYER_EXPORT VkResult VKAPI vkGetGlobalExtensionInfo(VkExtensionInfoType infoType, uint32_t extensionIndex, size_t* pDataSize, void* pData)')
         ggei_body.append('{')
-        ggei_body.append('    VkExtensionProperties *ext_props;')
         ggei_body.append('    uint32_t *count;')
         ggei_body.append('')
         ggei_body.append('    if (pDataSize == NULL)')
@@ -266,11 +206,7 @@
         ggei_body.append('                return VK_SUCCESS;')
         ggei_body.append('            if (extensionIndex >= LAYER_EXT_ARRAY_SIZE)')
         ggei_body.append('                return VK_ERROR_INVALID_VALUE;')
-        ggei_body.append('            ext_props = (VkExtensionProperties *) pData;')
-        ggei_body.append('            ext_props->version = layerExts[extensionIndex].version;')
-        ggei_body.append('            strncpy(ext_props->extName, layerExts[extensionIndex].name,')
-        ggei_body.append('                                        VK_MAX_EXTENSION_NAME);')
-        ggei_body.append("            ext_props->extName[VK_MAX_EXTENSION_NAME - 1] = '\\0';")
+        ggei_body.append('            memcpy((VkExtensionProperties *) pData, &layerExts[extensionIndex], sizeof(VkExtensionProperties));')
         ggei_body.append('            break;')
         ggei_body.append('        default:')
         ggei_body.append('            return VK_ERROR_INVALID_VALUE;')
@@ -292,10 +228,12 @@
                 intercept = self.generate_intercept(proto, qual)
                 if intercept is None:
                     # fill in default intercept for certain entrypoints
-                    if 'DbgRegisterMsgCallback' == proto.name:
-                        intercept = self._gen_layer_dbg_callback_register()
-                    elif 'DbgUnregisterMsgCallback' == proto.name:
-                        intercept = self._gen_layer_dbg_callback_unregister()
+                    if 'DbgCreateMsgCallback' == proto.name:
+                        intercept = self._gen_layer_dbg_create_msg_callback()
+                    elif 'DbgDestroyMsgCallback' == proto.name:
+                        intercept = self._gen_layer_dbg_destroy_msg_callback()
+                    elif 'CreateDevice' == proto.name:
+                        funcs.append('/* CreateDevice HERE */')
                     elif 'GetGlobalExtensionInfo' == proto.name:
                         intercept = self._gen_layer_get_global_extension_info(self.layer_name)
                 if intercept is not None:
@@ -347,12 +285,14 @@
 
     def _generate_extensions(self):
         exts = []
-        exts.append('uint64_t objTrackGetObjectsCount(void)')
+        exts.append(self._gen_create_msg_callback())
+        exts.append(self._gen_destroy_msg_callback())
+        exts.append('uint64_t objTrackGetObjectsCount(VkObjectType type)')
         exts.append('{')
         exts.append('    return numTotalObjs;')
         exts.append('}')
         exts.append('')
-        exts.append('VkResult objTrackGetObjects(uint64_t objCount, OBJTRACK_NODE* pObjNodeArray)')
+        exts.append('VkResult objTrackGetObjects(VkObjectType type, uint64_t objCount, OBJTRACK_NODE* pObjNodeArray)')
         exts.append('{')
         exts.append("    // This bool flags if we're pulling all objs or just a single class of objs")
         exts.append('    // Check the count first thing')
@@ -360,7 +300,7 @@
         exts.append('    if (objCount > maxObjCount) {')
         exts.append('        char str[1024];')
         exts.append('        sprintf(str, "OBJ ERROR : Received objTrackGetObjects() request for %lu objs, but there are only %lu total objs", objCount, maxObjCount);')
-        exts.append('        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, 0, 0, OBJTRACK_OBJCOUNT_MAX_EXCEEDED, "OBJTRACK", str);')
+        exts.append('        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, type, 0, 0, OBJTRACK_OBJCOUNT_MAX_EXCEEDED, "OBJTRACK", str);')
         exts.append('        return VK_ERROR_INVALID_VALUE;')
         exts.append('    }')
         exts.append('    auto it = objMap.begin();')
@@ -368,7 +308,7 @@
         exts.append('        if (objMap.end() == it) {')
         exts.append('            char str[1024];')
         exts.append('            sprintf(str, "OBJ INTERNAL ERROR : Ran out of objs! Should have %lu, but only copied %lu and not the requested %lu.", maxObjCount, i, objCount);')
-        exts.append('            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, 0, 0, OBJTRACK_INTERNAL_ERROR, "OBJTRACK", str);')
+        exts.append('            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, type, 0, 0, OBJTRACK_INTERNAL_ERROR, "OBJTRACK", str);')
         exts.append('            return VK_ERROR_UNKNOWN;')
         exts.append('        }')
         exts.append('        memcpy(&pObjNodeArray[i], it->second, sizeof(OBJTRACK_NODE));')
@@ -387,8 +327,8 @@
         exts.append('    uint64_t maxObjCount = numObjs[type];')
         exts.append('    if (objCount > maxObjCount) {')
         exts.append('        char str[1024];')
-        exts.append('        sprintf(str, "OBJ ERROR : Received objTrackGetObjects() request for %lu objs, but there are only %lu objs of type %s", objCount, maxObjCount, string_from_vulkan_object_type(type));')
-        exts.append('        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, 0, 0, OBJTRACK_OBJCOUNT_MAX_EXCEEDED, "OBJTRACK", str);')
+        exts.append('        sprintf(str, "OBJ ERROR : Received objTrackGetObjects() request for %lu objs, but there are only %lu objs of type %s", objCount, maxObjCount, string_VkObjectType(type));')
+        exts.append('        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, type, 0, 0, OBJTRACK_OBJCOUNT_MAX_EXCEEDED, "OBJTRACK", str);')
         exts.append('        return VK_ERROR_INVALID_VALUE;')
         exts.append('    }')
         exts.append('    auto it = objMap.begin();')
@@ -398,8 +338,8 @@
         exts.append('            ++it;')
         exts.append('        if (objMap.end() == it) {')
         exts.append('            char str[1024];')
-        exts.append('            sprintf(str, "OBJ INTERNAL ERROR : Ran out of %s objs! Should have %lu, but only copied %lu and not the requested %lu.", string_from_vulkan_object_type(type), maxObjCount, i, objCount);')
-        exts.append('            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, 0, 0, OBJTRACK_INTERNAL_ERROR, "OBJTRACK", str);')
+        exts.append('            sprintf(str, "OBJ INTERNAL ERROR : Ran out of %s objs! Should have %lu, but only copied %lu and not the requested %lu.", string_VkObjectType(type), maxObjCount, i, objCount);')
+        exts.append('            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, type, 0, 0, OBJTRACK_INTERNAL_ERROR, "OBJTRACK", str);')
         exts.append('            return VK_ERROR_UNKNOWN;')
         exts.append('        }')
         exts.append('        memcpy(&pObjNodeArray[i], it->second, sizeof(OBJTRACK_NODE));')
@@ -470,7 +410,7 @@
         if init_opts:
             func_body.append('    const char *strOpt;')
             func_body.append('    // initialize %s options' % self.layer_name)
-            func_body.append('    getLayerOptionEnum("%sReportLevel", (uint32_t *) &g_reportingLevel);' % self.layer_name)
+            func_body.append('    getLayerOptionEnum("%sReportLevel", (uint32_t *) &g_reportFlags);' % self.layer_name)
             func_body.append('    g_actionIsDefault = getLayerOptionEnum("%sDebugAction", (uint32_t *) &g_debugAction);' % self.layer_name)
             func_body.append('')
             func_body.append('    if (g_debugAction & VK_DBG_LAYER_ACTION_LOG_MSG)')
@@ -532,7 +472,7 @@
         return '#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include "loader_platform.h"\n#include "vkLayer.h"\n//The following is #included again to catch certain OS-specific functions being used:\n#include "loader_platform.h"\n\n#include "layers_config.h"\n#include "layers_msg.h"\n\nstatic VkLayerDispatchTable nextTable;\nstatic VkLayerInstanceDispatchTable nextInstanceTable;\nstatic VkBaseLayerObject *pCurObj;\n\nstatic LOADER_PLATFORM_THREAD_ONCE_DECLARATION(tabDeviceOnce);\nstatic LOADER_PLATFORM_THREAD_ONCE_DECLARATION(tabInstanceOnce);\nstatic LOADER_PLATFORM_THREAD_ONCE_DECLARATION(initOnce);'
 
     def generate_intercept(self, proto, qual):
-        if proto.name in [ 'DbgRegisterMsgCallback', 'DbgUnregisterMsgCallback' , 'GetGlobalExtensionInfo']:
+        if proto.name in [ 'GetGlobalExtensionInfo' ]:
             # use default version
             return None
         decl = proto.c_func(prefix="vk", attr="VKAPI")
@@ -546,30 +486,21 @@
         if proto.ret != "void":
             ret_val = "%s result = " % proto.ret
             stmt = "    return result;\n"
-        if proto.name == "EnumerateLayers":
+        elif proto.name == "CreateDevice":
             funcs.append('%s%s\n'
                      '{\n'
-                     '    char str[1024];\n'
-                     '    if (gpu != VK_NULL_HANDLE) {\n'
-                     '        sprintf(str, "At start of layered %s\\n");\n'
-                     '        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, gpu, 0, 0, (char *) "GENERIC", (char *) str);\n'
-                     '        pCurObj = (VkBaseLayerObject *) gpu;\n'
-                     '        loader_platform_thread_once(&initOnce, init%s);\n'
-                     '        loader_platform_thread_once(&tabDeviceOnce, initDeviceTable);\n'
-                     '        %snext%sTable.%s;\n'
-                     '        sprintf(str, "Completed layered %s\\n");\n'
-                     '        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, gpu, 0, 0, (char *) "GENERIC", (char *) str);\n'
-                     '        fflush(stdout);\n'
-                     '    %s'
-                     '    } else {\n'
-                     '        if (pLayerCount == NULL || pOutLayers == NULL || pOutLayers[0] == NULL)\n'
-                     '            return VK_ERROR_INVALID_POINTER;\n'
-                     '        // This layer compatible with all GPUs\n'
-                     '        *pLayerCount = 1;\n'
-                     '        strncpy((char *) pOutLayers[0], "%s", maxStringSize);\n'
-                     '        return VK_SUCCESS;\n'
+                     '    %snextInstanceTable.%s;\n'
+                     '    if (result == VK_SUCCESS) {\n'
+                     '        enable_debug_report(pCreateInfo->extensionCount, pCreateInfo->pEnabledExtensions);\n'
                      '    }\n'
-                     '}' % (qual, decl, proto.name, self.layer_name, ret_val, table, proto.c_call(), proto.name, stmt, self.layer_name))
+                     '%s'
+                     '}' % (qual, decl, ret_val, proto.c_call(), stmt))
+        elif proto.name == "DestroyObject":
+            funcs.append('%s%s\n'
+                     '{\n'
+                     '    %snextTable.%s;\n'
+                     '%s'
+                     '}' % (qual, decl, ret_val, proto.c_call(), stmt))
         else:
             funcs.append('%s%s\n'
                      '{\n'
@@ -582,6 +513,8 @@
         self.layer_name = "Generic"
         body = [self._generate_layer_initialization(True),
                 self._generate_dispatch_entrypoints("VK_LAYER_EXPORT"),
+                self._gen_create_msg_callback(),
+                self._gen_destroy_msg_callback(),
                 self._generate_layer_gpa_function()]
 
         return "\n\n".join(body)
@@ -843,6 +776,8 @@
                     if not i_decl:
                         log_func += '\n%suint32_t i;' % (indent)
                         i_decl = True
+                    log_func += '\n%sif (%s) {' % (indent, proto.params[sp_index].name)
+                    indent += '    '
                     log_func += '\n%sfor (i = 0; i < %s; i++) {' % (indent, sp_param_dict[sp_index])
                     indent += '    '
                     log_func += '\n%s%s' % (indent, cis_print_func)
@@ -857,34 +792,15 @@
                     log_func += '\n%s}' % (indent)
                     indent = indent[4:]
                     log_func += '\n%s}' % (indent)
+                    indent = indent[4:]
+                    log_func += '\n%s}' % (indent)
             indent = indent[4:]
             log_func += '\n%s}' % (indent)
         table = ''
         if proto_is_global(proto):
            table = 'Instance'
 
-        if proto.name == "EnumerateLayers":
-            funcs.append('%s%s\n'
-                     '{\n'
-                     '    using namespace StreamControl;\n'
-                     '    if (gpu != NULL) {\n'
-                     '        pCurObj = (VkBaseLayerObject *) gpu;\n'
-                     '        loader_platform_thread_once(&initOnce, init%s);\n'
-                     '        loader_platform_thread_once(&tabDeviceOnce, initDeviceTable);\n'
-                     '        %snext%sTable.%s;\n'
-                     '        %s    %s    %s\n'
-                     '    %s'
-                     '    } else {\n'
-                     '        if (pLayerCount == NULL || pOutLayers == NULL || pOutLayers[0] == NULL)\n'
-                     '            return VK_ERROR_INVALID_POINTER;\n'
-                     '        // This layer compatible with all GPUs\n'
-                     '        *pLayerCount = 1;\n'
-                     '        strncpy((char *) pOutLayers[0], "%s", maxStringSize);\n'
-                     '        return VK_SUCCESS;\n'
-                     '    }\n'
-                         '}' % (qual, decl, self.layer_name, ret_val, table, proto.c_call(),f_open, log_func, f_close, stmt, self.layer_name))
-        else:
-            funcs.append('%s%s\n'
+        funcs.append('%s%s\n'
                      '{\n'
                      '    using namespace StreamControl;\n'
                      '    %snext%sTable.%s;\n'
@@ -911,6 +827,7 @@
         header_txt.append('#include "loader_platform.h"')
         header_txt.append('#include "layers_config.h"')
         header_txt.append('#include "layers_msg.h"')
+        header_txt.append('#include "vk_debug_report_lunarg.h"')
         header_txt.append('static VkLayerDispatchTable nextTable;\nstatic VkLayerInstanceDispatchTable nextInstanceTable;\n')
         header_txt.append('static VkBaseLayerObject *pCurObj;')
         header_txt.append('static LOADER_PLATFORM_THREAD_ONCE_DECLARATION(initOnce);')
@@ -966,7 +883,7 @@
         header_txt.append('    if (objMap.find(object) == objMap.end()) {')
         header_txt.append('        char str[1024];')
         header_txt.append('        sprintf(str, "Invalid Object %p", (void*)object);')
-        header_txt.append('        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, object, 0, OBJTRACK_INVALID_OBJECT, "OBJTRACK", str);')
+        header_txt.append('        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, object, 0, OBJTRACK_OBJECT_TYPE_MISMATCH, "OBJTRACK", str);')
         header_txt.append('    }')
         header_txt.append('}')
         header_txt.append('')
@@ -983,7 +900,7 @@
         header_txt.append('            char str[1024];')
         header_txt.append('            sprintf(str, "ERROR: Object Parameter Type %s does not match designated type %s",')
         header_txt.append('                string_VkObjectType(pNode->objType), string_VkObjectType(objType));')
-        header_txt.append('            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, object, 0, OBJTRACK_OBJECT_TYPE_MISMATCH, "OBJTRACK", str);')
+        header_txt.append('            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, objType, object, 0, OBJTRACK_OBJECT_TYPE_MISMATCH, "OBJTRACK", str);')
         header_txt.append('        }')
         header_txt.append('    }')
         header_txt.append('}')
@@ -1003,7 +920,7 @@
         header_txt.append('    else {')
         header_txt.append('        char str[1024];')
         header_txt.append('        sprintf(str, "ERROR:  VK_ERROR_OUT_OF_HOST_MEMORY -- could not allocate memory for Queue Information");')
-        header_txt.append('        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, queue, 0, OBJTRACK_INTERNAL_ERROR, "OBJTRACK", str);')
+        header_txt.append('        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_QUEUE, queue, 0, OBJTRACK_INTERNAL_ERROR, "OBJTRACK", str);')
         header_txt.append('    }')
         header_txt.append('}')
         header_txt.append('')
@@ -1028,8 +945,8 @@
         header_txt.append('')
         header_txt.append('static void create_obj(VkObject vkObj, VkObjectType objType) {')
         header_txt.append('    char str[1024];')
-        header_txt.append('    sprintf(str, "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64 , object_track_index++, string_from_vulkan_object_type(objType), reinterpret_cast<VkUintPtrLeast64>(vkObj));')
-        header_txt.append('    layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, vkObj, 0, OBJTRACK_NONE, "OBJTRACK", str);')
+        header_txt.append('    sprintf(str, "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64 , object_track_index++, string_VkObjectType(objType), reinterpret_cast<VkUintPtrLeast64>(vkObj));')
+        header_txt.append('    layerCbMsg(VK_DBG_REPORT_INFO_BIT, objType, vkObj, 0, OBJTRACK_NONE, "OBJTRACK", str);')
         header_txt.append('    OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE;')
         header_txt.append('    pNewObjNode->vkObj = vkObj;')
         header_txt.append('    pNewObjNode->objType = objType;')
@@ -1050,15 +967,15 @@
         header_txt.append('        assert(numObjs[objIndex] > 0);')
         header_txt.append('        numObjs[objIndex]--;')
         header_txt.append('        char str[1024];')
-        header_txt.append('        sprintf(str, "OBJ_STAT Destroy %s obj 0x%" PRIxLEAST64 " (%lu total objs remain & %lu %s objs).", string_from_vulkan_object_type(pNode->objType), reinterpret_cast<VkUintPtrLeast64>(pNode->vkObj), numTotalObjs, numObjs[objIndex], string_from_vulkan_object_type(pNode->objType));')
-        header_txt.append('        layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, vkObj, 0, OBJTRACK_NONE, "OBJTRACK", str);')
+        header_txt.append('        sprintf(str, "OBJ_STAT Destroy %s obj 0x%" PRIxLEAST64 " (%lu total objs remain & %lu %s objs).", string_VkObjectType(pNode->objType), reinterpret_cast<VkUintPtrLeast64>(pNode->vkObj), numTotalObjs, numObjs[objIndex], string_VkObjectType(pNode->objType));')
+        header_txt.append('        layerCbMsg(VK_DBG_REPORT_INFO_BIT, pNode->objType, vkObj, 0, OBJTRACK_NONE, "OBJTRACK", str);')
         header_txt.append('        delete pNode;')
         header_txt.append('        objMap.erase(vkObj);')
         header_txt.append('    }')
         header_txt.append('    else {')
         header_txt.append('        char str[1024];')
         header_txt.append('        sprintf(str, "Unable to remove obj 0x%" PRIxLEAST64 ". Was it created? Has it already been destroyed?", reinterpret_cast<VkUintPtrLeast64>(vkObj));')
-        header_txt.append('        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, vkObj, 0, OBJTRACK_DESTROY_OBJECT_FAILED, "OBJTRACK", str);')
+        header_txt.append('        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, vkObj, 0, OBJTRACK_NONE, "OBJTRACK", str);')
         header_txt.append('    }')
         header_txt.append('}')
         header_txt.append('// Set selected flag state for an object node')
@@ -1072,8 +989,8 @@
         header_txt.append('        else {')
         header_txt.append('            // If we do not find it print an error')
         header_txt.append('            char str[1024];')
-        header_txt.append('            sprintf(str, "Unable to set status for non-existent object 0x%" PRIxLEAST64 " of %s type", reinterpret_cast<VkUintPtrLeast64>(vkObj), string_from_vulkan_object_type(objType));')
-        header_txt.append('            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, vkObj, 0, OBJTRACK_UNKNOWN_OBJECT, "OBJTRACK", str);')
+        header_txt.append('            sprintf(str, "Unable to set status for non-existent object 0x%" PRIxLEAST64 " of %s type", reinterpret_cast<VkUintPtrLeast64>(vkObj), string_VkObjectType(objType));')
+        header_txt.append('            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, vkObj, 0, OBJTRACK_NONE, "OBJTRACK", str);')
         header_txt.append('        }')
         header_txt.append('    }')
         header_txt.append('}')
@@ -1088,8 +1005,8 @@
         header_txt.append('    else {')
         header_txt.append('        // If we do not find it print an error')
         header_txt.append('        char str[1024];')
-        header_txt.append('        sprintf(str, "Unable to reset status for non-existent object 0x%" PRIxLEAST64 " of %s type", reinterpret_cast<VkUintPtrLeast64>(vkObj), string_from_vulkan_object_type(objType));')
-        header_txt.append('        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, vkObj, 0, OBJTRACK_UNKNOWN_OBJECT, "OBJTRACK", str);')
+        header_txt.append('        sprintf(str, "Unable to reset status for non-existent object 0x%" PRIxLEAST64 " of %s type", reinterpret_cast<VkUintPtrLeast64>(vkObj), string_VkObjectType(objType));')
+        header_txt.append('        layerCbMsg(VK_DBG_REPORT_ERROR_BIT, objType, vkObj, 0, OBJTRACK_UNKNOWN_OBJECT, "OBJTRACK", str);')
         header_txt.append('    }')
         header_txt.append('}')
         header_txt.append('')
@@ -1111,22 +1028,22 @@
         header_txt.append('        char str[1024];\n')
         header_txt.append('        if ((queueInfo != NULL) && (queueInfo[pQueueInfo->queueNodeIndex].queueFlags & VK_QUEUE_SPARSE_MEMMGR_BIT) == 0) {')
         header_txt.append('            sprintf(str, "Attempting %s on a non-memory-management capable queue -- VK_QUEUE_SPARSE_MEMMGR_BIT not set", function);')
-        header_txt.append('            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, queue, 0, OBJTRACK_UNKNOWN_OBJECT, "OBJTRACK", str);')
+        header_txt.append('            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_QUEUE, queue, 0, OBJTRACK_UNKNOWN_OBJECT, "OBJTRACK", str);')
         header_txt.append('        } else {')
         header_txt.append('            sprintf(str, "Attempting %s on a possibly non-memory-management capable queue -- VK_QUEUE_SPARSE_MEMMGR_BIT not known", function);')
-        header_txt.append('            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, queue, 0, OBJTRACK_UNKNOWN_OBJECT, "OBJTRACK", str);')
+        header_txt.append('            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_QUEUE, queue, 0, OBJTRACK_UNKNOWN_OBJECT, "OBJTRACK", str);')
         header_txt.append('        }')
         header_txt.append('    }')
         header_txt.append('}')
         header_txt.append('')
         header_txt.append('// Check object status for selected flag state')
-        header_txt.append('static bool32_t validate_status(VkObject vkObj, VkObjectType objType, ObjectStatusFlags status_mask, ObjectStatusFlags status_flag, VK_DBG_MSG_TYPE error_level, OBJECT_TRACK_ERROR error_code, const char* fail_msg) {')
+        header_txt.append('static bool32_t validate_status(VkObject vkObj, VkObjectType objType, ObjectStatusFlags status_mask, ObjectStatusFlags status_flag, VkFlags msg_flags, OBJECT_TRACK_ERROR error_code, const char* fail_msg) {')
         header_txt.append('    if (objMap.find(vkObj) != objMap.end()) {')
         header_txt.append('        OBJTRACK_NODE* pNode = objMap[vkObj];')
         header_txt.append('        if ((pNode->status & status_mask) != status_flag) {')
         header_txt.append('            char str[1024];')
-        header_txt.append('            sprintf(str, "OBJECT VALIDATION WARNING: %s object 0x%" PRIxLEAST64 ": %s", string_from_vulkan_object_type(objType), reinterpret_cast<VkUintPtrLeast64>(vkObj), fail_msg);')
-        header_txt.append('            layerCbMsg(error_level, VK_VALIDATION_LEVEL_0, vkObj, 0, error_code, "OBJTRACK", str);')
+        header_txt.append('            sprintf(str, "OBJECT VALIDATION WARNING: %s object 0x%" PRIxLEAST64 ": %s", string_VkObjectType(objType), reinterpret_cast<VkUintPtrLeast64>(vkObj), fail_msg);')
+        header_txt.append('            layerCbMsg(msg_flags, pNode->objType, vkObj, 0, OBJTRACK_UNKNOWN_OBJECT, "OBJTRACK", str);')
         header_txt.append('            return VK_FALSE;')
         header_txt.append('        }')
         header_txt.append('        return VK_TRUE;')
@@ -1134,8 +1051,8 @@
         header_txt.append('    else {')
         header_txt.append('        // If we do not find it print an error')
         header_txt.append('        char str[1024];')
-        header_txt.append('        sprintf(str, "Unable to obtain status for non-existent object 0x%" PRIxLEAST64 " of %s type", reinterpret_cast<VkUintPtrLeast64>(vkObj), string_from_vulkan_object_type(objType));')
-        header_txt.append('        layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, vkObj, 0, OBJTRACK_UNKNOWN_OBJECT, "OBJTRACK", str);')
+        header_txt.append('        sprintf(str, "Unable to obtain status for non-existent object 0x%" PRIxLEAST64 " of %s type", reinterpret_cast<VkUintPtrLeast64>(vkObj), string_VkObjectType(objType));')
+        header_txt.append('        layerCbMsg(msg_flags, (VkObjectType) 0, vkObj, 0, OBJTRACK_UNKNOWN_OBJECT, "OBJTRACK", str);')
         header_txt.append('        return VK_FALSE;')
         header_txt.append('    }')
         header_txt.append('}')
@@ -1143,7 +1060,7 @@
         return "\n".join(header_txt)
 
     def generate_intercept(self, proto, qual):
-        if proto.name in [ 'DbgRegisterMsgCallback', 'DbgUnregisterMsgCallback', 'GetGlobalExtensionInfo' ]:
+        if proto.name in [ 'DbgCreateMsgCallback', 'GetGlobalExtensionInfo' ]:
             # use default version
             return None
 
@@ -1191,13 +1108,13 @@
         elif 'GetFenceStatus' in proto.name:
             using_line  = '    loader_platform_thread_lock_mutex(&objLock);\n'
             using_line += '    // Warn if submitted_flag is not set\n'
-            using_line += '    validate_status(fence, VK_OBJECT_TYPE_FENCE, OBJSTATUS_FENCE_IS_SUBMITTED, OBJSTATUS_FENCE_IS_SUBMITTED, VK_DBG_MSG_ERROR, OBJTRACK_INVALID_FENCE, "Status Requested for Unsubmitted Fence");\n'
+            using_line += '    validate_status(fence, VK_OBJECT_TYPE_FENCE, OBJSTATUS_FENCE_IS_SUBMITTED, OBJSTATUS_FENCE_IS_SUBMITTED, VK_DBG_REPORT_ERROR_BIT, OBJTRACK_INVALID_FENCE, "Status Requested for Unsubmitted Fence");\n'
             mutex_unlock = True
         elif 'WaitForFences' in proto.name:
             using_line  = '    loader_platform_thread_lock_mutex(&objLock);\n'
             using_line += '    // Warn if waiting on unsubmitted fence\n'
             using_line += '    for (uint32_t i = 0; i < fenceCount; i++) {\n'
-            using_line += '        validate_status(pFences[i], VK_OBJECT_TYPE_FENCE, OBJSTATUS_FENCE_IS_SUBMITTED, OBJSTATUS_FENCE_IS_SUBMITTED, VK_DBG_MSG_ERROR, OBJTRACK_INVALID_FENCE, "Waiting for Unsubmitted Fence");\n'
+            using_line += '        validate_status(pFences[i], VK_OBJECT_TYPE_FENCE, OBJSTATUS_FENCE_IS_SUBMITTED, OBJSTATUS_FENCE_IS_SUBMITTED, VK_DBG_REPORT_ERROR_BIT, OBJTRACK_INVALID_FENCE, "Waiting for Unsubmitted Fence");\n'
             using_line += '    }\n'
             mutex_unlock = True
         elif 'MapMemory' in proto.name:
@@ -1218,6 +1135,11 @@
             create_line =  '    loader_platform_thread_lock_mutex(&objLock);\n'
             create_line += '    create_obj(*%s, %s);\n' % (proto.params[-1].name, obj_type_mapping[proto.params[-1].ty.strip('*').replace('const ', '')])
             create_line += '    loader_platform_thread_unlock_mutex(&objLock);\n'
+            if 'CreateDevice' in proto.name:
+                create_line += '    if (result == VK_SUCCESS) {\n'
+                create_line += '         enable_debug_report(pCreateInfo->extensionCount, pCreateInfo->pEnabledExtensions);\n'
+                create_line += '    }\n'
+
         if 'GetDeviceQueue' in proto.name:
             destroy_line  = '    loader_platform_thread_lock_mutex(&objLock);\n'
             destroy_line += '    addQueueInfo(queueNodeIndex, *pQueue);\n'
@@ -1237,8 +1159,8 @@
             destroy_line += '            // Cannot destroy physical device so ignore\n'
             destroy_line += '        } else {\n'
             destroy_line += '            char str[1024];\n'
-            destroy_line += '            sprintf(str, "OBJ ERROR : %s object 0x%" PRIxLEAST64 " has not been destroyed.", string_from_vulkan_object_type(pNode->objType), reinterpret_cast<VkUintPtrLeast64>(pNode->vkObj));\n'
-            destroy_line += '            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, device, 0, OBJTRACK_OBJECT_LEAK, "OBJTRACK", str);\n'
+            destroy_line += '            sprintf(str, "OBJ ERROR : %s object 0x%" PRIxLEAST64 " has not been destroyed.", string_VkObjectType(pNode->objType), reinterpret_cast<VkUintPtrLeast64>(pNode->vkObj));\n'
+            destroy_line += '            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_PHYSICAL_DEVICE, device, 0, OBJTRACK_OBJECT_LEAK, "OBJTRACK", str);\n'
             destroy_line += '        }\n'
             destroy_line += '    }\n'
             destroy_line += '    // Clean up Queue\'s MemRef Linked Lists\n'
@@ -1269,26 +1191,7 @@
         if proto_is_global(proto):
            table = 'Instance'
 
-        if proto.name == "EnumerateLayers":
-            funcs.append('%s%s\n'
-                     '{\n'
-                     '    if (gpu != VK_NULL_HANDLE) {\n'
-                     '        pCurObj = (VkBaseLayerObject *) gpu;\n'
-                     '        loader_platform_thread_once(&initOnce, init%s);\n'
-                     '        loader_platform_thread_once(&tabDeviceOnce, initDeviceTable);\n'
-                     '        %snext%sTable.%s;\n'
-                     '    %s%s'
-                     '    %s'
-                     '    } else {\n'
-                     '        if (pLayerCount == NULL || pOutLayers == NULL || pOutLayers[0] == NULL)\n'
-                     '            return VK_ERROR_INVALID_POINTER;\n'
-                     '        // This layer compatible with all GPUs\n'
-                     '        *pLayerCount = 1;\n'
-                     '        strncpy((char *) pOutLayers[0], "%s", maxStringSize);\n'
-                     '        return VK_SUCCESS;\n'
-                     '    }\n'
-                     '}' % (qual, decl, self.layer_name, ret_val, table, proto.c_call(), create_line, destroy_line, stmt, self.layer_name))
-        elif 'GetPhysicalDeviceInfo' in proto.name:
+        if 'GetPhysicalDeviceInfo' in proto.name:
             gpu_state  = '    if (infoType == VK_PHYSICAL_DEVICE_INFO_TYPE_QUEUE_PROPERTIES) {\n'
             gpu_state += '        if (pData != NULL) {\n'
             gpu_state += '            loader_platform_thread_lock_mutex(&objLock);\n'
@@ -1362,7 +1265,7 @@
         header_txt.append('        if (objectsInUse[object] != tid) {')
         header_txt.append('            char str[1024];')
         header_txt.append('            sprintf(str, "THREADING ERROR : object of type %s is simultaneously used in thread %ld and thread %ld", type, objectsInUse[object], tid);')
-        header_txt.append('            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, 0, 0, THREADING_CHECKER_MULTIPLE_THREADS, "THREADING", str);')
+        header_txt.append('            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, 0, 0, THREADING_CHECKER_MULTIPLE_THREADS, "THREADING", str);')
         header_txt.append('            // Wait for thread-safe access to object')
         header_txt.append('            while (objectsInUse.find(object) != objectsInUse.end()) {')
         header_txt.append('                loader_platform_thread_cond_wait(&threadingCond, &threadingLock);')
@@ -1371,7 +1274,7 @@
         header_txt.append('        } else {')
         header_txt.append('            char str[1024];')
         header_txt.append('            sprintf(str, "THREADING ERROR : object of type %s is recursively used in thread %ld", type, tid);')
-        header_txt.append('            layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, 0, 0, THREADING_CHECKER_SINGLE_THREAD_REUSE, "THREADING", str);')
+        header_txt.append('            layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, 0, 0, THREADING_CHECKER_SINGLE_THREAD_REUSE, "THREADING", str);')
         header_txt.append('        }')
         header_txt.append('    }')
         header_txt.append('    loader_platform_thread_unlock_mutex(&threadingLock);')
@@ -1387,7 +1290,7 @@
         return "\n".join(header_txt)
 
     def generate_intercept(self, proto, qual):
-        if proto.name in [ 'DbgRegisterMsgCallback', 'DbgUnregisterMsgCallback' ]:
+        if proto.name in [ 'DbgCreateMsgCallback' ]:
             # use default version
             return None
         decl = proto.c_func(prefix="vk", attr="VKAPI")
@@ -1412,26 +1315,6 @@
         if proto_is_global(proto):
            table = 'Instance'
 
-        if proto.name == "EnumerateLayers":
-            funcs.append('%s%s\n'
-                     '{\n'
-                     '    if (gpu != NULL) {\n'
-                     '        pCurObj = (VkBaseLayerObject *) %s;\n'
-                     '        loader_platform_thread_once(&initOnce, init%s);\n'
-                     '        loader_platform_thread_once(&tabDeviceOnce, initDeviceTable);\n'
-                     '        %snext%sTable.%s;\n'
-                     '        fflush(stdout);\n'
-                     '    %s'
-                     '    } else {\n'
-                     '        if (pLayerCount == NULL || pOutLayers == NULL || pOutLayers[0] == NULL)\n'
-                     '            return VK_ERROR_INVALID_POINTER;\n'
-                     '        // This layer compatible with all GPUs\n'
-                     '        *pLayerCount = 1;\n'
-                     '        strncpy((char *) pOutLayers[0], "%s", maxStringSize);\n'
-                     '        return VK_SUCCESS;\n'
-                     '    }\n'
-                     '}' % (qual, decl, proto.params[0].name, self.layer_name, ret_val, table, proto.c_call(), stmt, self.layer_name))
-            return "\n".join(funcs)
         # Memory range calls are special in needed thread checking within structs
         if proto.name in ["FlushMappedMemoryRanges","InvalidateMappedMemoryRanges"]:
             funcs.append('%s%s\n'
diff --git a/vk_helper.py b/vk_helper.py
index 7d20125..4a7dce5 100755
--- a/vk_helper.py
+++ b/vk_helper.py
@@ -257,8 +257,13 @@
         self.struct_dict[struct_type][num]['type'] = member_type
         if '[' in member_name:
             (member_name, array_size) = member_name.split('[', 1)
-            self.struct_dict[struct_type][num]['array'] = True
-            self.struct_dict[struct_type][num]['array_size'] = array_size.strip(']')
+            if 'char' in member_type:
+                self.struct_dict[struct_type][num]['array'] = False
+                self.struct_dict[struct_type][num]['array_size'] = 0
+                self.struct_dict[struct_type][num]['ptr'] = True
+            else:
+                self.struct_dict[struct_type][num]['array'] = True
+                self.struct_dict[struct_type][num]['array_size'] = array_size.strip(']')
         elif self._is_dynamic_array(self.struct_dict[struct_type][num]['full_type'], member_name):
             #print("Found dynamic array %s of size %s" % (member_name, self.last_struct_count_name))
             self.struct_dict[struct_type][num]['array'] = True
@@ -778,17 +783,17 @@
                     addr_char = '&'
                     if 1 < stp_list[index]['full_type'].count('*'):
                         addr_char = ''
-                    if (stp_list[index]['array']):
-                        #sh_funcs.append('/* A */');
+                    if (stp_list[index]['array'] and 'char' not in stp_list[index]['type']):
+                        sh_funcs.append('/* A */');
                         if stp_list[index]['dyn_array']:
-                            #sh_funcs.append('/* AA */');
+                            sh_funcs.append('/* AA */');
                             array_count = 'pStruct->%s' % (stp_list[index]['array_size'])
                         else:
-                            #sh_funcs.append('/* AB */');
+                            sh_funcs.append('/* AB */');
                             array_count = '%s' % (stp_list[index]['array_size'])
                         sh_funcs.append('%sstp_strs[%u] = "";' % (indent, index))
                         if not idx_ss_decl:
-                            #sh_funcs.append('/* AC */');
+                            sh_funcs.append('/* AC */');
                             sh_funcs.append('%sstringstream index_ss;' % (indent))
                             idx_ss_decl = True
                         sh_funcs.append('%sif (pStruct->%s) {' % (indent, stp_list[index]['name']))
@@ -808,10 +813,10 @@
                             sh_funcs.append('%sss[%u] << %spStruct->%s[i];' % (indent, index, addr_char, stp_list[index]['name']))
                             sh_funcs.append('%stmp_str = %s(%spStruct->%s[i], extra_indent);' % (indent, self._get_sh_func_name(stp_list[index]['type']), addr_char, stp_list[index]['name']))
                             if self.no_addr:
-                                #sh_funcs.append('/* ADA */');
+                                sh_funcs.append('/* AEA */');
                                 sh_funcs.append('%sstp_strs[%u] += " " + prefix + "%s[" + index_ss.str() + "] (addr)\\n" + tmp_str;' % (indent, index, stp_list[index]['name']))
                             else:
-                                #sh_funcs.append('/* ADB */');
+                                sh_funcs.append('/* AEB */');
                                 sh_funcs.append('%sstp_strs[%u] += " " + prefix + "%s[" + index_ss.str() + "] (" + ss[%u].str() + ")\\n" + tmp_str;' % (indent, index, stp_list[index]['name'], index))
                         else:
                             #sh_funcs.append('/* AD */');
@@ -824,7 +829,7 @@
                         indent = indent[4:]
                         sh_funcs.append('%s}' % (indent))
                     elif (stp_list[index]['ptr']):
-                        #sh_funcs.append('/* B */');
+                        sh_funcs.append('/* B */');
                         sh_funcs.append('    if (pStruct->%s) {' % stp_list[index]['name'])
                         if 'pNext' == stp_list[index]['name']:
                             sh_funcs.append('        tmp_str = dynamic_display((void*)pStruct->pNext, prefix);')
diff --git a/vulkan.py b/vulkan.py
index 796a280..97976c4 100755
--- a/vulkan.py
+++ b/vulkan.py
@@ -181,7 +181,7 @@
 # VK core API
 core = Extension(
     name="VK_CORE",
-    headers=["vulkan.h", "vkDbg.h"],
+    headers=["vulkan.h", "vk_debug_report_lunarg.h"],
 
     objects=[
         "VkInstance",
@@ -264,13 +264,6 @@
              Param("size_t*", "pDataSize"),
              Param("void*", "pData")]),
 
-        Proto("VkResult", "EnumerateLayers",
-            [Param("VkPhysicalDevice", "gpu"),
-             Param("size_t", "maxStringSize"),
-             Param("size_t*", "pLayerCount"),
-             Param("char* const*", "pOutLayers"),
-             Param("void*", "pReserved")]),
-
         Proto("VkResult", "GetDeviceQueue",
             [Param("VkDevice", "device"),
              Param("uint32_t", "queueNodeIndex"),
@@ -879,49 +872,6 @@
         Proto("void", "CmdEndRenderPass",
             [Param("VkCmdBuffer", "cmdBuffer"),
              Param("VkRenderPass", "renderPass")]),
-
-        Proto("VkResult", "DbgSetValidationLevel",
-            [Param("VkDevice", "device"),
-             Param("VkValidationLevel", "validationLevel")]),
-
-        Proto("VkResult", "DbgRegisterMsgCallback",
-            [Param("VkInstance", "instance"),
-             Param("VK_DBG_MSG_CALLBACK_FUNCTION", "pfnMsgCallback"),
-             Param("void*", "pUserData")]),
-
-        Proto("VkResult", "DbgUnregisterMsgCallback",
-            [Param("VkInstance", "instance"),
-             Param("VK_DBG_MSG_CALLBACK_FUNCTION", "pfnMsgCallback")]),
-
-        Proto("VkResult", "DbgSetMessageFilter",
-            [Param("VkDevice", "device"),
-             Param("int32_t", "msgCode"),
-             Param("VK_DBG_MSG_FILTER", "filter")]),
-
-        Proto("VkResult", "DbgSetObjectTag",
-            [Param("VkDevice", "device"),
-             Param("VkObject", "object"),
-             Param("size_t", "tagSize"),
-             Param("const void*", "pTag")]),
-
-        Proto("VkResult", "DbgSetGlobalOption",
-            [Param("VkInstance", "instance"),
-             Param("VK_DBG_GLOBAL_OPTION", "dbgOption"),
-             Param("size_t", "dataSize"),
-             Param("const void*", "pData")]),
-
-        Proto("VkResult", "DbgSetDeviceOption",
-            [Param("VkDevice", "device"),
-             Param("VK_DBG_DEVICE_OPTION", "dbgOption"),
-             Param("size_t", "dataSize"),
-             Param("const void*", "pData")]),
-
-        Proto("void", "CmdDbgMarkerBegin",
-            [Param("VkCmdBuffer", "cmdBuffer"),
-             Param("const char*", "pMarker")]),
-
-        Proto("void", "CmdDbgMarkerEnd",
-            [Param("VkCmdBuffer", "cmdBuffer")]),
     ],
 )
 
@@ -931,6 +881,7 @@
     objects=[
         "VkDisplayWSI",
         "VkSwapChainWSI",
+        "VkDbgMsgCallback",
     ],
     protos=[
         Proto("VkResult", "GetDisplayInfoWSI",
@@ -956,6 +907,13 @@
         Proto("VkResult", "QueuePresentWSI",
             [Param("VkQueue", "queue"),
              Param("const VkPresentInfoWSI*", "pPresentInfo")]),
+
+#        Proto("VkResult", "DbgCreateMsgCallback",
+#            [Param("VkInstance", "instance"),
+#             Param("VkFlags", "msgFlags"),
+#             Param("PFN_vkDbgMsgCallback", "pfnMsgCallback"),
+#             Param("void*", "pUserData"),
+#             Param("VkDbgMsgCallback*", "pMsgCallback")]),
     ],
 )
 
@@ -1068,7 +1026,7 @@
 
     # make them an extension and print
     ext = Extension("VK_CORE",
-            headers=["vulkan.h", "vkDbg.h"],
+            headers=["vulkan.h", "vk_debug_report_lunarg.h"],
             objects=object_lines,
             protos=protos)
     print("core =", str(ext))