Signed-off-by: Roderick Colenbrander thunderbird2k@gmail.com --- dlls/gdi32/Makefile.in | 3 ++- dlls/gdi32/dibdrv/dc.c | 2 ++ dlls/gdi32/driver.c | 6 +++++ dlls/gdi32/enhmfdrv/dc.c | 1 + dlls/gdi32/enhmfdrv/init.c | 1 + dlls/gdi32/freetype.c | 1 + dlls/gdi32/gdi32.spec | 3 +++ dlls/gdi32/mfdrv/init.c | 1 + dlls/gdi32/path.c | 1 + dlls/gdi32/vulkan.c | 41 ++++++++++++++++++++++++++++++ dlls/wineandroid.drv/init.c | 1 + dlls/winemac.drv/gdi.c | 1 + dlls/wineps.drv/init.c | 1 + dlls/winevulkan/Makefile.in | 1 + dlls/winevulkan/make_vulkan | 60 ++++++++++++++++++++++++++++++++++++++++++++ dlls/winevulkan/vulkan.c | 25 ++++++++++++++++-- dlls/winex11.drv/init.c | 1 + dlls/winex11.drv/xrender.c | 1 + include/wine/gdi_driver.h | 5 +++- include/wine/vulkan_driver.h | 23 +++++++++++++++++ 20 files changed, 175 insertions(+), 4 deletions(-) create mode 100644 dlls/gdi32/vulkan.c create mode 100644 include/wine/vulkan_driver.h
diff --git a/dlls/gdi32/Makefile.in b/dlls/gdi32/Makefile.in index a0f76d23bb..9e5464de2d 100644 --- a/dlls/gdi32/Makefile.in +++ b/dlls/gdi32/Makefile.in @@ -46,7 +46,8 @@ C_SRCS = \ pen.c \ printdrv.c \ region.c \ - vertical.c + vertical.c \ + vulkan.c
RC_SRCS = gdi32.rc
diff --git a/dlls/gdi32/dibdrv/dc.c b/dlls/gdi32/dibdrv/dc.c index 2447093921..78f4b7a396 100644 --- a/dlls/gdi32/dibdrv/dc.c +++ b/dlls/gdi32/dibdrv/dc.c @@ -520,6 +520,7 @@ const struct gdi_dc_funcs dib_driver = NULL, /* pUnrealizePalette */ NULL, /* pWidenPath */ dibdrv_wine_get_wgl_driver, /* wine_get_wgl_driver */ + NULL, /* wine_get_vulkan_driver */ GDI_PRIORITY_DIB_DRV /* priority */ };
@@ -1146,5 +1147,6 @@ static const struct gdi_dc_funcs window_driver = NULL, /* pUnrealizePalette */ NULL, /* pWidenPath */ windrv_wine_get_wgl_driver, /* wine_get_wgl_driver */ + NULL, /* wine_get_vulkan_driver */ GDI_PRIORITY_DIB_DRV + 10 /* priority */ }; diff --git a/dlls/gdi32/driver.c b/dlls/gdi32/driver.c index 6a3975a531..fcf016b578 100644 --- a/dlls/gdi32/driver.c +++ b/dlls/gdi32/driver.c @@ -681,6 +681,11 @@ static struct opengl_funcs *nulldrv_wine_get_wgl_driver( PHYSDEV dev, UINT versi return (void *)-1; }
+static const struct vulkan_funcs *nulldrv_wine_get_vulkan_driver( PHYSDEV dev, UINT version ) +{ + return NULL; +} + const struct gdi_dc_funcs null_driver = { nulldrv_AbortDoc, /* pAbortDoc */ @@ -810,6 +815,7 @@ const struct gdi_dc_funcs null_driver = nulldrv_UnrealizePalette, /* pUnrealizePalette */ nulldrv_WidenPath, /* pWidenPath */ nulldrv_wine_get_wgl_driver, /* wine_get_wgl_driver */ + nulldrv_wine_get_vulkan_driver, /* wine_get_vulkan_driver */
GDI_PRIORITY_NULL_DRV /* priority */ }; diff --git a/dlls/gdi32/enhmfdrv/dc.c b/dlls/gdi32/enhmfdrv/dc.c index 37180fec9e..99a089f1a2 100644 --- a/dlls/gdi32/enhmfdrv/dc.c +++ b/dlls/gdi32/enhmfdrv/dc.c @@ -950,5 +950,6 @@ static const struct gdi_dc_funcs emfpath_driver = NULL, /* pUnrealizePalette */ NULL, /* pWidenPath */ NULL, /* wine_get_wgl_driver */ + NULL, /* wine_get_vulkan_driver */ GDI_PRIORITY_PATH_DRV + 1 /* priority */ }; diff --git a/dlls/gdi32/enhmfdrv/init.c b/dlls/gdi32/enhmfdrv/init.c index 6f9a95632c..35803bcc33 100644 --- a/dlls/gdi32/enhmfdrv/init.c +++ b/dlls/gdi32/enhmfdrv/init.c @@ -163,6 +163,7 @@ static const struct gdi_dc_funcs emfdrv_driver = NULL, /* pUnrealizePalette */ EMFDRV_WidenPath, /* pWidenPath */ NULL, /* wine_get_wgl_driver */ + NULL, /* wine_get_vulkan_driver */ GDI_PRIORITY_GRAPHICS_DRV /* priority */ };
diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c index 383314794a..37ca6dc5cc 100644 --- a/dlls/gdi32/freetype.c +++ b/dlls/gdi32/freetype.c @@ -8902,6 +8902,7 @@ static const struct gdi_dc_funcs freetype_funcs = NULL, /* pUnrealizePalette */ NULL, /* pWidenPath */ NULL, /* wine_get_wgl_driver */ + NULL, /* wine_get_vulkan_driver */ GDI_PRIORITY_FONT_DRV /* priority */ };
diff --git a/dlls/gdi32/gdi32.spec b/dlls/gdi32/gdi32.spec index 7792731b9e..2400a51038 100644 --- a/dlls/gdi32/gdi32.spec +++ b/dlls/gdi32/gdi32.spec @@ -524,3 +524,6 @@
# OpenGL @ cdecl __wine_get_wgl_driver(long long) + +# Vulkan +@ cdecl __wine_get_vulkan_driver(long long) diff --git a/dlls/gdi32/mfdrv/init.c b/dlls/gdi32/mfdrv/init.c index 50f8ba3b4e..d766d025e5 100644 --- a/dlls/gdi32/mfdrv/init.c +++ b/dlls/gdi32/mfdrv/init.c @@ -226,6 +226,7 @@ static const struct gdi_dc_funcs MFDRV_Funcs = NULL, /* pUnrealizePalette */ MFDRV_WidenPath, /* pWidenPath */ NULL, /* wine_get_wgl_driver */ + NULL, /* wine_get_vulkan_driver */ GDI_PRIORITY_GRAPHICS_DRV /* priority */ };
diff --git a/dlls/gdi32/path.c b/dlls/gdi32/path.c index 51334b28b4..41cab60515 100644 --- a/dlls/gdi32/path.c +++ b/dlls/gdi32/path.c @@ -2245,5 +2245,6 @@ const struct gdi_dc_funcs path_driver = NULL, /* pUnrealizePalette */ NULL, /* pWidenPath */ NULL, /* wine_get_wgl_driver */ + NULL, /* wine_get_vulkan_driver */ GDI_PRIORITY_PATH_DRV /* priority */ }; diff --git a/dlls/gdi32/vulkan.c b/dlls/gdi32/vulkan.c new file mode 100644 index 0000000000..6358417974 --- /dev/null +++ b/dlls/gdi32/vulkan.c @@ -0,0 +1,41 @@ +/* + * Vulkan display driver loading + * + * Copyright (c) 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 + */ + +#include "config.h" +#include "wine/port.h" + +#include "gdi_private.h" + +/*********************************************************************** + * __wine_get_vulkan_driver (GDI32.@) + */ +const struct vulkan_funcs * CDECL __wine_get_vulkan_driver(HDC hdc, UINT version) +{ + const struct vulkan_funcs *ret = NULL; + DC * dc = get_dc_ptr(hdc); + + if (dc) + { + PHYSDEV physdev = GET_DC_PHYSDEV(dc, wine_get_vulkan_driver); + ret = physdev->funcs->wine_get_vulkan_driver(physdev, version); + release_dc_ptr(dc); + } + return ret; +} diff --git a/dlls/wineandroid.drv/init.c b/dlls/wineandroid.drv/init.c index 47ef4a2a86..0dd3e5e686 100644 --- a/dlls/wineandroid.drv/init.c +++ b/dlls/wineandroid.drv/init.c @@ -453,6 +453,7 @@ static const struct gdi_dc_funcs android_drv_funcs = NULL, /* pUnrealizePalette */ NULL, /* pWidenPath */ ANDROID_wine_get_wgl_driver, /* wine_get_wgl_driver */ + NULL, /* wine_get_vulkan_driver */ GDI_PRIORITY_GRAPHICS_DRV /* priority */ };
diff --git a/dlls/winemac.drv/gdi.c b/dlls/winemac.drv/gdi.c index 896016bfb2..1f9ac8be41 100644 --- a/dlls/winemac.drv/gdi.c +++ b/dlls/winemac.drv/gdi.c @@ -418,6 +418,7 @@ static const struct gdi_dc_funcs macdrv_funcs = NULL, /* pUnrealizePalette */ NULL, /* pWidenPath */ macdrv_wine_get_wgl_driver, /* wine_get_wgl_driver */ + NULL, /* wine_get_vulkan_driver */ GDI_PRIORITY_GRAPHICS_DRV /* priority */ };
diff --git a/dlls/wineps.drv/init.c b/dlls/wineps.drv/init.c index 5b328798cc..2eb03b836c 100644 --- a/dlls/wineps.drv/init.c +++ b/dlls/wineps.drv/init.c @@ -908,6 +908,7 @@ static const struct gdi_dc_funcs psdrv_funcs = NULL, /* pUnrealizePalette */ NULL, /* pWidenPath */ NULL, /* wine_get_wgl_driver */ + NULL, /* wine_get_vulkan_driver */ GDI_PRIORITY_GRAPHICS_DRV /* priority */ };
diff --git a/dlls/winevulkan/Makefile.in b/dlls/winevulkan/Makefile.in index 0bffb487e2..859c731c6e 100644 --- a/dlls/winevulkan/Makefile.in +++ b/dlls/winevulkan/Makefile.in @@ -1,4 +1,5 @@ MODULE = winevulkan.dll +IMPORTS = user32 gdi32
C_SRCS = \ vulkan.c diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan index 80ad9fcee4..b786354168 100755 --- a/dlls/winevulkan/make_vulkan +++ b/dlls/winevulkan/make_vulkan @@ -69,6 +69,27 @@ WINE_VULKAN_THUNKS_C = "vulkan_thunks.c" WINE_VULKAN_THUNKS_H = "vulkan_thunks.h"
+# Functions part of our winevulkan graphics driver interface. +# DRIVER_VERSION should be bumped on any change to driver interface +# in FUNCTION_OVERRIDES +DRIVER_VERSION = 1 + +# Table of functions for which we have a special implementation. +# 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. +# - driver sets whether the api is part of the driver interface. +FUNCTION_OVERRIDES = { + # Global functions + "vkCreateInstance" : {"driver" : True}, + "vkEnumerateInstanceExtensionProperties" : {"driver" : True}, + "vkGetInstanceProcAddr": {"driver" : True}, + + # Instance functions + "vkDestroyInstance" : {"driver" : True}, +} + + class VkBaseType(object): def __init__(self, name, _type, requires=None): """ Vulkan base type class. @@ -235,6 +256,10 @@ class VkFunction(object): self.type = _type self.params = params
+ # For some functions we need some extra metadata from FUNCTION_OVERRIDES. + func_info = FUNCTION_OVERRIDES.get(self.name, None) + self.driver = func_info["driver"] if func_info is not None else False + # Required is set while parsing which APIs and types are required # and is used by the code generation. self.required = False @@ -257,6 +282,10 @@ class VkFunction(object): # If none of the other, it must be a device function return not self.is_global_func() and not self.is_instance_func()
+ def is_driver_func(self): + """ Returns if function is part of Wine driver interface. """ + return self.driver + def is_global_func(self): # Treat vkGetInstanceProcAddr as a global function as it # can operate with NULL for vkInstance. @@ -904,6 +933,34 @@ class VkGenerator(object):
f.write("#endif /* __WINE_VULKAN_H */\n")
+ def generate_vulkan_driver_h(self, f): + f.write("/* Automatically generated from Vulkan vk.xml; DO NOT EDIT! */\n\n") + f.write("#ifndef __WINE_VULKAN_DRIVER_H\n") + f.write("#define __WINE_VULKAN_DRIVER_H\n\n") + + f.write("/* Wine internal vulkan driver version, needs to be bumped upon vulkan_funcs changes. */\n") + f.write("#define WINE_VULKAN_DRIVER_VERSION {0}\n\n".format(DRIVER_VERSION)) + + f.write("struct vulkan_funcs\n{\n") + f.write(" /* Vulkan global functions. This are the only calls at this point a graphics driver\n") + f.write(" * needs to provide. Other function calls will be provided indirectly by dispatch\n") + f.write(" * tables part of dispatchable Vulkan objects such as VkInstance or vkDevice.\n") + f.write(" */\n") + + for vk_func in self.registry.funcs.values(): + if not vk_func.is_required() or not vk_func.is_driver_func(): + continue + + pfn = vk_func.pfn() + # Avoid PFN_vkVoidFunction in driver interface as Vulkan likes to put calling convention + # stuff in there. For simplicity substitute with "void *". + pfn = pfn.replace("PFN_vkVoidFunction", "void *") + f.write(" {0};\n".format(pfn)) + f.write("};\n\n") + + f.write("extern const struct vulkan_funcs * CDECL __wine_get_vulkan_driver(HDC hdc, UINT version);\n\n") + f.write("#endif /* __WINE_VULKAN_DRIVER_H */\n") +
class VkRegistry(object): def __init__(self, reg_filename): @@ -1187,5 +1244,8 @@ def main(): with open(WINE_VULKAN_H, "w") as f: generator.generate_vulkan_h(f)
+ with open(WINE_VULKAN_DRIVER_H, "w") as f: + generator.generate_vulkan_driver_h(f) + if __name__ == "__main__": main() diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c index 6f97fb99e6..103314bb9f 100644 --- a/dlls/winevulkan/vulkan.c +++ b/dlls/winevulkan/vulkan.c @@ -21,9 +21,11 @@
#include "windef.h" #include "winbase.h" +#include "winuser.h"
#include "wine/debug.h" #include "wine/vulkan.h" +#include "wine/vulkan_driver.h"
WINE_DEFAULT_DEBUG_CHANNEL(vulkan);
@@ -46,6 +48,26 @@ struct vulkan_func
static void *wine_vk_get_global_proc_addr(const char *name);
+static const struct vulkan_funcs *vk_funcs = NULL; + +static BOOL wine_vk_init(HINSTANCE hinst) +{ + HDC hdc = GetDC(0); + + vk_funcs = __wine_get_vulkan_driver(hdc, WINE_VULKAN_DRIVER_VERSION); + if (!vk_funcs) + { + ERR("Failed to load Wine graphics driver supporting Vulkan.\n"); + ReleaseDC(0, hdc); + return FALSE; + } + + DisableThreadLibraryCalls(hinst); + + ReleaseDC(0, hdc); + return TRUE; +} + static VkResult WINAPI wine_vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkInstance *pInstance) { @@ -121,8 +143,7 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved) switch(reason) { case DLL_PROCESS_ATTACH: - DisableThreadLibraryCalls(hinst); - break; + return wine_vk_init(hinst);
case DLL_THREAD_ATTACH: break; diff --git a/dlls/winex11.drv/init.c b/dlls/winex11.drv/init.c index e1eb3f84d3..24ed656405 100644 --- a/dlls/winex11.drv/init.c +++ b/dlls/winex11.drv/init.c @@ -475,6 +475,7 @@ static const struct gdi_dc_funcs x11drv_funcs = X11DRV_UnrealizePalette, /* pUnrealizePalette */ NULL, /* pWidenPath */ X11DRV_wine_get_wgl_driver, /* wine_get_wgl_driver */ + NULL, /* wine_get_vulkan_driver */ GDI_PRIORITY_GRAPHICS_DRV /* priority */ };
diff --git a/dlls/winex11.drv/xrender.c b/dlls/winex11.drv/xrender.c index b9b7c4f325..4d04741435 100644 --- a/dlls/winex11.drv/xrender.c +++ b/dlls/winex11.drv/xrender.c @@ -2284,6 +2284,7 @@ static const struct gdi_dc_funcs xrender_funcs = NULL, /* pUnrealizePalette */ NULL, /* pWidenPath */ NULL, /* wine_get_wgl_driver */ + NULL, /* wine_get_vulkan_driver */ GDI_PRIORITY_GRAPHICS_DRV + 10 /* priority */ };
diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index 32d17f7dce..4693235cae 100644 --- a/include/wine/gdi_driver.h +++ b/include/wine/gdi_driver.h @@ -25,6 +25,7 @@
struct gdi_dc_funcs; struct opengl_funcs; +struct vulkan_funcs;
typedef struct gdi_physdev { @@ -191,13 +192,14 @@ struct gdi_dc_funcs BOOL (*pUnrealizePalette)(HPALETTE); BOOL (*pWidenPath)(PHYSDEV); struct opengl_funcs * (*wine_get_wgl_driver)(PHYSDEV,UINT); + const struct vulkan_funcs * (*wine_get_vulkan_driver)(PHYSDEV,UINT);
/* priority order for the driver on the stack */ UINT priority; };
/* increment this when you change the DC function table */ -#define WINE_GDI_DRIVER_VERSION 47 +#define WINE_GDI_DRIVER_VERSION 48
#define GDI_PRIORITY_NULL_DRV 0 /* null driver */ #define GDI_PRIORITY_FONT_DRV 100 /* any font driver */ @@ -280,5 +282,6 @@ extern void CDECL __wine_set_visible_region( HDC hdc, HRGN hrgn, const RECT *vis const RECT *device_rect, struct window_surface *surface ); extern void CDECL __wine_set_display_driver( HMODULE module ); extern struct opengl_funcs * CDECL __wine_get_wgl_driver( HDC hdc, UINT version ); +extern const struct vulkan_funcs * CDECL __wine_get_vulkan_driver( HDC hdc, UINT version );
#endif /* __WINE_WINE_GDI_DRIVER_H */ diff --git a/include/wine/vulkan_driver.h b/include/wine/vulkan_driver.h new file mode 100644 index 0000000000..568a2128c3 --- /dev/null +++ b/include/wine/vulkan_driver.h @@ -0,0 +1,23 @@ +/* Automatically generated from Vulkan vk.xml; DO NOT EDIT! */ + +#ifndef __WINE_VULKAN_DRIVER_H +#define __WINE_VULKAN_DRIVER_H + +/* Wine internal vulkan driver version, needs to be bumped upon vulkan_funcs changes. */ +#define WINE_VULKAN_DRIVER_VERSION 1 + +struct vulkan_funcs +{ + /* Vulkan global functions. This are the only calls at this point a graphics driver + * needs to provide. Other function calls will be provided indirectly by dispatch + * tables part of dispatchable Vulkan objects such as VkInstance or vkDevice. + */ + VkResult (*p_vkCreateInstance)(const VkInstanceCreateInfo *, const VkAllocationCallbacks *, VkInstance *); + void (*p_vkDestroyInstance)(VkInstance, const VkAllocationCallbacks *); + VkResult (*p_vkEnumerateInstanceExtensionProperties)(const char *, uint32_t *, VkExtensionProperties *); + void * (*p_vkGetInstanceProcAddr)(VkInstance, const char *); +}; + +extern const struct vulkan_funcs * CDECL __wine_get_vulkan_driver(HDC hdc, UINT version); + +#endif /* __WINE_VULKAN_DRIVER_H */