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/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
 }