loader: Allow layers to call pre-instance commands

Add a mechanism whereby layers can get function pointers to, and call
vkEnumerateInstanceExtensionProperties and
vkEnumerateInstanceLayerProperties

Change-Id: I7de3196fc689c1529f37930245fc9c07e248ec44
diff --git a/include/vulkan/vk_layer.h b/include/vulkan/vk_layer.h
index 147dcd4..cd68a23 100644
--- a/include/vulkan/vk_layer.h
+++ b/include/vulkan/vk_layer.h
@@ -82,7 +82,8 @@
  */
 typedef enum VkLayerFunction_ {
     VK_LAYER_LINK_INFO = 0,
-    VK_LOADER_DATA_CALLBACK = 1
+    VK_LOADER_DATA_CALLBACK = 1,
+    VK_LAYER_PRE_INSTANCE_COMMANDS = 2,
 } VkLayerFunction;
 
 typedef struct VkLayerInstanceLink_ {
@@ -91,6 +92,12 @@
     PFN_GetPhysicalDeviceProcAddr pfnNextGetPhysicalDeviceProcAddr;
 } VkLayerInstanceLink;
 
+typedef struct {
+    PFN_vkEnumerateInstanceExtensionProperties pfnEnumerateInstanceExtensionProperties;
+    PFN_vkEnumerateInstanceLayerProperties pfnEnumerateInstanceLayerProperties;
+    PFN_vkVoidFunction reserved;
+} VkLayerPreInstanceCommands;
+
 /*
  * When creating the device chain the loader needs to pass
  * down information about it's device structure needed at
@@ -115,6 +122,7 @@
     union {
         VkLayerInstanceLink *pLayerInfo;
         PFN_vkSetInstanceLoaderData pfnSetInstanceLoaderData;
+        VkLayerPreInstanceCommands *pPreInstanceCommands;
     } u;
 } VkLayerInstanceCreateInfo;
 
diff --git a/loader/loader.c b/loader/loader.c
index dcb2ef1..972d8fc 100644
--- a/loader/loader.c
+++ b/loader/loader.c
@@ -4461,6 +4461,8 @@
     uint32_t activated_layers = 0;
     VkLayerInstanceCreateInfo chain_info;
     VkLayerInstanceLink *layer_instance_link_info = NULL;
+    VkLayerInstanceCreateInfo pre_instance_info;
+    VkLayerPreInstanceCommands pre_instance_commands;
     VkInstanceCreateInfo loader_create_info;
     VkResult res;
 
@@ -4472,8 +4474,16 @@
     memcpy(&loader_create_info, pCreateInfo, sizeof(VkInstanceCreateInfo));
 
     if (inst->expanded_activated_layer_list.count > 0) {
+        pre_instance_info.sType = VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO;
+        pre_instance_info.pNext = pCreateInfo->pNext;
+        pre_instance_info.function = VK_LAYER_PRE_INSTANCE_COMMANDS;
+        pre_instance_commands.pfnEnumerateInstanceExtensionProperties = &vkEnumerateInstanceExtensionProperties;
+        pre_instance_commands.pfnEnumerateInstanceLayerProperties = &vkEnumerateInstanceLayerProperties;
+        pre_instance_commands.reserved = NULL;
+        pre_instance_info.u.pPreInstanceCommands = &pre_instance_commands;
+
         chain_info.u.pLayerInfo = NULL;
-        chain_info.pNext = pCreateInfo->pNext;
+        chain_info.pNext = &pre_instance_info;
         chain_info.sType = VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO;
         chain_info.function = VK_LAYER_LINK_INFO;
         loader_create_info.pNext = &chain_info;