loader: ghlvl#79, Fix to not report unsupported WSI surface extensions on Linux

Also fix issue where loader would advertise support for these extensions even if
the ICD or layers doesn't support it.  Now ICD must report surface extensions
for the loader to report them.  And on Linux if loader support for a given
surface extension (eg Mir) is compiled out then loader doesn't report it.

Change-Id: I51e302a32f5431f4893a3795ff31be60e9263f43
diff --git a/loader/loader.c b/loader/loader.c
index c2cb0c5..7f1002b 100644
--- a/loader/loader.c
+++ b/loader/loader.c
@@ -583,14 +583,17 @@
     for (i = 0; i < count; i++) {
         char spec_version[64];
 
-        snprintf(spec_version, sizeof(spec_version), "%d.%d.%d",
-                 VK_MAJOR(ext_props[i].specVersion),
-                 VK_MINOR(ext_props[i].specVersion),
-                 VK_PATCH(ext_props[i].specVersion));
-        loader_log(inst, VK_DEBUG_REPORT_DEBUG_BIT_EXT, 0,
-                   "Instance Extension: %s (%s) version %s",
-                   ext_props[i].extensionName, lib_name, spec_version);
-        loader_add_to_ext_list(inst, ext_list, 1, &ext_props[i]);
+        bool ext_unsupported = wsi_unsupported_instance_extension(&ext_props[i]);
+        if (!ext_unsupported) {
+            snprintf(spec_version, sizeof(spec_version), "%d.%d.%d",
+                     VK_MAJOR(ext_props[i].specVersion),
+                     VK_MINOR(ext_props[i].specVersion),
+                     VK_PATCH(ext_props[i].specVersion));
+            loader_log(inst, VK_DEBUG_REPORT_DEBUG_BIT_EXT, 0,
+                       "Instance Extension: %s (%s) version %s",
+                       ext_props[i].extensionName, lib_name, spec_version);
+            loader_add_to_ext_list(inst, ext_list, 1, &ext_props[i]);
+        }
     }
 
     return;
@@ -1099,7 +1102,6 @@
     };
 
     // Traverse loader's extensions, adding non-duplicate extensions to the list
-    wsi_add_instance_extensions(inst, inst_exts);
     debug_report_add_instance_extensions(inst, inst_exts);
 }
 
@@ -2076,8 +2078,11 @@
                         '\0';
                 }
                 ext_prop.specVersion = atoi(spec_version);
-                loader_add_to_ext_list(inst, &props->instance_extension_list, 1,
-                                       &ext_prop);
+                bool ext_unsupported = wsi_unsupported_instance_extension(&ext_prop);
+                if (!ext_unsupported) {
+                    loader_add_to_ext_list(inst, &props->instance_extension_list,
+                                           1, &ext_prop);
+                }
             }
         }
         /**
diff --git a/loader/wsi.c b/loader/wsi.c
index 43807e9..5b408ec 100644
--- a/loader/wsi.c
+++ b/loader/wsi.c
@@ -85,34 +85,6 @@
 };
 #endif // VK_USE_PLATFORM_ANDROID_KHR
 
-// Note for VK_DISPLAY_KHR don't advertise support since we really need support
-// to come from ICD, although the loader supplements the support from ICD
-
-void wsi_add_instance_extensions(const struct loader_instance *inst,
-                                 struct loader_extension_list *ext_list) {
-    loader_add_to_ext_list(inst, ext_list, 1, &wsi_surface_extension_info);
-#ifdef VK_USE_PLATFORM_WIN32_KHR
-    loader_add_to_ext_list(inst, ext_list, 1,
-                           &wsi_win32_surface_extension_info);
-#endif // VK_USE_PLATFORM_WIN32_KHR
-#ifdef VK_USE_PLATFORM_MIR_KHR
-    loader_add_to_ext_list(inst, ext_list, 1, &wsi_mir_surface_extension_info);
-#endif // VK_USE_PLATFORM_MIR_KHR
-#ifdef VK_USE_PLATFORM_WAYLAND_KHR
-    loader_add_to_ext_list(inst, ext_list, 1,
-                           &wsi_wayland_surface_extension_info);
-#endif // VK_USE_PLATFORM_WAYLAND_KHR
-#ifdef VK_USE_PLATFORM_XCB_KHR
-    loader_add_to_ext_list(inst, ext_list, 1, &wsi_xcb_surface_extension_info);
-#endif // VK_USE_PLATFORM_XCB_KHR
-#ifdef VK_USE_PLATFORM_XLIB_KHR
-    loader_add_to_ext_list(inst, ext_list, 1, &wsi_xlib_surface_extension_info);
-#endif // VK_USE_PLATFORM_XLIB_KHR
-#ifdef VK_USE_PLATFORM_ANDROID_KHR
-    loader_add_to_ext_list(inst, ext_list, 1,
-                           &wsi_android_surface_extension_info);
-#endif // VK_USE_PLATFORM_ANDROID_KHR
-}
 
 void wsi_create_instance(struct loader_instance *ptr_instance,
                          const VkInstanceCreateInfo *pCreateInfo) {
@@ -194,7 +166,36 @@
         }
     }
 }
+/*
+ * Linux WSI surface extensions are not always compiled into the loader. (Assume
+ * for Windows the KHR_win32_surface is always compiled into loader). A given
+ * Linux build environment might not have the headers required for building one
+ * of the four extensions  (Xlib, Xcb, Mir, Wayland).  Thus, need to check if
+ * the built loader actually supports the particular Linux surface extension.
+ * If not supported by the built loader it will not be included in the list of
+ * enumerated instance extensions.  This solves the issue where an ICD or layer
+ * advertises support for a given Linux surface extension but the loader was not
+ * built to support the extension. */
+bool wsi_unsupported_instance_extension(const VkExtensionProperties *ext_prop) {
+#ifndef VK_USE_PLATFORM_MIR_KHR
+    if (!strcmp(ext_prop->extensionName, "VK_KHR_mir_surface"))
+        return true;
+#endif // VK_USE_PLATFORM_MIR_KHR
+#ifndef VK_USE_PLATFORM_WAYLAND_KHR
+    if (!strcmp(ext_prop->extensionName, "VK_KHR_wayland_surface"))
+        return true;
+#endif // VK_USE_PLATFORM_WAYLAND_KHR
+#ifndef VK_USE_PLATFORM_XCB_KHR
+    if (!strcmp(ext_prop->extensionName, "VK_KHR_xcb_surface"))
+        return true;
+#endif // VK_USE_PLATFORM_XCB_KHR
+#ifndef VK_USE_PLATFORM_XLIB_KHR
+    if (!strcmp(ext_prop->extensionName, "VK_KHR_xlib_surface"))
+        return true;
+#endif // VK_USE_PLATFORM_XLIB_KHR
 
+    return false;
+}
 /*
  * Functions for the VK_KHR_surface extension:
  */
diff --git a/loader/wsi.h b/loader/wsi.h
index 88540f5..083ddfe 100644
--- a/loader/wsi.h
+++ b/loader/wsi.h
@@ -31,11 +31,10 @@
 
 bool wsi_swapchain_instance_gpa(struct loader_instance *ptr_instance,
                                 const char *name, void **addr);
-void wsi_add_instance_extensions(const struct loader_instance *inst,
-                                 struct loader_extension_list *ext_list);
 
 void wsi_create_instance(struct loader_instance *ptr_instance,
                          const VkInstanceCreateInfo *pCreateInfo);
+bool wsi_unsupported_instance_extension(const VkExtensionProperties *ext_prop);
 
 VKAPI_ATTR void VKAPI_CALL
 terminator_DestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface,