[PATCH 8/9] winex11: Implement vkCreateInstance.

Roderick Colenbrander thunderbird2k at gmail.com
Mon Nov 6 02:08:24 CST 2017


Signed-off-by: Roderick Colenbrander <thunderbird2k at gmail.com>
---
 configure.ac                 |   9 ++++
 dlls/winex11.drv/vulkan.c    | 111 +++++++++++++++++++++++++++++++++++++++++--
 include/config.h.in          |   3 ++
 include/wine/vulkan_driver.h |  22 +++++++++
 4 files changed, 142 insertions(+), 3 deletions(-)

diff --git a/configure.ac b/configure.ac
index 6a2ebe36f0..88c4d543ed 100644
--- a/configure.ac
+++ b/configure.ac
@@ -78,6 +78,7 @@ AC_ARG_WITH(sane,      AS_HELP_STRING([--without-sane],[do not use SANE (scanner
 AC_ARG_WITH(tiff,      AS_HELP_STRING([--without-tiff],[do not use TIFF]))
 AC_ARG_WITH(udev,      AS_HELP_STRING([--without-udev],[do not use udev (plug and play support)]))
 AC_ARG_WITH(v4l,       AS_HELP_STRING([--without-v4l],[do not use v4l1 (v4l support)]))
+AC_ARG_WITH(vulkan,    AS_HELP_STRING([--without-vulkan],[do not use vulkan]))
 AC_ARG_WITH(xcomposite,AS_HELP_STRING([--without-xcomposite],[do not use the Xcomposite extension]),
             [if test "x$withval" = "xno"; then ac_cv_header_X11_extensions_Xcomposite_h=no; fi])
 AC_ARG_WITH(xcursor,   AS_HELP_STRING([--without-xcursor],[do not use the Xcursor extension]),
@@ -1791,6 +1792,14 @@ then
     WINE_WARNING([No sound system was found. Windows applications will be silent.])
 fi
 
+dnl *** Check for vulkan ***
+if test "x$with_vulkan" != "xno"
+then
+    WINE_CHECK_SONAME(vulkan, vkGetInstanceProcAddr)
+fi
+WINE_NOTICE_WITH(vulkan,[test "x$ac_cv_lib_soname_vulkan" = "x"],
+                 [libvulkan ${notice_platform}development files not found, vulkan won't be supported.])
+
 dnl **** Check for gcc specific options ****
 
 AC_SUBST(EXTRACFLAGS,"")
diff --git a/dlls/winex11.drv/vulkan.c b/dlls/winex11.drv/vulkan.c
index c3897af85d..04a9ea0a9c 100644
--- a/dlls/winex11.drv/vulkan.c
+++ b/dlls/winex11.drv/vulkan.c
@@ -20,17 +20,110 @@
 #include "config.h"
 #include "wine/port.h"
 
+#include "windef.h"
+#include "winbase.h"
+
 #include "wine/debug.h"
+#include "wine/library.h"
 #include "wine/vulkan.h"
 #include "wine/vulkan_driver.h"
 
+#ifdef SONAME_LIBVULKAN
+
 WINE_DEFAULT_DEBUG_CHANNEL(vulkan);
 
+static VkResult (*pvkCreateInstance)(const VkInstanceCreateInfo *, const VkAllocationCallbacks *, VkInstance *);
+static void (*pvkDestroyInstance)(VkInstance, const VkAllocationCallbacks *);
+
+static void *wine_vk_alloc_dispatchable_object(size_t size)
+{
+    struct wine_vk_dispatchable_object *object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
+
+    if (!object)
+        return NULL;
+
+    /* Set special header for ICD loader. */
+    ((struct wine_vk_base*)object)->loader_magic = VULKAN_ICD_MAGIC_VALUE;
+
+    return object;
+}
+
+static BOOL wine_vk_init(void)
+{
+    static BOOL init_done = FALSE;
+    static void *vulkan_handle;
+
+    if (init_done) return (vulkan_handle != NULL);
+    init_done = TRUE;
+
+    if (!(vulkan_handle = wine_dlopen(SONAME_LIBVULKAN, RTLD_NOW, NULL, 0))) return FALSE;
+
+#define LOAD_FUNCPTR(f) if((p##f = wine_dlsym(vulkan_handle, #f, NULL, 0)) == NULL) return FALSE;
+LOAD_FUNCPTR(vkCreateInstance)
+LOAD_FUNCPTR(vkDestroyInstance)
+#undef LOAD_FUNCPTR
+
+    return TRUE;
+}
+
+/* Helper function used for freeing an instance structure. This function supports full
+ * and partial object cleanups and can thus be used for vkCreateInstance failures.
+ */
+static void wine_vk_instance_free(struct VkInstance_T *instance)
+{
+    if (!instance)
+        return;
+
+    if (instance->instance)
+        pvkDestroyInstance(instance->instance, NULL /* pAllocator */);
+
+    HeapFree(GetProcessHeap(), 0, instance);
+}
+
 static VkResult X11DRV_vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
         VkInstance *pInstance)
 {
-    FIXME("stub: %p %p %p\n", pCreateInfo, pAllocator, pInstance);
-    return VK_ERROR_INCOMPATIBLE_DRIVER;
+    VkInstance instance = NULL;
+    VkResult res;
+
+    TRACE("pCreateInfo %p, pAllocater %p, pInstance %p\n", pCreateInfo, pAllocator, pInstance);
+
+    if (pAllocator)
+    {
+        FIXME("Support for allocation callbacks not implemented yet\n");
+    }
+
+    if (pCreateInfo->enabledExtensionCount > 0)
+    {
+        FIXME("Extensions are not supported yet, aborting!\n");
+        res = VK_ERROR_INCOMPATIBLE_DRIVER;
+        goto err;
+    }
+
+    instance = wine_vk_alloc_dispatchable_object(sizeof(*instance));
+    if (!instance)
+    {
+        ERR("Failed to allocate memory for instance\n");
+        res = VK_ERROR_OUT_OF_HOST_MEMORY;
+        goto err;
+    }
+
+    res = pvkCreateInstance(pCreateInfo, NULL /* pAllocator */, &instance->instance);
+    if (res != VK_SUCCESS)
+    {
+        ERR("Failed to create instance, res=%d\n", res);
+        goto err;
+    }
+
+    *pInstance = instance;
+    TRACE("Done, instance=%p native_instance=%p\n", instance, instance->instance);
+    return VK_SUCCESS;
+
+err:
+    if (instance)
+        wine_vk_instance_free(instance);
+
+    return res;
 }
 
 static VkResult X11DRV_vkEnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pPropertyCount,
@@ -77,5 +170,17 @@ struct vulkan_funcs *get_vulkan_driver(UINT version)
         return NULL;
     }
 
-    return &vulkan_funcs;
+    if (wine_vk_init())
+        return &vulkan_funcs;
+
+    return NULL;
 }
+
+#else /* No vulkan */
+
+struct vulkan_funcs *get_vulkan_driver(UINT version)
+{
+    return NULL;
+}
+
+#endif /* SONAME_LIBVULKAN */
diff --git a/include/config.h.in b/include/config.h.in
index a6ec41b5fa..444f4595d4 100644
--- a/include/config.h.in
+++ b/include/config.h.in
@@ -1541,6 +1541,9 @@
 /* Define to the soname of the libXxf86vm library. */
 #undef SONAME_LIBXXF86VM
 
+/* Define to the soname of the libvulkan library. */
+#undef SONAME_LIBVULKAN
+
 /* Define to 1 if the `S_IS*' macros in <sys/stat.h> do not work properly. */
 #undef STAT_MACROS_BROKEN
 
diff --git a/include/wine/vulkan_driver.h b/include/wine/vulkan_driver.h
index fd5c881897..bcdf892667 100644
--- a/include/wine/vulkan_driver.h
+++ b/include/wine/vulkan_driver.h
@@ -1,6 +1,9 @@
 #ifndef __WINE_VULKAN_DRIVER_H
 #define __WINE_VULKAN_DRIVER_H
 
+/* Magic value defined by Vulkan ICD / Loader spec */
+#define VULKAN_ICD_MAGIC_VALUE 0x01CDC0DE
+/* Wine internal vulkan driver version, needs to be bumped upon vulkan_funcs changes. */
 #define WINE_VULKAN_DRIVER_VERSION 1
 
 struct vulkan_funcs
@@ -15,4 +18,23 @@ struct vulkan_funcs
 
 extern struct vulkan_funcs * CDECL __wine_get_vulkan_driver(HDC hdc, UINT version);
 
+/* Base 'class' for our Vulkan dispatchable objects such as VkDevice and VkInstance.
+ * This structure MUST be the first element of a dispatchable object as the ICD
+ * loader depends on it. For now only contains loader_magic, but over time more common
+ * functionality is expected.
+ */
+struct wine_vk_base
+{
+    /* Special section in each dispatchable object for use by the ICD loader for
+     * storing dispatch tables. The start contains a magical value '0x01CDC0DE'.
+     */
+    UINT_PTR loader_magic;
+};
+
+struct VkInstance_T
+{
+    struct wine_vk_base base;
+    VkInstance instance; /* native instance */
+};
+
 #endif /* __WINE_VULKAN_DRIVER_H */
-- 
2.13.6




More information about the wine-patches mailing list