The first patch is needed due to the way unixlibs are loaded. We require imported unixlibs to be loaded first by other means and loading user32 as a result of winevulkan PE import is too late. It's not a problem with native vulkan loader, because it statically links to user32 (and ICDs are loaded later). This patch mimics that behavior in our vulkan-1.dll.
From: Jacek Caban jacek@codeweavers.com
--- dlls/vulkan-1/Makefile.in | 5 ++++- dlls/vulkan-1/vulkan.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 dlls/vulkan-1/vulkan.c
diff --git a/dlls/vulkan-1/Makefile.in b/dlls/vulkan-1/Makefile.in index a4a10bc8e93..9c4dca9a880 100644 --- a/dlls/vulkan-1/Makefile.in +++ b/dlls/vulkan-1/Makefile.in @@ -1,7 +1,10 @@ MODULE = vulkan-1.dll -IMPORTS = winevulkan +IMPORTS = user32 IMPORTLIB = vulkan-1
EXTRADLLFLAGS = -Wb,--prefer-native
RC_SRCS = version.rc + +C_SRCS = \ + vulkan.c diff --git a/dlls/vulkan-1/vulkan.c b/dlls/vulkan-1/vulkan.c new file mode 100644 index 00000000000..ab40260d9bd --- /dev/null +++ b/dlls/vulkan-1/vulkan.c @@ -0,0 +1,30 @@ +/* + * Copyright 2022 Jacek Caban for CodeWeavers + * + * 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 <windows.h> +#include "wine/debug.h" + + +BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, void *reserved) +{ + if (reason != DLL_PROCESS_ATTACH) return TRUE; + + DisableThreadLibraryCalls(hinst); + GetDpiForSystem(); /* make sure that user32 is loaded */ + return TRUE; +}
From: Jacek Caban jacek@codeweavers.com
--- dlls/winevulkan/Makefile.in | 2 +- dlls/winevulkan/loader.c | 15 +-------------- dlls/winevulkan/vulkan.c | 9 ++++++++- 3 files changed, 10 insertions(+), 16 deletions(-)
diff --git a/dlls/winevulkan/Makefile.in b/dlls/winevulkan/Makefile.in index 360fb77a6eb..732bf5493a9 100644 --- a/dlls/winevulkan/Makefile.in +++ b/dlls/winevulkan/Makefile.in @@ -2,7 +2,7 @@ MODULE = winevulkan.dll UNIXLIB = winevulkan.so IMPORTLIB = winevulkan IMPORTS = user32 gdi32 advapi32 setupapi win32u -UNIX_LIBS = $(PTHREAD_LIBS) +UNIX_LIBS = -lwin32u $(PTHREAD_LIBS)
C_SRCS = \ loader.c \ diff --git a/dlls/winevulkan/loader.c b/dlls/winevulkan/loader.c index 61c583d5c13..3be43432504 100644 --- a/dlls/winevulkan/loader.c +++ b/dlls/winevulkan/loader.c @@ -215,24 +215,11 @@ VkResult WINAPI vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t *supported_ver
static BOOL WINAPI wine_vk_init(INIT_ONCE *once, void *param, void **context) { - const void *driver; - - driver = __wine_get_vulkan_driver(WINE_VULKAN_DRIVER_VERSION); - if (!driver) - { - ERR("Failed to load Wine graphics driver supporting Vulkan.\n"); - return FALSE; - } - if (NtQueryVirtualMemory(GetCurrentProcess(), hinstance, MemoryWineUnixFuncs, &unix_handle, sizeof(unix_handle), NULL)) return FALSE;
- if (vk_unix_call(unix_init, &driver) || !driver) - return FALSE; - - unix_funcs = driver; - return TRUE; + return !vk_unix_call(unix_init, &unix_funcs); }
static BOOL wine_vk_init_once(void) diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c index 190f70f3616..071dbd4cdff 100644 --- a/dlls/winevulkan/vulkan.c +++ b/dlls/winevulkan/vulkan.c @@ -436,7 +436,14 @@ static void wine_vk_device_free(struct VkDevice_T *device)
NTSTATUS init_vulkan(void *args) { - vk_funcs = *(const struct vulkan_funcs **)args; + vk_funcs = __wine_get_vulkan_driver(WINE_VULKAN_DRIVER_VERSION); + if (!vk_funcs) + { + ERR("Failed to load Wine graphics driver supporting Vulkan.\n"); + return STATUS_UNSUCCESSFUL; + } + + *(const struct unix_funcs **)args = &loader_funcs; return STATUS_SUCCESS; }
From: Jacek Caban jacek@codeweavers.com
--- dlls/winevulkan/make_vulkan | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan index d93d8958214..5dd5fbcf578 100755 --- a/dlls/winevulkan/make_vulkan +++ b/dlls/winevulkan/make_vulkan @@ -147,12 +147,8 @@ ALLOWED_X_EXTENSIONS = [ "VK_NVX_image_view_handle", ]
-# We can't use syscall interface for functions that may call display drivers -# until drivers are converted to pure Unix libraries. Also some frequently -# called functions use direct calls for performance reasons. +# Some frequently called functions use direct calls for performance reasons. DIRECT_CALL_FUNCTIONS = [ - "vkCreateDevice", - "vkEnumerateInstanceVersion", "vkUpdateDescriptorSets", "vkUpdateDescriptorSetWithTemplate", ] @@ -691,7 +687,7 @@ class VkFunction(object): # vkCmd* functions are frequently called, use direct calls for performance if self.name.startswith("vkCmd"): return True - return self.is_driver_func() or self.name in DIRECT_CALL_FUNCTIONS + return self.name in DIRECT_CALL_FUNCTIONS
def pfn(self, prefix="p", call_conv=None, conv=False): """ Create function pointer. """
From: Jacek Caban jacek@codeweavers.com
--- dlls/win32u/gdiobj.c | 1 - dlls/win32u/vulkan.c | 8 +++++--- dlls/win32u/win32u.spec | 3 --- dlls/win32u/win32u_private.h | 1 - dlls/win32u/wrappers.c | 6 ------ dlls/winevulkan/make_vulkan | 4 ++-- dlls/winevulkan/vulkan.c | 2 +- dlls/winevulkan/vulkan_loader.h | 1 - include/wine/gdi_driver.h | 1 - include/wine/vulkan_driver.h | 4 ++-- 10 files changed, 10 insertions(+), 21 deletions(-)
diff --git a/dlls/win32u/gdiobj.c b/dlls/win32u/gdiobj.c index cb5297c5676..aaeed2ba676 100644 --- a/dlls/win32u/gdiobj.c +++ b/dlls/win32u/gdiobj.c @@ -1149,7 +1149,6 @@ static struct unix_funcs unix_funcs = __wine_get_brush_bitmap_info, __wine_get_file_outline_text_metric, __wine_get_icm_profile, - __wine_get_vulkan_driver, __wine_get_wgl_driver, __wine_send_input, }; diff --git a/dlls/win32u/vulkan.c b/dlls/win32u/vulkan.c index 8f85f4e4632..c66be5bc7ed 100644 --- a/dlls/win32u/vulkan.c +++ b/dlls/win32u/vulkan.c @@ -22,12 +22,14 @@ #pragma makedep unix #endif
-#include "ntgdi_private.h" +#include "win32u_private.h" +#include "wine/vulkan.h" +#include "wine/vulkan_driver.h"
/*********************************************************************** - * __wine_get_vulkan_driver (win32u.@) + * __wine_get_vulkan_driver (win32u.so) */ -const struct vulkan_funcs * CDECL __wine_get_vulkan_driver( UINT version ) +const struct vulkan_funcs *__wine_get_vulkan_driver( UINT version ) { return user_driver->pwine_get_vulkan_driver( version ); } diff --git a/dlls/win32u/win32u.spec b/dlls/win32u/win32u.spec index 979fa8475b2..3054bed8347 100644 --- a/dlls/win32u/win32u.spec +++ b/dlls/win32u/win32u.spec @@ -1326,9 +1326,6 @@ # OpenGL @ cdecl __wine_get_wgl_driver(long long)
-# Vulkan -@ cdecl __wine_get_vulkan_driver(long) - # gdi32 @ stdcall SetDIBits(long long long long ptr ptr long) @ cdecl __wine_get_brush_bitmap_info(long ptr ptr ptr) diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index d8509c83445..6e9a1926891 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -207,7 +207,6 @@ struct unix_funcs BOOL (CDECL *get_brush_bitmap_info)( HBRUSH handle, BITMAPINFO *info, void *bits, UINT *usage ); BOOL (CDECL *get_file_outline_text_metric)( const WCHAR *path, OUTLINETEXTMETRICW *otm ); BOOL (CDECL *get_icm_profile)( HDC hdc, BOOL allow_default, DWORD *size, WCHAR *filename ); - const struct vulkan_funcs * (CDECL *get_vulkan_driver)( UINT version ); struct opengl_funcs * (CDECL *get_wgl_driver)( HDC hdc, UINT version ); BOOL (CDECL *wine_send_input)( HWND hwnd, const INPUT *input, const RAWINPUT *rawinput ); }; diff --git a/dlls/win32u/wrappers.c b/dlls/win32u/wrappers.c index f331039714e..c5078c8a7f7 100644 --- a/dlls/win32u/wrappers.c +++ b/dlls/win32u/wrappers.c @@ -798,12 +798,6 @@ BOOL CDECL __wine_get_file_outline_text_metric( const WCHAR *path, OUTLINETEXTME return unix_funcs->get_file_outline_text_metric( path, otm ); }
-const struct vulkan_funcs * CDECL __wine_get_vulkan_driver(UINT version) -{ - if (!unix_funcs) return NULL; - return unix_funcs->get_vulkan_driver( version ); -} - struct opengl_funcs * CDECL __wine_get_wgl_driver( HDC hdc, UINT version ) { if (!unix_funcs) return NULL; diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan index 5dd5fbcf578..2eeff42c56e 100755 --- a/dlls/winevulkan/make_vulkan +++ b/dlls/winevulkan/make_vulkan @@ -156,7 +156,7 @@ DIRECT_CALL_FUNCTIONS = [ # Functions part of our winevulkan graphics driver interface. # DRIVER_VERSION should be bumped on any change to driver interface # in FUNCTION_OVERRIDES -DRIVER_VERSION = 10 +DRIVER_VERSION = 11
class ThunkType(Enum): NONE = 1 @@ -3202,7 +3202,7 @@ class VkGenerator(object): f.write(" VkSurfaceKHR (*p_wine_get_native_surface)(VkSurfaceKHR);\n") f.write("};\n\n")
- f.write("extern const struct vulkan_funcs * CDECL __wine_get_vulkan_driver(UINT version);\n\n") + f.write("extern const struct vulkan_funcs * __wine_get_vulkan_driver(UINT version);\n\n")
f.write("static inline void *get_vulkan_driver_device_proc_addr(\n") f.write(" const struct vulkan_funcs *vulkan_funcs, const char *name)\n{\n") diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c index 071dbd4cdff..da89cdd5ba2 100644 --- a/dlls/winevulkan/vulkan.c +++ b/dlls/winevulkan/vulkan.c @@ -26,7 +26,7 @@ #include <stdlib.h>
#include "vulkan_private.h" -#include "winreg.h" +#include "wine/vulkan_driver.h" #include "ntuser.h"
WINE_DEFAULT_DEBUG_CHANNEL(vulkan); diff --git a/dlls/winevulkan/vulkan_loader.h b/dlls/winevulkan/vulkan_loader.h index 2efa56e0193..3ba945dbfcc 100644 --- a/dlls/winevulkan/vulkan_loader.h +++ b/dlls/winevulkan/vulkan_loader.h @@ -28,7 +28,6 @@ #include "winternl.h" #include "wine/debug.h" #include "wine/vulkan.h" -#include "wine/vulkan_driver.h" #include "wine/unixlib.h"
#include "loader_thunks.h" diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index 77ccc431e51..9adeac63704 100644 --- a/include/wine/gdi_driver.h +++ b/include/wine/gdi_driver.h @@ -338,6 +338,5 @@ extern void __wine_set_user_driver( const struct user_driver_funcs *funcs, UINT #endif /* WINE_UNIX_LIB */
extern struct opengl_funcs * CDECL __wine_get_wgl_driver( HDC hdc, UINT version ); -extern const struct vulkan_funcs * CDECL __wine_get_vulkan_driver( UINT version );
#endif /* __WINE_WINE_GDI_DRIVER_H */ diff --git a/include/wine/vulkan_driver.h b/include/wine/vulkan_driver.h index 110716e3160..f5269d554fb 100644 --- a/include/wine/vulkan_driver.h +++ b/include/wine/vulkan_driver.h @@ -13,7 +13,7 @@ #define __WINE_VULKAN_DRIVER_H
/* Wine internal vulkan driver version, needs to be bumped upon vulkan_funcs changes. */ -#define WINE_VULKAN_DRIVER_VERSION 10 +#define WINE_VULKAN_DRIVER_VERSION 11
struct vulkan_funcs { @@ -46,7 +46,7 @@ struct vulkan_funcs VkSurfaceKHR (*p_wine_get_native_surface)(VkSurfaceKHR); };
-extern const struct vulkan_funcs * CDECL __wine_get_vulkan_driver(UINT version); +extern const struct vulkan_funcs * __wine_get_vulkan_driver(UINT version);
static inline void *get_vulkan_driver_device_proc_addr( const struct vulkan_funcs *vulkan_funcs, const char *name)
This merge request was approved by Huw Davies.