Add support for VK_FUCHSIA_imagepipe_surface
diff --git a/loader/generated/vk_loader_extensions.c b/loader/generated/vk_loader_extensions.c
index 72d4027..d4cbd76 100644
--- a/loader/generated/vk_loader_extensions.c
+++ b/loader/generated/vk_loader_extensions.c
@@ -3564,28 +3564,6 @@
 }
 
 
-// ---- VK_FUCHSIA_imagepipe_surface extension trampoline/terminators
-
-#ifdef VK_USE_PLATFORM_FUCHSIA
-VKAPI_ATTR VkResult VKAPI_CALL CreateImagePipeSurfaceFUCHSIA(
-    VkInstance                                  instance,
-    const VkImagePipeSurfaceCreateInfoFUCHSIA*  pCreateInfo,
-    const VkAllocationCallbacks*                pAllocator,
-    VkSurfaceKHR*                               pSurface) {
-#error("Not implemented. Likely needs to be manually generated!");
-    return disp->CreateImagePipeSurfaceFUCHSIA(instance, pCreateInfo, pAllocator, pSurface);
-}
-
-VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateImagePipeSurfaceFUCHSIA(
-    VkInstance                                  instance,
-    const VkImagePipeSurfaceCreateInfoFUCHSIA*  pCreateInfo,
-    const VkAllocationCallbacks*                pAllocator,
-    VkSurfaceKHR*                               pSurface) {
-#error("Not implemented. Likely needs to be manually generated!");
-}
-
-#endif // VK_USE_PLATFORM_FUCHSIA
-
 // ---- VK_EXT_buffer_device_address extension trampoline/terminators
 
 VKAPI_ATTR VkDeviceAddress VKAPI_CALL GetBufferDeviceAddressEXT(
@@ -4943,16 +4921,6 @@
         return true;
     }
 
-    // ---- VK_FUCHSIA_imagepipe_surface extension commands
-#ifdef VK_USE_PLATFORM_FUCHSIA
-    if (!strcmp("vkCreateImagePipeSurfaceFUCHSIA", name)) {
-        *addr = (ptr_instance->enabled_known_extensions.fuchsia_imagepipe_surface == 1)
-                     ? (void *)CreateImagePipeSurfaceFUCHSIA
-                     : NULL;
-        return true;
-    }
-#endif // VK_USE_PLATFORM_FUCHSIA
-
     // ---- VK_EXT_buffer_device_address extension commands
     if (!strcmp("vkGetBufferDeviceAddressEXT", name)) {
         *addr = (void *)GetBufferDeviceAddressEXT;
@@ -5278,12 +5246,6 @@
     // ---- VK_EXT_debug_utils extension commands
         } else if (0 == strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_DEBUG_UTILS_EXTENSION_NAME)) {
             ptr_instance->enabled_known_extensions.ext_debug_utils = 1;
-
-    // ---- VK_FUCHSIA_imagepipe_surface extension commands
-#ifdef VK_USE_PLATFORM_FUCHSIA
-        } else if (0 == strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_FUCHSIA_IMAGEPIPE_SURFACE_EXTENSION_NAME)) {
-            ptr_instance->enabled_known_extensions.fuchsia_imagepipe_surface = 1;
-#endif // VK_USE_PLATFORM_FUCHSIA
         }
     }
 }
diff --git a/loader/generated/vk_loader_extensions.h b/loader/generated/vk_loader_extensions.h
index 9835e16..b008dee 100644
--- a/loader/generated/vk_loader_extensions.h
+++ b/loader/generated/vk_loader_extensions.h
@@ -453,7 +453,6 @@
         uint8_t ext_acquire_xlib_display : 1;
         uint8_t ext_display_surface_counter : 1;
         uint8_t ext_debug_utils : 1;
-        uint8_t fuchsia_imagepipe_surface : 1;
     };
     uint64_t padding[4];
 };
diff --git a/loader/loader.h b/loader/loader.h
index 621eb0b..4779f8e 100644
--- a/loader/loader.h
+++ b/loader/loader.h
@@ -342,6 +342,9 @@
 #if defined(VK_USE_PLATFORM_METAL_EXT)
     bool wsi_metal_surface_enabled;
 #endif
+#ifdef VK_USE_PLATFORM_FUCHSIA
+    bool wsi_imagepipe_surface_enabled;
+#endif
     bool wsi_display_enabled;
     bool wsi_display_props2_enabled;
 };
diff --git a/loader/wsi.c b/loader/wsi.c
index 804046c..0d687b2 100644
--- a/loader/wsi.c
+++ b/loader/wsi.c
@@ -64,6 +64,9 @@
 #ifdef VK_USE_PLATFORM_IOS_MVK
     ptr_instance->wsi_ios_surface_enabled = false;
 #endif  // VK_USE_PLATFORM_IOS_MVK
+#ifdef VK_USE_PLATFORM_FUCHSIA
+    ptr_instance->wsi_imagepipe_surface_enabled = false;
+#endif  // VK_USE_PLATFORM_FUCHSIA
     ptr_instance->wsi_display_enabled = false;
     ptr_instance->wsi_display_props2_enabled = false;
 #ifdef VK_USE_PLATFORM_METAL_EXT
@@ -123,6 +126,12 @@
             continue;
         }
 #endif  // VK_USE_PLATFORM_IOS_MVK
+#ifdef VK_USE_PLATFORM_FUCHSIA
+        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_FUCHSIA_IMAGEPIPE_SURFACE_EXTENSION_NAME) == 0) {
+            ptr_instance->wsi_imagepipe_surface_enabled = true;
+            continue;
+        }
+#endif  // VK_USE_PLATFORM_FUCHSIA
         if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME) == 0) {
             ptr_instance->wsi_headless_surface_enabled = true;
             continue;
@@ -1936,6 +1945,86 @@
                                                              pDisplayPlaneInfo->planeIndex, &pCapabilities->capabilities);
 }
 
+#ifdef VK_USE_PLATFORM_FUCHSIA
+
+// This is the trampoline entrypoint for CreateImagePipeSurfaceFUCHSIA
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateImagePipeSurfaceFUCHSIA(VkInstance instance,
+                                                                             const VkImagePipeSurfaceCreateInfoFUCHSIA *pCreateInfo,
+                                                                             const VkAllocationCallbacks *pAllocator,
+                                                                             VkSurfaceKHR *pSurface) {
+    const VkLayerInstanceDispatchTable *disp;
+    disp = loader_get_instance_layer_dispatch(instance);
+    VkResult res;
+
+    res = disp->CreateImagePipeSurfaceFUCHSIA(instance, pCreateInfo, pAllocator, pSurface);
+    return res;
+}
+
+// This is the instance chain terminator function for CreateImagePipeSurfaceFUCHSIA
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateImagePipeSurfaceFUCHSIA(VkInstance instance,
+                                                                        const VkImagePipeSurfaceCreateInfoFUCHSIA *pCreateInfo,
+                                                                        const VkAllocationCallbacks *pAllocator,
+                                                                        VkSurfaceKHR *pSurface) {
+    VkResult vkRes = VK_SUCCESS;
+    VkIcdSurface *pIcdSurface = NULL;
+    uint32_t i = 0;
+
+    // Initialize pSurface to NULL just to be safe.
+    *pSurface = VK_NULL_HANDLE;
+    // First, check to ensure the appropriate extension was enabled:
+    struct loader_instance *ptr_instance = loader_get_instance(instance);
+    if (!ptr_instance->wsi_imagepipe_surface_enabled) {
+        loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+                   "VK_FUCHSIA_imagepipe_surface extension not enabled.  "
+                   "vkCreateImagePipeSurfaceFUCHSIA not executed!\n");
+        vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
+        goto out;
+    }
+
+    // Next, if so, proceed with the implementation of this function:
+    pIcdSurface =
+        AllocateIcdSurfaceStruct(ptr_instance, sizeof(pIcdSurface->imagepipe_surf.base), sizeof(pIcdSurface->imagepipe_surf));
+    if (pIcdSurface == NULL) {
+        vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
+        goto out;
+    }
+
+    pIcdSurface->imagepipe_surf.base.platform = VK_ICD_WSI_PLATFORM_FUCHSIA;
+
+    // Loop through each ICD and determine if they need to create a surface
+    for (struct loader_icd_term *icd_term = ptr_instance->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
+        if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
+            if (NULL != icd_term->dispatch.CreateImagePipeSurfaceFUCHSIA) {
+                vkRes = icd_term->dispatch.CreateImagePipeSurfaceFUCHSIA(icd_term->instance, pCreateInfo, pAllocator,
+                                                                         &pIcdSurface->real_icd_surfaces[i]);
+                if (VK_SUCCESS != vkRes) {
+                    goto out;
+                }
+            }
+        }
+    }
+
+    *pSurface = (VkSurfaceKHR)(pIcdSurface);
+
+out:
+
+    if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
+        if (NULL != pIcdSurface->real_icd_surfaces) {
+            i = 0;
+            for (struct loader_icd_term *icd_term = ptr_instance->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
+                if ((VkSurfaceKHR)NULL != pIcdSurface->real_icd_surfaces[i] && NULL != icd_term->dispatch.DestroySurfaceKHR) {
+                    icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
+                }
+            }
+            loader_instance_heap_free(ptr_instance, pIcdSurface->real_icd_surfaces);
+        }
+        loader_instance_heap_free(ptr_instance, pIcdSurface);
+    }
+
+    return vkRes;
+}
+#endif  // VK_USE_PLATFORM_FUCHSIA
+
 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
 vkGetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
                                            VkSurfaceCapabilities2KHR *pSurfaceCapabilities) {
@@ -2261,6 +2350,15 @@
         return true;
     }
 #endif  // VK_USE_PLATFORM_IOS_MVK
+#ifdef VK_USE_PLATFORM_FUCHSIA
+
+    // Functions for the VK_FUCHSIA_imagepipe_surface extension:
+    if (!strcmp("vkCreateImagePipeSurfaceFUCHSIA", name)) {
+        *addr = ptr_instance->wsi_imagepipe_surface_enabled ? (void *)vkCreateImagePipeSurfaceFUCHSIA : NULL;
+        return true;
+    }
+
+#endif  // VK_USE_PLATFORM_FUCHSIA
 
     // Functions for the VK_EXT_headless_surface extension:
     if (!strcmp("vkCreateHeadlessSurfaceEXT", name)) {
diff --git a/loader/wsi.h b/loader/wsi.h
index e6c699f..a5a6835 100644
--- a/loader/wsi.h
+++ b/loader/wsi.h
@@ -45,6 +45,9 @@
 #ifdef VK_USE_PLATFORM_MACOS_MVK
         VkIcdSurfaceMacOS macos_surf;
 #endif  // VK_USE_PLATFORM_MACOS_MVK
+#ifdef VK_USE_PLATFORM_FUCHSIA
+        VkIcdSurfaceImagePipe imagepipe_surf;
+#endif  // VK_USE_PLATFORM_FUCHSIA
 #ifdef VK_USE_PLATFORM_METAL_EXT
         VkIcdSurfaceMetal metal_surf;
 #endif // VK_USE_PLATFORM_METAL_EXT
@@ -191,6 +194,10 @@
 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDisplayPlaneCapabilities2KHR(VkPhysicalDevice physicalDevice,
                                                                           const VkDisplayPlaneInfo2KHR *pDisplayPlaneInfo,
                                                                           VkDisplayPlaneCapabilities2KHR *pCapabilities);
+#ifdef VK_USE_PLATFORM_FUCHSIA
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateImagePipeSurfaceFUCHSIA(VkInstance instance, const VkImagePipeSurfaceCreateInfoFUCHSIA *pCreateInfo,
+                                                                const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface);
+#endif
 
 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceCapabilities2KHR(
     VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
diff --git a/scripts/loader_extension_generator.py b/scripts/loader_extension_generator.py
index 53e13bd..4985793 100644
--- a/scripts/loader_extension_generator.py
+++ b/scripts/loader_extension_generator.py
@@ -39,6 +39,7 @@
                  'VK_MVK_ios_surface',
                  'VK_EXT_headless_surface',
                  'VK_EXT_metal_surface',
+                 'VK_FUCHSIA_imagepipe_surface',
                  'VK_KHR_swapchain',
                  'VK_KHR_display_swapchain',
                  'VK_KHR_get_display_properties2',