loader: Wrote vk{Create|Destroy}*SurfaceKHR() trampoline functions.
authorIan Elliott <ianelliott@google.com>
Thu, 19 Nov 2015 20:14:05 +0000 (13:14 -0700)
committerJon Ashburn <jon@lunarg.com>
Tue, 1 Dec 2015 17:18:23 +0000 (10:18 -0700)
This is an area where the loader-ICD interface is different.  Instead of the
trampoline function calling down a call-chain, For Windows and Linux, this
function actually fully implements the function.  A VkSurfaceKHR is actually a
pointer to a platform-specific struct (declared in "vk_icd.h").  The memory for
the struct is allocated, and the struct is initialized.  All ICDs and layers on
Windows and Linux are supposed to treat VkSurfaceKHR's (e.g. in other calls) as
such a pointer to a struct.

Also, per a Skype conversation with Jon Ashburn, there will be
per-WSI-extension sections of the file, with pairs of trampoline-terminator
functions right next to each other.

loader/wsi.c

index ba9a58a..e65b401 100644 (file)
@@ -48,6 +48,7 @@
 #include "vk_loader_platform.h"
 #include "loader.h"
 #include "wsi.h"
+#include <vulkan/vk_icd.h>
 
 static const VkExtensionProperties wsi_surface_extension_info = {
         .extensionName = VK_KHR_SURFACE_EXTENSION_NAME,
@@ -173,6 +174,28 @@ void wsi_create_instance(
 }
 
 /*
+ * Functions for the VK_KHR_surface extension:
+ */
+
+/*
+ * This is the trampoline entrypoint
+ * for DestroySurfaceKHR
+ *
+ * Note: There is no terminator for this function.
+ */
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroySurfaceKHR(
+    VkInstance                                   instance,
+    VkSurfaceKHR                                 surface,
+    const VkAllocationCallbacks*                 pAllocator)
+{
+    if (pAllocator) {
+        pAllocator->pfnFree(pAllocator->pUserData, surface);
+    } else {
+        free(surface);
+    }
+}
+
+/*
  * This is the trampoline entrypoint
  * for GetPhysicalDeviceSurfaceSupportKHR
  */
@@ -216,14 +239,280 @@ VKAPI_ATTR VkResult VKAPI_CALL loader_GetPhysicalDeviceSurfaceSupportKHR(
                                                    pSupported);
 }
 
+
+
+
+/*
+ * Functions for the VK_KHR_swapchain extension:
+ */
+
+
+
+
+
+#ifdef _WIN32
+
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+
+/*
+ * Functions for the VK_KHR_win32_surface extension:
+ */
+
+/*
+ * This is the trampoline entrypoint
+ * for CreateWin32SurfaceKHR
+ */
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateWin32SurfaceKHR(
+    VkInstance                                  instance,
+    HINSTANCE                                   hinstance,
+    HWND                                        hwnd,
+    const VkAllocationCallbacks*                pAllocator,
+    VkSurfaceKHR*                               pSurface)
+{
+    VkIcdSurfaceWin32 *pIcdSurface = NULL;
+
+    if (pAllocator) {
+        pIcdSurface = (VkIcdSurfaceWin32 *) pAllocator->pfnAllocation(
+                           pAllocator->pUserData,
+                           sizeof(VkIcdSurfaceWin32),
+                           sizeof(VkSurfaceKHR),
+                           VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+    } else {
+        pIcdSurface = (VkIcdSurfaceWin32 *) malloc(sizeof(VkIcdSurfaceWin32));
+    }
+    if (pIcdSurface == NULL) {
+        return VK_ERROR_OUT_OF_HOST_MEMORY;
+    }
+
+    pIcdSurface->base.platform = VK_ICD_WSI_PLATFORM_WIN32;
+    pIcdSurface->hinstance = hinstance;
+    pIcdSurface->hwnd = hwnd;
+
+    *pSurface = (VkSurfaceKHR) pIcdSurface;
+
+    return VK_SUCCESS;
+}
+#endif/ VK_USE_PLATFORM_WIN32_KHR
+
+#else // _WIN32 (i.e. Linux)
+
+#ifdef VK_USE_PLATFORM_MIR_KHR
+
+/*
+ * Functions for the VK_KHR_mir_surface extension:
+ */
+
+/*
+ * This is the trampoline entrypoint
+ * for CreateMirSurfaceKHR
+ */
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateMirSurfaceKHR(
+    VkInstance                                  instance,
+    MirConnection*                              connection,
+    MirSurface*                                 mirSurface,
+    const VkAllocationCallbacks*                pAllocator,
+    VkSurfaceKHR*                               pSurface)
+{
+    VkIcdSurfaceMir *pIcdSurface = NULL;
+
+    if (pAllocator) {
+        pIcdSurface = (VkIcdSurfaceMir *) pAllocator->pfnAllocation(
+                           pAllocator->pUserData,
+                           sizeof(VkIcdSurfaceMir),
+                           sizeof(VkSurfaceKHR),
+                           VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+    } else {
+        pIcdSurface = (VkIcdSurfaceMir *) malloc(sizeof(VkIcdSurfaceMir));
+    }
+    if (pIcdSurface == NULL) {
+        return VK_ERROR_OUT_OF_HOST_MEMORY;
+    }
+
+    pIcdSurface->base.platform = VK_ICD_WSI_PLATFORM_MIR;
+    pIcdSurface->connection = connection;
+    pIcdSurface->mirSurface = mirSurface;
+
+    *pSurface = (VkSurfaceKHR) pIcdSurface;
+
+    return VK_SUCCESS;
+}
+#endif // VK_USE_PLATFORM_MIR_KHR
+
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+
+/*
+ * Functions for the VK_KHR_wayland_surface extension:
+ */
+
+/*
+ * This is the trampoline entrypoint
+ * for CreateWaylandSurfaceKHR
+ */
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateWaylandSurfaceKHR(
+    VkInstance                                  instance,
+    struct wl_display*                          display,
+    struct wl_surface*                          surface,
+    const VkAllocationCallbacks*                pAllocator,
+    VkSurfaceKHR*                               pSurface)
+{
+    VkIcdSurfaceWayland *pIcdSurface = NULL;
+
+    if (pAllocator) {
+        pIcdSurface = (VkIcdSurfaceWayland *) pAllocator->pfnAllocation(
+                           pAllocator->pUserData,
+                           sizeof(VkIcdSurfaceWayland),
+                           sizeof(VkSurfaceKHR),
+                           VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+    } else {
+        pIcdSurface = (VkIcdSurfaceWayland *) malloc(sizeof(VkIcdSurfaceWayland));
+    }
+    if (pIcdSurface == NULL) {
+        return VK_ERROR_OUT_OF_HOST_MEMORY;
+    }
+
+    pIcdSurface->base.platform = VK_ICD_WSI_PLATFORM_WAYLAND;
+    pIcdSurface->display = display;
+    pIcdSurface->surface = surface;
+
+    *pSurface = (VkSurfaceKHR) pIcdSurface;
+
+    return VK_SUCCESS;
+}
+#endif // VK_USE_PLATFORM_WAYLAND_KHR
+
+#ifdef VK_USE_PLATFORM_XCB_KHR
+
+/*
+ * Functions for the VK_KHR_xcb_surface extension:
+ */
+
+/*
+ * This is the trampoline entrypoint
+ * for CreateXcbSurfaceKHR
+ */
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateXcbSurfaceKHR(
+    VkInstance                                  instance,
+    xcb_connection_t*                           connection,
+    xcb_window_t                                window,
+    const VkAllocationCallbacks*                pAllocator,
+    VkSurfaceKHR*                               pSurface)
+{
+    VkIcdSurfaceXcb *pIcdSurface = NULL;
+
+    if (pAllocator) {
+        pIcdSurface = (VkIcdSurfaceXcb *) pAllocator->pfnAllocation(
+                           pAllocator->pUserData,
+                           sizeof(VkIcdSurfaceXcb),
+                           sizeof(VkSurfaceKHR),
+                           VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+    } else {
+        pIcdSurface = (VkIcdSurfaceXcb *) malloc(sizeof(VkIcdSurfaceXcb));
+    }
+    if (pIcdSurface == NULL) {
+        return VK_ERROR_OUT_OF_HOST_MEMORY;
+    }
+
+    pIcdSurface->base.platform = VK_ICD_WSI_PLATFORM_XCB;
+    pIcdSurface->connection = connection;
+    pIcdSurface->window = window;
+
+    *pSurface = (VkSurfaceKHR) pIcdSurface;
+
+    return VK_SUCCESS;
+}
+#endif // VK_USE_PLATFORM_XCB_KHR
+
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+
+/*
+ * Functions for the VK_KHR_xlib_surface extension:
+ */
+
+/*
+ * This is the trampoline entrypoint
+ * for CreateXlibSurfaceKHR
+ */
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateXlibSurfaceKHR(
+    VkInstance                                  instance,
+    Display*                                    dpy,
+    Window                                      window,
+    const VkAllocationCallbacks*                pAllocator,
+    VkSurfaceKHR*                               pSurface)
+{
+    VkIcdSurfaceXlib *pIcdSurface = NULL;
+
+    if (pAllocator) {
+        pIcdSurface = (VkIcdSurfaceXlib *) pAllocator->pfnAllocation(
+                           pAllocator->pUserData,
+                           sizeof(VkIcdSurfaceXlib),
+                           sizeof(VkSurfaceKHR),
+                           VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+    } else {
+        pIcdSurface = (VkIcdSurfaceXlib *) malloc(sizeof(VkIcdSurfaceXlib));
+    }
+    if (pIcdSurface == NULL) {
+        return VK_ERROR_OUT_OF_HOST_MEMORY;
+    }
+
+    pIcdSurface->base.platform = VK_ICD_WSI_PLATFORM_XLIB;
+    pIcdSurface->dpy = dpy;
+    pIcdSurface->window = window;
+
+    *pSurface = (VkSurfaceKHR) pIcdSurface;
+
+    return VK_SUCCESS;
+}
+#endif // VK_USE_PLATFORM_XLIB_KHR
+
+#endif // _WIN32
+
+
 bool wsi_swapchain_instance_gpa(struct loader_instance *ptr_instance,
                                  const char* name, void **addr)
 {
     *addr = NULL;
 
+    if (!strcmp("vkDestroySurfaceKHR", name)) {
+        *addr = ptr_instance->wsi_surface_enabled ? (void *) vkDestroySurfaceKHR : NULL;
+        return true;
+    }
     if (!strcmp("vkGetPhysicalDeviceSurfaceSupportKHR", name)) {
         *addr = ptr_instance->wsi_surface_enabled ? (void *) vkGetPhysicalDeviceSurfaceSupportKHR : NULL;
         return true;
     }
+#ifdef _WIN32
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+    if (!strcmp("vkCreateWin32SurfaceKHR", name)) {
+        *addr = ptr_instance->wsi_win32_surface_enabled ? (void *) vkCreateWin32SurfaceKHR : NULL;
+        return true;
+    }
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#else // _WIN32 (i.e. Linux)
+#ifdef VK_USE_PLATFORM_MIR_KHR
+    if (!strcmp("vkCreateMirSurfaceKHR", name)) {
+        *addr = ptr_instance->wsi_mir_surface_enabled ? (void *) vkCreateMirSurfaceKHR : NULL;
+        return true;
+    }
+#endif // VK_USE_PLATFORM_MIR_KHR
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+    if (!strcmp("vkCreateWaylandSurfaceKHR", name)) {
+        *addr = ptr_instance->wsi_wayland_surface_enabled ? (void *) vkCreateWaylandSurfaceKHR : NULL;
+        return true;
+    }
+#endif // VK_USE_PLATFORM_WAYLAND_KHR
+#ifdef VK_USE_PLATFORM_XCB_KHR
+    if (!strcmp("vkCreateXcbSurfaceKHR", name)) {
+        *addr = ptr_instance->wsi_xcb_surface_enabled ? (void *) vkCreateXcbSurfaceKHR : NULL;
+        return true;
+    }
+#endif // VK_USE_PLATFORM_XCB_KHR
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+    if (!strcmp("vkCreateXlibSurfaceKHR", name)) {
+        *addr = ptr_instance->wsi_xlib_surface_enabled ? (void *) vkCreateXlibSurfaceKHR : NULL;
+        return true;
+    }
+#endif // VK_USE_PLATFORM_XLIB_KHR
+#endif // _WIN32
+
     return false;
 }