[PATCH 8/9] winex11: Implement vkCreateInstance.
Roderick Colenbrander <[email protected]> Mon, 6 Nov 2017 00:08:24 -0800
| Newsgroups | gmane.comp.emulators.wine.patches |
|---|---|
| Message-ID | <[email protected]> |
Signed-off-by: Roderick Colenbrander <[email protected]> --- 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