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
From: Roderick Colenbrander thunderbird2k@gmail.com
Signed-off-by: Roderick Colenbrander thunderbird2k@gmail.com Signed-off-by: Józef Kucia jkucia@codeweavers.com --- dlls/winevulkan/Makefile.in | 3 +- dlls/winevulkan/make_vulkan | 194 ++++++++++++++++++++++++++++++++++++++- dlls/winevulkan/vulkan.c | 13 +-- dlls/winevulkan/vulkan_private.h | 12 +++ dlls/winevulkan/vulkan_thunks.c | 106 +++++++++++++++++++++ dlls/winevulkan/vulkan_thunks.h | 9 ++ 6 files changed, 322 insertions(+), 15 deletions(-) create mode 100644 dlls/winevulkan/vulkan_thunks.c create mode 100644 dlls/winevulkan/vulkan_thunks.h
diff --git a/dlls/winevulkan/Makefile.in b/dlls/winevulkan/Makefile.in index 859c731c6e4c..a3c40bd39864 100644 --- a/dlls/winevulkan/Makefile.in +++ b/dlls/winevulkan/Makefile.in @@ -2,6 +2,7 @@ MODULE = winevulkan.dll IMPORTS = user32 gdi32
C_SRCS = \ - vulkan.c + vulkan.c \ + vulkan_thunks.c
RC_SRCS = version.rc diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan index fd2fd7bd779b..c22619af1bf6 100755 --- a/dlls/winevulkan/make_vulkan +++ b/dlls/winevulkan/make_vulkan @@ -65,6 +65,8 @@ LOGGER.addHandler(logging.StreamHandler()) # Filenames to create. WINE_VULKAN_H = "../../include/wine/vulkan.h" WINE_VULKAN_DRIVER_H = "../../include/wine/vulkan_driver.h" +WINE_VULKAN_THUNKS_C = "vulkan_thunks.c" +WINE_VULKAN_THUNKS_H = "vulkan_thunks.h"
# Functions part of our winevulkan graphics driver interface. @@ -76,15 +78,18 @@ DRIVER_VERSION = 1 # This are regular device / instance functions for which we need # to more work compared to a regular thunk or because they are # part of the driver interface. +# - dispatch set whether we need a function pointer in the device +# / instance dispatch table. # - driver sets whether the api is part of the driver interface. +# - thunk sets whether to create a thunk in vulkan_thunks.c. FUNCTION_OVERRIDES = { # Global functions - "vkCreateInstance" : {"driver" : True}, - "vkEnumerateInstanceExtensionProperties" : {"driver" : True}, - "vkGetInstanceProcAddr": {"driver" : True}, + "vkCreateInstance" : {"dispatch" : False, "driver" : True, "thunk" : False}, + "vkEnumerateInstanceExtensionProperties" : {"dispatch" : False, "driver" : True, "thunk" : False}, + "vkGetInstanceProcAddr": {"dispatch" : False, "driver" : True, "thunk" : False},
# Instance functions - "vkDestroyInstance" : {"driver" : True}, + "vkDestroyInstance" : {"dispatch" : True, "driver" : True, "thunk" : True }, }
@@ -256,7 +261,9 @@ class VkFunction(object):
# For some functions we need some extra metadata from FUNCTION_OVERRIDES. func_info = FUNCTION_OVERRIDES.get(self.name, None) + self.dispatch = func_info["dispatch"] if func_info is not None else True self.driver = func_info["driver"] if func_info is not None else False + self.thunk_needed = func_info["thunk"] if func_info is not None else True
# Required is set while parsing which APIs and types are required # and is used by the code generation. @@ -303,6 +310,12 @@ class VkFunction(object): def is_required(self): return self.required
+ def needs_dispatch(self): + return self.dispatch + + def needs_thunk(self): + return self.thunk_needed + def pfn(self, call_conv=None, conv=False): """ Create function pointer. """
@@ -359,6 +372,48 @@ class VkFunction(object):
return proto
+ def stub(self, call_conv=None, prefix=None): + stub = self.prototype(call_conv=call_conv, prefix=prefix) + stub += "\n{\n" + stub += " {0}".format(self.trace(message="stub: ", trace_func="FIXME")) + + if self.type == "VkResult": + stub += " return VK_ERROR_OUT_OF_HOST_MEMORY;\n" + elif self.type == "VkBool32": + stub += " return VK_FALSE;\n" + + stub += "}\n\n" + return stub + + def trace(self, message=None, trace_func=None): + """ Create a trace string including all parameters. + + Args: + message (str, optional): text to print at start of trace message e.g. 'stub: ' + trace_func (str, optional): used to override trace function e.g. FIXME, printf, etcetera. + """ + if trace_func is not None: + trace = "{0}("".format(trace_func) + else: + trace = "TRACE("" + + if message is not None: + trace += message + + # First loop is for all the format strings. + trace += ", ".join([p.format_string() for p in self.params]) + trace += "\n"" + + # Second loop for parameter names and optional conversions. + for param in self.params: + if param.format_conv is not None: + trace += ", " + param.format_conv.format(param.name) + else: + trace += ", {0}".format(param.name) + trace += ");\n" + + return trace +
class VkFunctionPointer(object): def __init__(self, _type, name, members): @@ -628,6 +683,8 @@ class VkParam(object): self.handle = type_info["data"] if type_info["category"] == "handle" else None self.struct = type_info["data"] if type_info["category"] == "struct" else None
+ self._set_format_string() + def __repr__(self): return "{0} {1} {2} {3} {4}".format(self.const, self.type, self.pointer, self.name, self.array_len, self.dyn_array_len)
@@ -663,6 +720,49 @@ class VkParam(object):
return VkParam(type_info, const=const, pointer=pointer, name=name, array_len=array_len, dyn_array_len=dyn_array_len)
+ def _set_format_string(self): + """ Internal helper function to be used by constructor to set format string. """ + + # Determine a format string used by code generation for traces. + # 64-bit types need a conversion function. + self.format_conv = None + if self.is_static_array() or self.is_pointer(): + self.format_str = "%p" + else: + if self.type_info["category"] == "bitmask": + self.format_str = "%#x" + elif self.type_info["category"] == "enum": + self.format_str = "%d" + elif self.is_handle(): + # We use uint64_t for non-dispatchable handles as opposed to pointers + # for dispatchable handles. + if self.handle.is_dispatchable(): + self.format_str = "%p" + else: + self.format_str = "0x%s" + self.format_conv = "wine_dbgstr_longlong({0})" + elif self.type == "float": + self.format_str = "%f" + elif self.type == "int": + self.format_str = "%d" + elif self.type == "int32_t": + self.format_str = "%d" + elif self.type == "size_t": + self.format_str = "0x%s" + self.format_conv = "wine_dbgstr_longlong({0})" + elif self.type in ["uint32_t", "VkBool32"]: + self.format_str = "%u" + elif self.type in ["uint64_t", "VkDeviceSize"]: + self.format_str = "0x%s" + self.format_conv = "wine_dbgstr_longlong({0})" + elif self.type == "HANDLE": + self.format_str = "%p" + elif self.type in ["VisualID", "xcb_visualid_t", "RROutput"]: + # Don't care about Linux specific types. + self.format_str = "" + else: + LOGGER.warn("Unhandled type: {0}".format(self.type_info)) + def definition(self, postfix=None): """ Return prototype for the parameter. E.g. 'const char *foo' """
@@ -687,6 +787,17 @@ class VkParam(object):
return proto
+ def direction(self): + """ Returns parameter direction: input, output, input_output. + + Parameter direction in Vulkan is not straight-forward, which this function determines. + """ + + return self._direction + + def format_string(self): + return self.format_str + def is_const(self): return self.const is not None
@@ -854,6 +965,75 @@ class VkGenerator(object): def __init__(self, registry): self.registry = registry
+ def generate_thunks_c(self, f, prefix): + f.write("/* Automatically generated from Vulkan vk.xml; DO NOT EDIT! */\n\n") + + f.write("#include "config.h"\n") + f.write("#include "wine/port.h"\n\n") + + f.write("#include "wine/debug.h"\n") + f.write("#include "wine/vulkan.h"\n") + f.write("#include "wine/vulkan_driver.h"\n") + f.write("#include "vulkan_private.h"\n\n") + + f.write("WINE_DEFAULT_DEBUG_CHANNEL(vulkan);\n\n") + + # Create thunks for instance functions. + # Global functions don't go through the thunks. + for vk_func in self.registry.funcs.values(): + if not vk_func.is_required(): + continue + + if vk_func.is_global_func(): + continue + + # We don't support device functions yet as other plumbing + # is needed first. + if vk_func.is_device_func(): + continue + + if not vk_func.needs_thunk(): + continue + + f.write("static " + vk_func.stub(prefix=prefix, call_conv="WINAPI")) + + f.write("static const struct vulkan_func vk_instance_dispatch_table[] =\n{\n") + for vk_func in self.registry.instance_funcs: + if not vk_func.is_required(): + continue + + if not vk_func.needs_dispatch(): + LOGGER.debug("skipping {0} in instance dispatch table".format(vk_func.name)) + continue + + f.write(" {{"{0}", &{1}{0}}},\n".format(vk_func.name, prefix)) + f.write("};\n\n") + + f.write("void *wine_vk_get_instance_proc_addr(const char *name)\n") + f.write("{\n") + f.write(" unsigned int i;\n") + f.write(" for (i = 0; i < ARRAY_SIZE(vk_instance_dispatch_table); i++)\n") + f.write(" {\n") + f.write(" if (strcmp(vk_instance_dispatch_table[i].name, name) == 0)\n") + f.write(" {\n") + f.write(" TRACE("Found pName=%s in instance table\n", name);\n") + f.write(" return vk_instance_dispatch_table[i].func;\n") + f.write(" }\n") + f.write(" }\n") + f.write(" return NULL;\n") + f.write("}\n") + + def generate_thunks_h(self, f, prefix): + f.write("/* Automatically generated from Vulkan vk.xml; DO NOT EDIT! */\n\n") + + f.write("#ifndef __WINE_VULKAN_THUNKS_H\n") + f.write("#define __WINE_VULKAN_THUNKS_H\n\n") + + f.write("/* For use by vk_icdGetInstanceProcAddr / vkGetInstanceProcAddr */\n") + f.write("void *wine_vk_get_instance_proc_addr(const char *name) DECLSPEC_HIDDEN;\n\n") + + f.write("#endif /* __WINE_VULKAN_THUNKS_H */\n") + def generate_vulkan_h(self, f): f.write("/* Automatically generated from Vulkan vk.xml; DO NOT EDIT! */\n\n") f.write("#ifndef __WINE_VULKAN_H\n") @@ -1245,5 +1425,11 @@ def main(): with open(WINE_VULKAN_DRIVER_H, "w") as f: generator.generate_vulkan_driver_h(f)
+ with open(WINE_VULKAN_THUNKS_H, "w") as f: + generator.generate_thunks_h(f, "wine_") + + with open(WINE_VULKAN_THUNKS_C, "w") as f: + generator.generate_thunks_c(f, "wine_") + if __name__ == "__main__": main() diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c index 2152cb15fefe..9d2cdd2fa483 100644 --- a/dlls/winevulkan/vulkan.c +++ b/dlls/winevulkan/vulkan.c @@ -38,16 +38,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(vulkan); */ #define WINE_VULKAN_ICD_VERSION 4
-#ifndef ARRAY_SIZE -#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) -#endif - -struct vulkan_func -{ - const char *name; - void *func; -}; - static void *wine_vk_get_global_proc_addr(const char *name);
static const struct vulkan_funcs *vk_funcs = NULL; @@ -148,6 +138,9 @@ static PFN_vkVoidFunction WINAPI wine_vkGetInstanceProcAddr(VkInstance instance, return NULL; }
+ func = wine_vk_get_instance_proc_addr(name); + if (func) return func; + FIXME("Unsupported device or instance function: '%s'\n", debugstr_a(name)); return NULL; } diff --git a/dlls/winevulkan/vulkan_private.h b/dlls/winevulkan/vulkan_private.h index 6b83e875a299..56881378332f 100644 --- a/dlls/winevulkan/vulkan_private.h +++ b/dlls/winevulkan/vulkan_private.h @@ -20,9 +20,21 @@ #ifndef __WINE_VULKAN_PRIVATE_H #define __WINE_VULKAN_PRIVATE_H
+#include "vulkan_thunks.h" + /* Magic value defined by Vulkan ICD / Loader spec */ #define VULKAN_ICD_MAGIC_VALUE 0x01CDC0DE
+#ifndef ARRAY_SIZE +#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) +#endif + +struct vulkan_func +{ + const char *name; + void *func; +}; + /* 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 diff --git a/dlls/winevulkan/vulkan_thunks.c b/dlls/winevulkan/vulkan_thunks.c new file mode 100644 index 000000000000..57d4f3549b25 --- /dev/null +++ b/dlls/winevulkan/vulkan_thunks.c @@ -0,0 +1,106 @@ +/* Automatically generated from Vulkan vk.xml; DO NOT EDIT! */ + +#include "config.h" +#include "wine/port.h" + +#include "wine/debug.h" +#include "wine/vulkan.h" +#include "wine/vulkan_driver.h" +#include "vulkan_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(vulkan); + +static VkResult WINAPI wine_vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) +{ + FIXME("stub: %p, %p, %p, %p\n", physicalDevice, pCreateInfo, pAllocator, pDevice); + return VK_ERROR_OUT_OF_HOST_MEMORY; +} + +static void WINAPI wine_vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) +{ + FIXME("stub: %p, %p\n", instance, pAllocator); +} + +static VkResult WINAPI wine_vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char *pLayerName, uint32_t *pPropertyCount, VkExtensionProperties *pProperties) +{ + FIXME("stub: %p, %p, %p, %p\n", physicalDevice, pLayerName, pPropertyCount, pProperties); + return VK_ERROR_OUT_OF_HOST_MEMORY; +} + +static VkResult WINAPI wine_vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, VkLayerProperties *pProperties) +{ + FIXME("stub: %p, %p, %p\n", physicalDevice, pPropertyCount, pProperties); + return VK_ERROR_OUT_OF_HOST_MEMORY; +} + +static VkResult WINAPI wine_vkEnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount, VkPhysicalDevice *pPhysicalDevices) +{ + FIXME("stub: %p, %p, %p\n", instance, pPhysicalDeviceCount, pPhysicalDevices); + return VK_ERROR_OUT_OF_HOST_MEMORY; +} + +static void WINAPI wine_vkGetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures *pFeatures) +{ + FIXME("stub: %p, %p\n", physicalDevice, pFeatures); +} + +static void WINAPI wine_vkGetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties *pFormatProperties) +{ + FIXME("stub: %p, %d, %p\n", physicalDevice, format, pFormatProperties); +} + +static VkResult WINAPI wine_vkGetPhysicalDeviceImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags, VkImageFormatProperties *pImageFormatProperties) +{ + FIXME("stub: %p, %d, %d, %d, %#x, %#x, %p\n", physicalDevice, format, type, tiling, usage, flags, pImageFormatProperties); + return VK_ERROR_OUT_OF_HOST_MEMORY; +} + +static void WINAPI wine_vkGetPhysicalDeviceMemoryProperties(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties *pMemoryProperties) +{ + FIXME("stub: %p, %p\n", physicalDevice, pMemoryProperties); +} + +static void WINAPI wine_vkGetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties *pProperties) +{ + FIXME("stub: %p, %p\n", physicalDevice, pProperties); +} + +static void WINAPI wine_vkGetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice, uint32_t *pQueueFamilyPropertyCount, VkQueueFamilyProperties *pQueueFamilyProperties) +{ + FIXME("stub: %p, %p, %p\n", physicalDevice, pQueueFamilyPropertyCount, pQueueFamilyProperties); +} + +static void WINAPI wine_vkGetPhysicalDeviceSparseImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkSampleCountFlagBits samples, VkImageUsageFlags usage, VkImageTiling tiling, uint32_t *pPropertyCount, VkSparseImageFormatProperties *pProperties) +{ + FIXME("stub: %p, %d, %d, %d, %#x, %d, %p, %p\n", physicalDevice, format, type, samples, usage, tiling, pPropertyCount, pProperties); +} + +static const struct vulkan_func vk_instance_dispatch_table[] = +{ + {"vkCreateDevice", &wine_vkCreateDevice}, + {"vkDestroyInstance", &wine_vkDestroyInstance}, + {"vkEnumerateDeviceExtensionProperties", &wine_vkEnumerateDeviceExtensionProperties}, + {"vkEnumerateDeviceLayerProperties", &wine_vkEnumerateDeviceLayerProperties}, + {"vkEnumeratePhysicalDevices", &wine_vkEnumeratePhysicalDevices}, + {"vkGetPhysicalDeviceFeatures", &wine_vkGetPhysicalDeviceFeatures}, + {"vkGetPhysicalDeviceFormatProperties", &wine_vkGetPhysicalDeviceFormatProperties}, + {"vkGetPhysicalDeviceImageFormatProperties", &wine_vkGetPhysicalDeviceImageFormatProperties}, + {"vkGetPhysicalDeviceMemoryProperties", &wine_vkGetPhysicalDeviceMemoryProperties}, + {"vkGetPhysicalDeviceProperties", &wine_vkGetPhysicalDeviceProperties}, + {"vkGetPhysicalDeviceQueueFamilyProperties", &wine_vkGetPhysicalDeviceQueueFamilyProperties}, + {"vkGetPhysicalDeviceSparseImageFormatProperties", &wine_vkGetPhysicalDeviceSparseImageFormatProperties}, +}; + +void *wine_vk_get_instance_proc_addr(const char *name) +{ + unsigned int i; + for (i = 0; i < ARRAY_SIZE(vk_instance_dispatch_table); i++) + { + if (strcmp(vk_instance_dispatch_table[i].name, name) == 0) + { + TRACE("Found pName=%s in instance table\n", name); + return vk_instance_dispatch_table[i].func; + } + } + return NULL; +} diff --git a/dlls/winevulkan/vulkan_thunks.h b/dlls/winevulkan/vulkan_thunks.h new file mode 100644 index 000000000000..dbfd83c1156d --- /dev/null +++ b/dlls/winevulkan/vulkan_thunks.h @@ -0,0 +1,9 @@ +/* Automatically generated from Vulkan vk.xml; DO NOT EDIT! */ + +#ifndef __WINE_VULKAN_THUNKS_H +#define __WINE_VULKAN_THUNKS_H + +/* For use by vk_icdGetInstanceProcAddr / vkGetInstanceProcAddr */ +void *wine_vk_get_instance_proc_addr(const char *name) DECLSPEC_HIDDEN; + +#endif /* __WINE_VULKAN_THUNKS_H */
From: Roderick Colenbrander thunderbird2k@gmail.com
Signed-off-by: Roderick Colenbrander thunderbird2k@gmail.com Signed-off-by: Józef Kucia jkucia@codeweavers.com --- dlls/winevulkan/make_vulkan | 17 ++++++++++++++++- dlls/winevulkan/vulkan.c | 10 ++++++++++ dlls/winevulkan/vulkan_thunks.c | 5 ----- dlls/winevulkan/vulkan_thunks.h | 3 +++ 4 files changed, 29 insertions(+), 6 deletions(-)
diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan index c22619af1bf6..6c6cf2ea3cad 100755 --- a/dlls/winevulkan/make_vulkan +++ b/dlls/winevulkan/make_vulkan @@ -89,7 +89,7 @@ FUNCTION_OVERRIDES = { "vkGetInstanceProcAddr": {"dispatch" : False, "driver" : True, "thunk" : False},
# Instance functions - "vkDestroyInstance" : {"dispatch" : True, "driver" : True, "thunk" : True }, + "vkDestroyInstance" : {"dispatch" : True, "driver" : True, "thunk" : False }, }
@@ -1032,6 +1032,21 @@ class VkGenerator(object): f.write("/* For use by vk_icdGetInstanceProcAddr / vkGetInstanceProcAddr */\n") f.write("void *wine_vk_get_instance_proc_addr(const char *name) DECLSPEC_HIDDEN;\n\n")
+ # Generate prototypes for device and instance functions requiring a custom implementation. + f.write("/* Functions for which we have custom implementations outside of the thunks. */\n") + for vk_func in self.registry.funcs.values(): + if not vk_func.is_required(): + continue + + if vk_func.is_global_func(): + continue + + if vk_func.needs_thunk(): + continue + + f.write("{0};\n".format(vk_func.prototype("WINAPI", prefix="wine_", postfix="DECLSPEC_HIDDEN"))) + f.write("\n") + f.write("#endif /* __WINE_VULKAN_THUNKS_H */\n")
def generate_vulkan_h(self, f): diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c index 9d2cdd2fa483..85836bdd4267 100644 --- a/dlls/winevulkan/vulkan.c +++ b/dlls/winevulkan/vulkan.c @@ -108,6 +108,16 @@ err: return res; }
+void WINAPI wine_vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks *allocator) +{ + TRACE("%p, %p\n", instance, allocator); + + if (allocator) + FIXME("Support allocation allocators\n"); + + wine_vk_instance_free(instance); +} + static VkResult WINAPI wine_vkEnumerateInstanceExtensionProperties(const char *layer_name, uint32_t *count, VkExtensionProperties *properties) { diff --git a/dlls/winevulkan/vulkan_thunks.c b/dlls/winevulkan/vulkan_thunks.c index 57d4f3549b25..c1c0b079a534 100644 --- a/dlls/winevulkan/vulkan_thunks.c +++ b/dlls/winevulkan/vulkan_thunks.c @@ -16,11 +16,6 @@ static VkResult WINAPI wine_vkCreateDevice(VkPhysicalDevice physicalDevice, cons return VK_ERROR_OUT_OF_HOST_MEMORY; }
-static void WINAPI wine_vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) -{ - FIXME("stub: %p, %p\n", instance, pAllocator); -} - static VkResult WINAPI wine_vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char *pLayerName, uint32_t *pPropertyCount, VkExtensionProperties *pProperties) { FIXME("stub: %p, %p, %p, %p\n", physicalDevice, pLayerName, pPropertyCount, pProperties); diff --git a/dlls/winevulkan/vulkan_thunks.h b/dlls/winevulkan/vulkan_thunks.h index dbfd83c1156d..969bf125f974 100644 --- a/dlls/winevulkan/vulkan_thunks.h +++ b/dlls/winevulkan/vulkan_thunks.h @@ -6,4 +6,7 @@ /* For use by vk_icdGetInstanceProcAddr / vkGetInstanceProcAddr */ void *wine_vk_get_instance_proc_addr(const char *name) DECLSPEC_HIDDEN;
+/* Functions for which we have custom implementations outside of the thunks. */ +void WINAPI wine_vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) DECLSPEC_HIDDEN; + #endif /* __WINE_VULKAN_THUNKS_H */
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/configure.ac b/configure.ac index 3b93966c3648..2695c67f05e2 100644 --- a/configure.ac +++ b/configure.ac @@ -77,9 +77,9 @@ AC_ARG_WITH(pthread, AS_HELP_STRING([--without-pthread],[do not use the pthrea [if test "x$withval" = "xno"; then ac_cv_header_pthread_h=no; fi]) AC_ARG_WITH(pulse, AS_HELP_STRING([--without-pulse],[do not use PulseAudio sound support])) AC_ARG_WITH(sane, AS_HELP_STRING([--without-sane],[do not use SANE (scanner support)])) +AC_ARG_WITH(sdl, AS_HELP_STRING([--without-sdl],[do not use SDL])) 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]),