Browse Source

Merge pull request #43112 from akien-mga/vulkan-loader-readd-windows-patch

vulkan: Re-add Windows patch to fix static library use
Rémi Verschelde 4 năm trước cách đây
mục cha
commit
c94ae3cf84

+ 1 - 1
thirdparty/vulkan/loader/loader.c

@@ -7849,7 +7849,7 @@ out:
     return result;
 }
 
-#if defined(_WIN32)
+#if defined(_WIN32) && defined(LOADER_DYNAMIC_LIB)
 BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved) {
     switch (reason) {
         case DLL_PROCESS_ATTACH:

+ 3 - 0
thirdparty/vulkan/loader/loader.h

@@ -428,6 +428,9 @@ static inline void loader_init_dispatch(void *obj, const void *data) {
 // Global variables used across files
 extern struct loader_struct loader;
 extern THREAD_LOCAL_DECL struct loader_instance *tls_instance;
+#if defined(_WIN32) && !defined(LOADER_DYNAMIC_LIB)
+extern LOADER_PLATFORM_THREAD_ONCE_DEFINITION(once_init);
+#endif
 extern loader_platform_thread_mutex loader_lock;
 extern loader_platform_thread_mutex loader_json_lock;
 extern loader_platform_thread_mutex loader_preload_icd_lock;

+ 16 - 0
thirdparty/vulkan/loader/vk_loader_platform.h

@@ -368,9 +368,25 @@ typedef HANDLE loader_platform_thread;
 // The once init functionality is not used when building a DLL on Windows. This is because there is no way to clean up the
 // resources allocated by anything allocated by once init. This isn't a problem for static libraries, but it is for dynamic
 // ones. When building a DLL, we use DllMain() instead to allow properly cleaning up resources.
+#if defined(LOADER_DYNAMIC_LIB)
 #define LOADER_PLATFORM_THREAD_ONCE_DECLARATION(var)
 #define LOADER_PLATFORM_THREAD_ONCE_DEFINITION(var)
 #define LOADER_PLATFORM_THREAD_ONCE(ctl, func)
+#else
+#define LOADER_PLATFORM_THREAD_ONCE_DECLARATION(var) INIT_ONCE var = INIT_ONCE_STATIC_INIT;
+#define LOADER_PLATFORM_THREAD_ONCE_DEFINITION(var) INIT_ONCE var;
+#define LOADER_PLATFORM_THREAD_ONCE(ctl, func) loader_platform_thread_once_fn(ctl, func)
+static BOOL CALLBACK InitFuncWrapper(PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context) {
+    void (*func)(void) = (void (*)(void))Parameter;
+    func();
+    return TRUE;
+}
+static void loader_platform_thread_once_fn(void *ctl, void (*func)(void)) {
+    assert(func != NULL);
+    assert(ctl != NULL);
+    InitOnceExecuteOnce((PINIT_ONCE)ctl, InitFuncWrapper, (void *)func, NULL);
+}
+#endif
 
 // Thread IDs:
 typedef DWORD loader_platform_thread_id;

+ 57 - 0
thirdparty/vulkan/patches/Vulkan-Loader-revert-pr260.patch

@@ -0,0 +1,57 @@
+diff --git a/thirdparty/vulkan/loader/loader.c b/thirdparty/vulkan/loader/loader.c
+index 87d08d5116..c7cdb47122 100644
+--- a/thirdparty/vulkan/loader/loader.c
++++ b/thirdparty/vulkan/loader/loader.c
+@@ -7330,7 +7330,7 @@ out:
+     return result;
+ }
+ 
+-#if defined(_WIN32)
++#if defined(_WIN32) && defined(LOADER_DYNAMIC_LIB)
+ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved) {
+     switch (reason) {
+         case DLL_PROCESS_ATTACH:
+diff --git a/thirdparty/vulkan/loader/loader.h b/thirdparty/vulkan/loader/loader.h
+index 5e9495521b..56745a968d 100644
+--- a/thirdparty/vulkan/loader/loader.h
++++ b/thirdparty/vulkan/loader/loader.h
+@@ -420,6 +420,9 @@ static inline void loader_init_dispatch(void *obj, const void *data) {
+ // Global variables used across files
+ extern struct loader_struct loader;
+ extern THREAD_LOCAL_DECL struct loader_instance *tls_instance;
++#if defined(_WIN32) && !defined(LOADER_DYNAMIC_LIB)
++extern LOADER_PLATFORM_THREAD_ONCE_DEFINITION(once_init);
++#endif
+ extern loader_platform_thread_mutex loader_lock;
+ extern loader_platform_thread_mutex loader_json_lock;
+ 
+diff --git a/thirdparty/vulkan/loader/vk_loader_platform.h b/thirdparty/vulkan/loader/vk_loader_platform.h
+index 7824e35d6b..62e8e3ae09 100644
+--- a/thirdparty/vulkan/loader/vk_loader_platform.h
++++ b/thirdparty/vulkan/loader/vk_loader_platform.h
+@@ -330,9 +330,25 @@ typedef HANDLE loader_platform_thread;
+ // The once init functionality is not used when building a DLL on Windows. This is because there is no way to clean up the
+ // resources allocated by anything allocated by once init. This isn't a problem for static libraries, but it is for dynamic
+ // ones. When building a DLL, we use DllMain() instead to allow properly cleaning up resources.
++#if defined(LOADER_DYNAMIC_LIB)
+ #define LOADER_PLATFORM_THREAD_ONCE_DECLARATION(var)
+ #define LOADER_PLATFORM_THREAD_ONCE_DEFINITION(var)
+ #define LOADER_PLATFORM_THREAD_ONCE(ctl, func)
++#else
++#define LOADER_PLATFORM_THREAD_ONCE_DECLARATION(var) INIT_ONCE var = INIT_ONCE_STATIC_INIT;
++#define LOADER_PLATFORM_THREAD_ONCE_DEFINITION(var) INIT_ONCE var;
++#define LOADER_PLATFORM_THREAD_ONCE(ctl, func) loader_platform_thread_once_fn(ctl, func)
++static BOOL CALLBACK InitFuncWrapper(PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context) {
++    void (*func)(void) = (void (*)(void))Parameter;
++    func();
++    return TRUE;
++}
++static void loader_platform_thread_once_fn(void *ctl, void (*func)(void)) {
++    assert(func != NULL);
++    assert(ctl != NULL);
++    InitOnceExecuteOnce((PINIT_ONCE)ctl, InitFuncWrapper, (void *)func, NULL);
++}
++#endif
+ 
+ // Thread IDs:
+ typedef DWORD loader_platform_thread_id;