misc: Make wsi lunarg an extension rather than core entrypoints
diff --git a/include/vk_wsi_lunarg.h b/include/vk_wsi_lunarg.h
index 84de8d2..3507cfe 100644
--- a/include/vk_wsi_lunarg.h
+++ b/include/vk_wsi_lunarg.h
@@ -31,6 +31,7 @@
 
 #define VK_WSI_LUNARG_REVISION             3
 #define VK_WSI_LUNARG_EXTENSION_NUMBER     1
+#define VK_WSI_LUNARG_EXTENSION_NAME       "VK_WSI_LunarG"
 
 #ifdef __cplusplus
 extern "C"
diff --git a/loader/CMakeLists.txt b/loader/CMakeLists.txt
index 6365e8d..b334af3 100644
--- a/loader/CMakeLists.txt
+++ b/loader/CMakeLists.txt
@@ -10,16 +10,16 @@
 if (WIN32)
     set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DVK_PROTOTYPES -D_CRT_SECURE_NO_WARNINGS -DXCB_NVIDIA")
 
-    add_library(vulkan SHARED loader.c loader.h loader_platform.h dirent_on_windows.c trampoline.c table_ops.h gpa_helper.h vulkan.def)
+    add_library(vulkan SHARED loader.c loader.h loader_platform.h dirent_on_windows.c trampoline.c  wsi_lunarg.c wsi_lunarg.h table_ops.h gpa_helper.h vulkan.def)
     set_target_properties(vulkan PROPERTIES LINK_FLAGS "/DEF:${PROJECT_SOURCE_DIR}/loader/vulkan.def")
-    add_library(VKstatic STATIC loader.c loader.h dirent_on_windows.c trampoline.c table_ops.h gpa_helper.h)
+    add_library(VKstatic STATIC loader.c loader.h dirent_on_windows.c trampoline.c wsi_lunarg.c wsi_lunarg.h table_ops.h gpa_helper.h)
     set_target_properties(VKstatic PROPERTIES OUTPUT_NAME VKstatic)
     target_link_libraries(vulkan)
 endif()
 if (NOT WIN32)
     set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DVK_PROTOTYPES -Wpointer-arith")
 
-    add_library(vulkan SHARED loader.c trampoline.c loader.h loader_platform.h table_ops.h gpa_helper.h)
+    add_library(vulkan SHARED loader.c trampoline.c wsi_lunarg.c wsi_lunarg.h loader.h loader_platform.h table_ops.h gpa_helper.h)
     set_target_properties(vulkan PROPERTIES SOVERSION 0)
     target_link_libraries(vulkan -ldl -lpthread)
 endif()
diff --git a/loader/gpa_helper.h b/loader/gpa_helper.h
index 3e49195..6e831bd 100644
--- a/loader/gpa_helper.h
+++ b/loader/gpa_helper.h
@@ -276,16 +276,6 @@
         return (void*) vkCmdDbgMarkerBegin;
     if (!strcmp(name, "CmdDbgMarkerEnd"))
         return (void*) vkCmdDbgMarkerEnd;
-    if (!strcmp(name, "GetDisplayInfoWSI"))
-        return (void*) vkGetDisplayInfoWSI;
-    if (!strcmp(name, "CreateSwapChainWSI"))
-        return (void*) vkCreateSwapChainWSI;
-    if (!strcmp(name, "DestroySwapChainWSI"))
-        return (void*) vkDestroySwapChainWSI;
-    if (!strcmp(name, "GetSwapChainInfoWSI"))
-        return (void*) vkGetSwapChainInfoWSI;
-    if (!strcmp(name, "QueuePresentWSI"))
-        return (void*) vkQueuePresentWSI;
 
     return NULL;
 }
@@ -328,8 +318,6 @@
         return (void*) vkDbgUnregisterMsgCallback;
     if (!strcmp(name, "DbgSetGlobalOption"))
         return (void*) vkDbgSetGlobalOption;
-    if (!strcmp(name, "CreateSwapChainWSI"))
-        return (void*) vkCreateSwapChainWSI;
 
     return NULL;
 }
diff --git a/loader/loader.c b/loader/loader.c
index 0d114a4..1c53f17 100644
--- a/loader/loader.c
+++ b/loader/loader.c
@@ -42,6 +42,7 @@
 #endif // WIN32
 #include "loader_platform.h"
 #include "loader.h"
+#include "wsi_lunarg.h"
 #include "gpa_helper.h"
 #include "table_ops.h"
 #include "vkIcd.h"
@@ -741,6 +742,15 @@
             return NULL;
         return disp_table->GetDeviceProcAddr(physDev, pName);
     }
+#if 0
+    return icd->GetDeviceProcAddr(physDev, pName);
+    uint32_t gpu_index;
+    struct loader_icd *icd = loader_get_icd((const VkBaseLayerObject *) physDev, &gpu_index);
+    if (icd->GetDeviceProcAddr == NULL)
+    //if (disp_table->GetDeviceProcAddr == NULL)
+            return NULL;
+    return icd->GetDeviceProcAddr(physDev, pName);
+#endif
 }
 
 static void* VKAPI loader_gpa_instance_internal(VkInstance inst, const char * pName)
@@ -1397,11 +1407,27 @@
 
 LOADER_EXPORT void * VKAPI vkGetInstanceProcAddr(VkInstance instance, const char * pName)
 {
-    if (instance != VK_NULL_HANDLE) {
+    if (instance == VK_NULL_HANDLE)
+        return NULL;
+    void *addr;
+    /* get entrypoint addresses that are global (in the loader)*/
+    addr = globalGetProcAddr(pName);
+    if (addr)
+        return addr;
 
-        /* return entrypoint addresses that are global (in the loader)*/
-        return globalGetProcAddr(pName);
-    }
+    /* return any extension global entrypoints */
+    addr = wsi_lunarg_GetInstanceProcAddr(instance, pName);
+    if (addr)
+        return addr;
+
+    /* return the instance dispatch table entrypoint for extensions */
+    const VkLayerInstanceDispatchTable *disp_table = * (VkLayerInstanceDispatchTable **) instance;
+    if (disp_table == NULL)
+        return NULL;
+
+    addr = loader_lookup_instance_dispatch_table(disp_table, pName);
+    if (addr)
+        return addr;
 
     return NULL;
 }
@@ -1421,6 +1447,11 @@
         return addr;
     }
 
+    /* return any extension device entrypoints the loader knows about */
+    addr = wsi_lunarg_GetDeviceProcAddr(device, pName);
+    if (addr)
+        return addr;
+
     /* return the dispatch table entrypoint for the fastest case */
     const VkLayerDispatchTable *disp_table = * (VkLayerDispatchTable **) device;
     if (disp_table == NULL)
@@ -1709,18 +1740,3 @@
     return res;
 }
 
-VkResult loader_GetDisplayInfoWSI(
-        VkDisplayWSI                            display,
-        VkDisplayInfoTypeWSI                    infoType,
-        size_t*                                 pDataSize,
-        void*                                   pData)
-{
-    uint32_t gpu_index;
-    struct loader_icd *icd = loader_get_icd((const VkBaseLayerObject *) display, &gpu_index);
-    VkResult res = VK_ERROR_INITIALIZATION_FAILED;
-
-    if (icd->GetDisplayInfoWSI)
-        res = icd->GetDisplayInfoWSI(display, infoType, pDataSize, pData);
-
-    return res;
-}
diff --git a/loader/loader.h b/loader/loader.h
index 972b4f1..e7a4618 100644
--- a/loader/loader.h
+++ b/loader/loader.h
@@ -205,11 +205,7 @@
         size_t                                  dataSize,
         const void*                             pData);
 
-VkResult loader_GetDisplayInfoWSI(
-        VkDisplayWSI                            display,
-        VkDisplayInfoTypeWSI                    infoType,
-        size_t*                                 pDataSize,
-        void*                                   pData);
+
 
 /* function definitions */
 bool loader_is_extension_scanned(const char *name);
diff --git a/loader/table_ops.h b/loader/table_ops.h
index 9a5a0c0..adcc42a 100644
--- a/loader/table_ops.h
+++ b/loader/table_ops.h
@@ -142,6 +142,7 @@
     table->DbgSetDeviceOption = (PFN_vkDbgSetDeviceOption) gpa(dev, "vkDbgSetDeviceOption");
     table->CmdDbgMarkerBegin = (PFN_vkCmdDbgMarkerBegin) gpa(dev, "vkCmdDbgMarkerBegin");
     table->CmdDbgMarkerEnd = (PFN_vkCmdDbgMarkerEnd) gpa(dev, "vkCmdDbgMarkerEnd");
+//TODO move into it's own table
     table->CreateSwapChainWSI = (PFN_vkCreateSwapChainWSI) gpa(dev, "vkCreateSwapChainWSI");
     table->DestroySwapChainWSI = (PFN_vkDestroySwapChainWSI) gpa(dev, "vkDestroySwapChainWSI");
     table->GetSwapChainInfoWSI = (PFN_vkGetSwapChainInfoWSI) gpa(dev, "vkGetSwapChainInfoWSI");
@@ -376,6 +377,7 @@
         return (void *) table->CmdDbgMarkerBegin;
     if (!strcmp(name, "CmdDbgMarkerEnd"))
         return (void *) table->CmdDbgMarkerEnd;
+//TODO put in it's own table
     if (!strcmp(name, "CreateSwapChainWSI"))
         return (void *) table->CreateSwapChainWSI;
     if (!strcmp(name, "DestroySwapChainWSI"))
@@ -405,6 +407,7 @@
     table->DbgRegisterMsgCallback = (PFN_vkDbgRegisterMsgCallback) gpa(inst, "vkDbgRegisterMsgCallback");
     table->DbgUnregisterMsgCallback = (PFN_vkDbgUnregisterMsgCallback) gpa(inst, "vkDbgUnregisterMsgCallback");
     table->DbgSetGlobalOption = (PFN_vkDbgSetGlobalOption) gpa(inst, "vkDbgSetGlobalOption");
+//TODO put in it's own table
     table->GetDisplayInfoWSI = (PFN_vkGetDisplayInfoWSI) gpa(inst, "vkGetDisplayInfoWSI");
 }
 
@@ -442,8 +445,8 @@
         return (void *) table->DbgUnregisterMsgCallback;
     if (!strcmp(name, "DbgSetGlobalOption"))
         return (void *) table->DbgSetGlobalOption;
+    //TODO eventually extensions are in their own table
     if (!strcmp(name, "GetDisplayInfoWSI"))
         return (void *) table->GetDisplayInfoWSI;
-
     return NULL;
 }
diff --git a/loader/trampoline.c b/loader/trampoline.c
index 20fbe35..c5186e3 100644
--- a/loader/trampoline.c
+++ b/loader/trampoline.c
@@ -26,6 +26,7 @@
 
 #include "loader_platform.h"
 #include "loader.h"
+#include "wsi_lunarg.h"
 
 #if defined(WIN32)
 // On Windows need to disable global optimization for function entrypoints or
@@ -76,6 +77,10 @@
     memcpy(ptr_instance->disp, &instance_disp, sizeof(instance_disp));
     ptr_instance->next = loader.instances;
     loader.instances = ptr_instance;
+
+    wsi_lunarg_register_extensions(pCreateInfo);
+
+    /* enable any layers on instance chain */
     loader_activate_instance_layers(ptr_instance);
 
     *pInstance = (VkInstance) ptr_instance;
@@ -1217,48 +1222,6 @@
     disp->CmdDbgMarkerEnd(cmdBuffer);
 }
 
-LOADER_EXPORT VkResult VKAPI vkGetDisplayInfoWSI(VkDisplayWSI display, VkDisplayInfoTypeWSI infoType, size_t* pDataSize, void* pData)
-{
-    const VkLayerInstanceDispatchTable *disp;
-
-    disp = loader_get_instance_dispatch(display);
-
-    return disp->GetDisplayInfoWSI(display, infoType, pDataSize, pData);
-}
-
-LOADER_EXPORT VkResult VKAPI vkCreateSwapChainWSI(VkDevice device, const VkSwapChainCreateInfoWSI* pCreateInfo, VkSwapChainWSI* pSwapChain)
-{
-    const VkLayerDispatchTable *disp;
-    VkResult res;
-
-    disp = loader_get_dispatch(device);
-
-    res = disp->CreateSwapChainWSI(device, pCreateInfo, pSwapChain);
-    if (res == VK_SUCCESS) {
-        loader_init_dispatch(*pSwapChain, disp);
-    }
-
-    return res;
-}
-
-LOADER_EXPORT VkResult VKAPI vkDestroySwapChainWSI(VkSwapChainWSI swapChain)
-{
-    const VkLayerDispatchTable *disp;
-
-    disp = loader_get_dispatch(swapChain);
-
-    return disp->DestroySwapChainWSI(swapChain);
-}
-
-LOADER_EXPORT VkResult VKAPI vkGetSwapChainInfoWSI(VkSwapChainWSI swapChain, VkSwapChainInfoTypeWSI infoType, size_t* pDataSize, void* pData)
-{
-    const VkLayerDispatchTable *disp;
-
-    disp = loader_get_dispatch(swapChain);
-
-    return disp->GetSwapChainInfoWSI(swapChain, infoType, pDataSize, pData);
-}
-
 LOADER_EXPORT VkResult VKAPI vkQueuePresentWSI(VkQueue queue, const VkPresentInfoWSI* pPresentInfo)
 {
     const VkLayerDispatchTable *disp;
diff --git a/loader/wsi_lunarg.c b/loader/wsi_lunarg.c
new file mode 100644
index 0000000..5d8a51b
--- /dev/null
+++ b/loader/wsi_lunarg.c
@@ -0,0 +1,190 @@
+/*
+ * Vulkan
+ *
+ * Copyright (C) 2015 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *   Jon Ashburn <jon@lunarg.com>
+ *   Courtney Goeltzenleuchter <courtney@lunarg.com>
+ */
+
+#include <string.h>
+#include "loader_platform.h"
+#include "loader.h"
+#include "wsi_lunarg.h"
+
+/************  Trampoline entrypoints *******************/
+/* since one entrypoint is instance level will make available all entrypoints */
+VkResult VKAPI wsi_lunarg_GetDisplayInfoWSI(
+        VkDisplayWSI                            display,
+        VkDisplayInfoTypeWSI                    infoType,
+        size_t*                                 pDataSize,
+        void*                                   pData)
+{
+    const VkLayerInstanceDispatchTable *disp;
+
+    disp = loader_get_instance_dispatch(display);
+
+    return disp->GetDisplayInfoWSI(display, infoType, pDataSize, pData);
+}
+
+VkResult wsi_lunarg_CreateSwapChainWSI(
+        VkDevice                                device,
+        const VkSwapChainCreateInfoWSI*         pCreateInfo,
+        VkSwapChainWSI*                         pSwapChain)
+{
+    const VkLayerDispatchTable *disp;
+    VkResult res;
+
+    disp = loader_get_dispatch(device);
+
+    res = disp->CreateSwapChainWSI(device, pCreateInfo, pSwapChain);
+    if (res == VK_SUCCESS) {
+        loader_init_dispatch(*pSwapChain, disp);
+    }
+
+    return res;
+}
+
+VkResult wsi_lunarg_DestroySwapChainWSI(
+        VkSwapChainWSI                          swapChain)
+{
+    const VkLayerDispatchTable *disp;
+
+    disp = loader_get_dispatch(swapChain);
+
+    return disp->DestroySwapChainWSI(swapChain);
+}
+
+static VkResult wsi_lunarg_GetSwapChainInfoWSI(
+        VkSwapChainWSI                          swapChain,
+        VkSwapChainInfoTypeWSI                  infoType,
+        size_t*                                 pDataSize,
+        void*                                   pData)
+{
+    const VkLayerDispatchTable *disp;
+
+    disp = loader_get_dispatch(swapChain);
+
+    return disp->GetSwapChainInfoWSI(swapChain, infoType, pDataSize, pData);
+}
+
+static VkResult wsi_lunarg_QueuePresentWSI(
+        VkQueue                                 queue,
+        const VkPresentInfoWSI*                 pPresentInfo)
+{
+    const VkLayerDispatchTable *disp;
+
+    disp = loader_get_dispatch(queue);
+
+    return disp->QueuePresentWSI(queue, pPresentInfo);
+}
+
+/************  loader instance chain termination entrypoints ***************/
+VkResult loader_GetDisplayInfoWSI(
+        VkDisplayWSI                            display,
+        VkDisplayInfoTypeWSI                    infoType,
+        size_t*                                 pDataSize,
+        void*                                   pData)
+{
+    uint32_t gpu_index;
+    struct loader_icd *icd = loader_get_icd((const VkBaseLayerObject *) display, &gpu_index);
+    VkResult res = VK_ERROR_INITIALIZATION_FAILED;
+
+    if (icd->GetDisplayInfoWSI)
+        res = icd->GetDisplayInfoWSI(display, infoType, pDataSize, pData);
+
+    return res;
+}
+
+
+/************ extension enablement ***************/
+static bool wsi_enabled = false;
+
+struct ext_props {
+    uint32_t version;
+    const char * const name;
+};
+
+#define WSI_LUNARG_EXT_ARRAY_SIZE 1
+static const struct ext_props wsi_lunarg_exts[WSI_LUNARG_EXT_ARRAY_SIZE] = {
+    {VK_WSI_LUNARG_REVISION, VK_WSI_LUNARG_EXTENSION_NAME},
+};
+
+void wsi_lunarg_register_extensions(
+        const VkInstanceCreateInfo*             pCreateInfo)
+{
+    uint32_t i, ext_idx;
+
+    for (i = 0; i < pCreateInfo->extensionCount; i++) {
+        for (ext_idx = 0; ext_idx < WSI_LUNARG_EXT_ARRAY_SIZE; ext_idx++) {
+            /* TODO: Should we include version number as well as extension name? */
+            if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], wsi_lunarg_exts[ext_idx].name) == 0) {
+                /* Found a matching extension name, mark it enabled */
+                wsi_enabled = true;
+            }
+
+        }
+    }
+
+}
+
+void *wsi_lunarg_GetInstanceProcAddr(
+        VkInstance                              instance,
+        const char*                             pName)
+{
+    if (instance == VK_NULL_HANDLE)
+        return NULL;
+
+    if (wsi_enabled == false)
+	return NULL;
+
+    /* since two of these entrypoints must be loader handled will report all */
+    if (!strcmp(pName, "vkGetDisplayInfoWSI"))
+        return (void*) wsi_lunarg_GetDisplayInfoWSI;
+    if (!strcmp(pName, "vkCreateSwapChainWSI"))
+        return (void*) wsi_lunarg_CreateSwapChainWSI;
+    if (!strcmp(pName, "vkDestroySwapChainWSI"))
+        return (void*) wsi_lunarg_DestroySwapChainWSI;
+    if (!strcmp(pName, "vkGetSwapChainInfoWSI"))
+        return (void*) wsi_lunarg_GetSwapChainInfoWSI;
+    if (!strcmp(pName, "vkQueuePresentWSI"))
+        return (void*) wsi_lunarg_QueuePresentWSI;
+
+    return NULL;
+}
+
+void *wsi_lunarg_GetDeviceProcAddr(
+        VkDevice                                device,
+        const char*                             name)
+{
+    if (device == VK_NULL_HANDLE)
+        return NULL;
+
+    if (wsi_enabled == false)
+	    return NULL;
+
+    /* only handle device entrypoints that are loader special cases */
+    if (!strcmp(name, "vkCreateSwapChainWSI"))
+        return (void*) wsi_lunarg_CreateSwapChainWSI;
+
+    return NULL;
+}
diff --git a/loader/wsi_lunarg.h b/loader/wsi_lunarg.h
new file mode 100644
index 0000000..fd1b6da
--- /dev/null
+++ b/loader/wsi_lunarg.h
@@ -0,0 +1,46 @@
+/*
+ * Vulkan
+ *
+ * Copyright (C) 2015 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *   Jon Ashburn <jon@lunarg.com>
+ *   Courtney Goeltzenleuchter <courtney@lunarg.com>
+ */
+
+#include "vk_wsi_lunarg.h"
+
+VkResult loader_GetDisplayInfoWSI(
+        VkDisplayWSI                            display,
+        VkDisplayInfoTypeWSI                    infoType,
+        size_t*                                 pDataSize,
+        void*                                   pData);
+
+void wsi_lunarg_register_extensions(
+        const VkInstanceCreateInfo*             pCreateInfo);
+
+void *wsi_lunarg_GetInstanceProcAddr(
+        VkInstance                              instance,
+        const char*                             pName);
+
+void *wsi_lunarg_GetDeviceProcAddr(
+        VkDevice                                device,
+        const char*                             pName);
diff --git a/tests/test_environment.h b/tests/test_environment.h
index fba8885..9f6891e 100644
--- a/tests/test_environment.h
+++ b/tests/test_environment.h
@@ -15,6 +15,7 @@
 
     const std::vector<Device *> &devices() { return devs_; }
     Device &default_device() { return *(devs_[default_dev_]); }
+    VkInstance get_instance() { return inst; }
     VkPhysicalDevice gpus[16];
 
 private:
diff --git a/tests/vktestframework.cpp b/tests/vktestframework.cpp
index 58cae8f..ecb192f 100644
--- a/tests/vktestframework.cpp
+++ b/tests/vktestframework.cpp
@@ -58,7 +58,7 @@
     TestFrameworkVkPresent(vk_testing::Device &device);
 
     void Run();
-    void InitPresentFramework(std::list<VkTestImageRecord> &imagesIn);
+    void InitPresentFramework(std::list<VkTestImageRecord> &imagesIn, VkInstance inst);
     void CreateMyWindow();
     void CreateSwapChain();
     void TearDown();
@@ -85,6 +85,11 @@
 #endif
     std::list<VkTestImageRecord>            m_images;
 
+    PFN_vkCreateSwapChainWSI                m_fpCreateSwapChainWSI;
+    PFN_vkDestroySwapChainWSI               m_fpDestroySwapChainWSI;
+    PFN_vkGetSwapChainInfoWSI               m_fpGetSwapChainInfoWSI;
+    PFN_vkQueuePresentWSI                   m_fpQueuePresentWSI;
+
     VkSwapChainWSI                          m_swap_chain;
     std::vector<VkSwapChainImageInfoWSI>    m_persistent_images;
     int                                     m_current_buffer;
@@ -510,7 +515,8 @@
                          m_display_image->m_title.size(),
                          m_display_image->m_title.c_str());
 #endif
-    err = vkQueuePresentWSI(m_queue.obj(), &present);
+
+    err = m_fpQueuePresentWSI(m_queue.obj(), &present);
     assert(!err);
 
     m_queue.wait();
@@ -687,13 +693,14 @@
     swap_chain.swapModeFlags = VK_SWAP_MODE_FLIP_BIT_WSI |
                                VK_SWAP_MODE_BLIT_BIT_WSI;
 
-    err = vkCreateSwapChainWSI(m_device.obj(), &swap_chain, &m_swap_chain);
+    err = m_fpCreateSwapChainWSI(m_device.obj(), &swap_chain, &m_swap_chain);
     assert(!err);
 
-    size_t size = sizeof(VkSwapChainImageInfoWSI) * 2;
     VkSwapChainImageInfoWSI infos[2];
-    
-    err = vkGetSwapChainInfoWSI(m_swap_chain,
+    size_t size = sizeof(VkSwapChainImageInfoWSI) * m_images.size();
+    std::vector<VkSwapChainImageInfoWSI> persistent_images;
+    persistent_images.resize(m_images.size());
+    err = m_fpGetSwapChainInfoWSI(m_swap_chain,
             VK_SWAP_CHAIN_INFO_TYPE_PERSISTENT_IMAGES_WSI,
             &size, &infos);
     assert(!err && size == sizeof(VkSwapChainImageInfoWSI) * 2);
@@ -701,8 +708,20 @@
     m_persistent_images.push_back(infos[1]);
 }
 
-void  TestFrameworkVkPresent::InitPresentFramework(std::list<VkTestImageRecord>  &imagesIn)
+void  TestFrameworkVkPresent::InitPresentFramework(std::list<VkTestImageRecord>  &imagesIn, VkInstance inst)
 {
+    m_fpCreateSwapChainWSI = (PFN_vkCreateSwapChainWSI) vkGetInstanceProcAddr(inst, "vkCreateSwapChainWSI");
+    ASSERT_TRUE(m_fpCreateSwapChainWSI != NULL) << "vkGetInstanceProcAddr failed to find vkCreateSwapChainWSI";
+
+    m_fpDestroySwapChainWSI = (PFN_vkDestroySwapChainWSI) vkGetInstanceProcAddr(inst, "vkDestroySwapChainWSI");
+    ASSERT_TRUE(m_fpDestroySwapChainWSI != NULL) << "vkGetInstanceProcAddr failed to find vkDestroySwapChainWSI";
+
+    m_fpGetSwapChainInfoWSI = (PFN_vkGetSwapChainInfoWSI) vkGetInstanceProcAddr(inst, "vkGetSwapChainInfoWSI");
+    ASSERT_TRUE(m_fpGetSwapChainInfoWSI != NULL) << "vkGetInstanceProcAddr failed to find vkGetSwapChainInfoWSI";
+
+    m_fpQueuePresentWSI = (PFN_vkQueuePresentWSI) vkGetInstanceProcAddr(inst, "vkQueuePresentWSI");
+    ASSERT_TRUE(m_fpQueuePresentWSI != NULL) << "vkGetInstanceProcAddr failed to find vkQueuePresentWSI";
+
     m_images = imagesIn;
 }
 
@@ -827,7 +846,7 @@
 
 void TestFrameworkVkPresent::TearDown()
 {
-    vkDestroySwapChainWSI(m_swap_chain);
+    m_fpDestroySwapChainWSI(m_swap_chain);
 #ifndef _WIN32
     xcb_destroy_window(m_connection, m_window);
     xcb_disconnect(m_connection);
@@ -843,7 +862,7 @@
     {
         TestFrameworkVkPresent vkPresent(env.default_device());
 
-        vkPresent.InitPresentFramework(m_images);
+        vkPresent.InitPresentFramework(m_images, env.get_instance());
         vkPresent.CreateMyWindow();
         vkPresent.CreateSwapChain();
         vkPresent.Run();