vulkan: Add vkGetGlobalExtensionInfo entrypoint

have loader use it to enumerate all extensions from layers and drivers.
Non-gode_gen layers also updated to include vkGetGlobalExtensionInfo

Includes verion info as part of GetExtensionSupport return data.

TODO: vk-layer-generate needs work

v2: do not check for non-existing ENABLE_WSI_X11 (olv)
diff --git a/layers/basic.cpp b/layers/basic.cpp
index 524bd40..d82c6c5 100644
--- a/layers/basic.cpp
+++ b/layers/basic.cpp
@@ -61,6 +61,59 @@
     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"
+};
+
+VK_LAYER_EXPORT VkResult VKAPI vkGetGlobalExtensionInfo(
+                                               VkExtensionInfoType infoType,
+                                               uint32_t extensionIndex,
+                                               size_t*  pDataSize,
+                                               void*    pData)
+{
+    VkResult result;
+
+    /* 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 = BASIC_LAYER_EXT_ARRAY_SIZE;
+            break;
+        case VK_EXTENSION_INFO_TYPE_PROPERTIES:
+            *pDataSize = sizeof(VkExtensionProperties);
+            if (pData == NULL)
+                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';
+            break;
+        default:
+            return VK_ERROR_INVALID_VALUE;
+    };
+
+    return VK_SUCCESS;
+}
+
 VK_LAYER_EXPORT VkResult VKAPI vkGetExtensionSupport(VkPhysicalGpu gpu, const char* pExtName)
 {
     VkResult result;
diff --git a/layers/draw_state.cpp b/layers/draw_state.cpp
index 58db632..e74fa18 100644
--- a/layers/draw_state.cpp
+++ b/layers/draw_state.cpp
@@ -1466,6 +1466,58 @@
     return result;
 }
 
+struct extProps {
+    uint32_t version;
+    const char * const name;
+};
+#define DRAW_STATE_LAYER_EXT_ARRAY_SIZE 1
+static const struct extProps dsExts[DRAW_STATE_LAYER_EXT_ARRAY_SIZE] = {
+    // TODO what is the version?
+    0x10, "DrawState"
+};
+
+VK_LAYER_EXPORT VkResult VKAPI vkGetGlobalExtensionInfo(
+                                               VkExtensionInfoType infoType,
+                                               uint32_t extensionIndex,
+                                               size_t*  pDataSize,
+                                               void*    pData)
+{
+    VkResult result;
+
+    /* 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 = DRAW_STATE_LAYER_EXT_ARRAY_SIZE;
+            break;
+        case VK_EXTENSION_INFO_TYPE_PROPERTIES:
+            *pDataSize = sizeof(VkExtensionProperties);
+            if (pData == NULL)
+                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';
+            break;
+        default:
+            return VK_ERROR_INVALID_VALUE;
+    };
+
+    return VK_SUCCESS;
+}
+
 VK_LAYER_EXPORT VkResult VKAPI vkGetExtensionSupport(VkPhysicalGpu gpu, const char* pExtName)
 {
     VkResult result;
diff --git a/layers/mem_tracker.cpp b/layers/mem_tracker.cpp
index 86fd02d..e7f1f7e 100644
--- a/layers/mem_tracker.cpp
+++ b/layers/mem_tracker.cpp
@@ -864,6 +864,58 @@
     return result;
 }
 
+struct extProps {
+    uint32_t version;
+    const char * const name;
+};
+#define MEM_TRACKER_LAYER_EXT_ARRAY_SIZE 1
+static const struct extProps mtExts[MEM_TRACKER_LAYER_EXT_ARRAY_SIZE] = {
+    // TODO what is the version?
+    0x10, "MemTracker"
+};
+
+VK_LAYER_EXPORT VkResult VKAPI vkGetGlobalExtensionInfo(
+                                               VkExtensionInfoType infoType,
+                                               uint32_t extensionIndex,
+                                               size_t*  pDataSize,
+                                               void*    pData)
+{
+    VkResult result;
+
+    /* 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 = MEM_TRACKER_LAYER_EXT_ARRAY_SIZE;
+            break;
+        case VK_EXTENSION_INFO_TYPE_PROPERTIES:
+            *pDataSize = sizeof(VkExtensionProperties);
+            if (pData == NULL)
+                return VK_SUCCESS;
+            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';
+            break;
+        default:
+            return VK_ERROR_INVALID_VALUE;
+    };
+
+    return VK_SUCCESS;
+}
+
 VK_LAYER_EXPORT VkResult VKAPI vkGetExtensionSupport(VkPhysicalGpu gpu, const char* pExtName)
 {
     VkResult result;
diff --git a/layers/multi.cpp b/layers/multi.cpp
index 910bc5b..c590620 100644
--- a/layers/multi.cpp
+++ b/layers/multi.cpp
@@ -283,6 +283,60 @@
     return VK_SUCCESS;
 }
 
+struct extProps {
+    uint32_t version;
+    const char * const name;
+};
+
+#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",
+};
+
+VK_LAYER_EXPORT VkResult VKAPI vkGetGlobalExtensionInfo(
+                                               VkExtensionInfoType infoType,
+                                               uint32_t extensionIndex,
+                                               size_t*  pDataSize,
+                                               void*    pData)
+{
+    VkResult result;
+
+    /* 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 = MULTI_LAYER_EXT_ARRAY_SIZE;
+            break;
+        case VK_EXTENSION_INFO_TYPE_PROPERTIES:
+            *pDataSize = sizeof(VkExtensionProperties);
+            if (pData == NULL)
+                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';
+            break;
+        default:
+            return VK_ERROR_INVALID_VALUE;
+    };
+
+    return VK_SUCCESS;
+}
+
 VK_LAYER_EXPORT VkResult VKAPI vkGetExtensionSupport(VkPhysicalGpu gpu, const char* pExtName)
 {
     VkResult result;
diff --git a/layers/param_checker.cpp b/layers/param_checker.cpp
index 5687a54..e7c7e63 100644
--- a/layers/param_checker.cpp
+++ b/layers/param_checker.cpp
@@ -257,6 +257,59 @@
     return result;
 }
 
+struct extProps {
+    uint32_t version;
+    const char * const name;
+};
+
+#define PARAM_CHECKER_LAYER_EXT_ARRAY_SIZE 1
+static const struct extProps pcExts[PARAM_CHECKER_LAYER_EXT_ARRAY_SIZE] = {
+    // TODO what is the version?
+    0x10, "ParamChecker",
+};
+
+VK_LAYER_EXPORT VkResult VKAPI vkGetGlobalExtensionInfo(
+                                               VkExtensionInfoType infoType,
+                                               uint32_t extensionIndex,
+                                               size_t*  pDataSize,
+                                               void*    pData)
+{
+    VkResult result;
+
+    /* 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 = PARAM_CHECKER_LAYER_EXT_ARRAY_SIZE;
+            break;
+        case VK_EXTENSION_INFO_TYPE_PROPERTIES:
+            *pDataSize = sizeof(VkExtensionProperties);
+            if (pData == NULL)
+                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';
+            break;
+        default:
+            return VK_ERROR_INVALID_VALUE;
+    };
+
+    return VK_SUCCESS;
+}
+
 VK_LAYER_EXPORT VkResult VKAPI vkGetExtensionSupport(VkPhysicalGpu gpu, const char* pExtName)
 {
     pCurObj = (VkBaseLayerObject *) gpu;