[PATCH v5 1/4] winevulkan/winex11: Implement vkCreateInstance.
Józef Kucia
jkucia at codeweavers.com
Thu Mar 1 09:37:03 CST 2018
From: Roderick Colenbrander <thunderbird2k at gmail.com>
Signed-off-by: Roderick Colenbrander <thunderbird2k at gmail.com>
Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
---
v5: Rebased and fixed compilation errors between patches.
---
configure.ac | 9 ++++++
dlls/winevulkan/vulkan.c | 49 +++++++++++++++++++++++++++--
dlls/winevulkan/vulkan_private.h | 45 +++++++++++++++++++++++++++
dlls/winex11.drv/vulkan.c | 67 +++++++++++++++++++++++++++++++++++++---
include/config.h.in | 3 ++
5 files changed, 166 insertions(+), 7 deletions(-)
create mode 100644 dlls/winevulkan/vulkan_private.h
diff --git a/configure.ac b/configure.ac
index 02937cab5db8..3b93966c3648 100644
--- a/configure.ac
+++ b/configure.ac
@@ -81,6 +81,7 @@ 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(sdl, AS_HELP_STRING([--without-sdl],[do not use SDL]))
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]),
@@ -1836,6 +1837,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/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c
index e6c77cab3259..2152cb15fefe 100644
--- a/dlls/winevulkan/vulkan.c
+++ b/dlls/winevulkan/vulkan.c
@@ -24,8 +24,10 @@
#include "winuser.h"
#include "wine/debug.h"
+#include "wine/heap.h"
#include "wine/vulkan.h"
#include "wine/vulkan_driver.h"
+#include "vulkan_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(vulkan);
@@ -66,11 +68,54 @@ static BOOL wine_vk_init(void)
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)
+ vk_funcs->p_vkDestroyInstance(instance->instance, NULL /* allocator */);
+
+ heap_free(instance);
+}
+
static VkResult WINAPI wine_vkCreateInstance(const VkInstanceCreateInfo *create_info,
const VkAllocationCallbacks *allocator, VkInstance *instance)
{
- TRACE("%p %p %p\n", create_info, allocator, instance);
- return vk_funcs->p_vkCreateInstance(create_info, allocator, instance);
+ struct VkInstance_T *object = NULL;
+ VkResult res;
+
+ TRACE("create_info %p, allocator %p, instance %p\n", create_info, allocator, instance);
+
+ if (allocator)
+ FIXME("Support for allocation callbacks not implemented yet\n");
+
+ object = heap_alloc(sizeof(*object));
+ if (!object)
+ {
+ ERR("Failed to allocate memory for instance\n");
+ res = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto err;
+ }
+ object->base.loader_magic = VULKAN_ICD_MAGIC_VALUE;
+
+ res = vk_funcs->p_vkCreateInstance(create_info, NULL /* allocator */, &object->instance);
+ if (res != VK_SUCCESS)
+ {
+ ERR("Failed to create instance, res=%d\n", res);
+ goto err;
+ }
+
+ *instance = object;
+ TRACE("Done, instance=%p native_instance=%p\n", object, object->instance);
+ return VK_SUCCESS;
+
+err:
+ wine_vk_instance_free(object);
+ return res;
}
static VkResult WINAPI wine_vkEnumerateInstanceExtensionProperties(const char *layer_name,
diff --git a/dlls/winevulkan/vulkan_private.h b/dlls/winevulkan/vulkan_private.h
new file mode 100644
index 000000000000..6b83e875a299
--- /dev/null
+++ b/dlls/winevulkan/vulkan_private.h
@@ -0,0 +1,45 @@
+/* Wine Vulkan ICD private data structures
+ *
+ * Copyright 2017 Roderick Colenbrander
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __WINE_VULKAN_PRIVATE_H
+#define __WINE_VULKAN_PRIVATE_H
+
+/* Magic value defined by Vulkan ICD / Loader spec */
+#define VULKAN_ICD_MAGIC_VALUE 0x01CDC0DE
+
+/* 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_PRIVATE_H */
diff --git a/dlls/winex11.drv/vulkan.c b/dlls/winex11.drv/vulkan.c
index 92f8a0e4526b..adc3da35e49d 100644
--- a/dlls/winex11.drv/vulkan.c
+++ b/dlls/winex11.drv/vulkan.c
@@ -20,22 +20,67 @@
#include "config.h"
#include "wine/port.h"
+#include <stdarg.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 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;
+}
+
static VkResult X11DRV_vkCreateInstance(const VkInstanceCreateInfo *create_info,
const VkAllocationCallbacks *allocator, VkInstance *instance)
{
- FIXME("stub: %p %p %p\n", create_info, allocator, instance);
- return VK_ERROR_INCOMPATIBLE_DRIVER;
+ TRACE("create_info %p, allocator %p, instance %p\n", create_info, allocator, instance);
+
+ if (allocator)
+ FIXME("Support for allocation callbacks not implemented yet\n");
+
+ /* TODO: convert win32 to x11 extensions here. */
+ if (create_info->enabledExtensionCount > 0)
+ {
+ FIXME("Extensions are not supported yet, aborting!\n");
+ return VK_ERROR_INCOMPATIBLE_DRIVER;
+ }
+
+ return pvkCreateInstance(create_info, NULL /* allocator */, instance);
}
static void X11DRV_vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks *allocator)
{
- FIXME("stub: %p %p\n", instance, allocator);
+ TRACE("%p %p\n", instance, allocator);
+
+ if (allocator)
+ FIXME("Support for allocation callbacks not implemented yet\n");
+
+ pvkDestroyInstance(instance, NULL /* allocator */);
}
static VkResult X11DRV_vkEnumerateInstanceExtensionProperties(const char *layer_name,
@@ -75,7 +120,7 @@ static void * X11DRV_vkGetInstanceProcAddr(VkInstance instance, const char *name
return NULL;
}
-static struct vulkan_funcs vulkan_funcs =
+static const struct vulkan_funcs vulkan_funcs =
{
X11DRV_vkCreateInstance,
X11DRV_vkDestroyInstance,
@@ -91,5 +136,17 @@ const 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 */
+
+const 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 b7ed9d2b8c60..c9f24851563d 100644
--- a/include/config.h.in
+++ b/include/config.h.in
@@ -1560,6 +1560,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
--
2.16.1
More information about the wine-devel
mailing list