From: Roderick Colenbrander thunderbird2k@gmail.com
Signed-off-by: Roderick Colenbrander thunderbird2k@gmail.com Signed-off-by: Józef Kucia jkucia@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