diff --git a/dlls/user32/user_main.c b/dlls/user32/user_main.c index e489bcda17a..78bc1fddfc2 100644 --- a/dlls/user32/user_main.c +++ b/dlls/user32/user_main.c @@ -214,7 +214,7 @@ static void dpiaware_init(void) } -static const void *kernel_callback_table[] = +static const void *kernel_callback_table[NtUserCallCount] = { User32CallEnumDisplayMonitor, }; diff --git a/dlls/winevulkan/loader.c b/dlls/winevulkan/loader.c index bea60b07245..534e6646c3a 100644 --- a/dlls/winevulkan/loader.c +++ b/dlls/winevulkan/loader.c @@ -19,7 +19,7 @@ #include "vulkan_loader.h" #include "winreg.h" -#include "winuser.h" +#include "ntuser.h" #include "initguid.h" #include "devguid.h" #include "setupapi.h" @@ -373,8 +373,21 @@ void WINAPI vkGetPhysicalDeviceProperties2KHR(VkPhysicalDevice phys_dev, fill_luid_property(properties2); } +static BOOL WINAPI call_vulkan_debug_report_callback( struct wine_vk_debug_report_params *params, ULONG size ) +{ + return params->user_callback(params->flags, params->object_type, params->object_handle, params->location, + params->code, params->layer_prefix, params->message, params->user_data); +} + +static BOOL WINAPI call_vulkan_debug_utils_callback( struct wine_vk_debug_utils_params *params, ULONG size ) +{ + return params->user_callback(params->severity, params->message_types, ¶ms->data, params->user_data); +} + BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, void *reserved) { + void **kernel_callback_table; + TRACE("%p, %u, %p\n", hinst, reason, reserved); switch (reason) @@ -382,6 +395,10 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, void *reserved) case DLL_PROCESS_ATTACH: hinstance = hinst; DisableThreadLibraryCalls(hinst); + + kernel_callback_table = NtCurrentTeb()->Peb->KernelCallbackTable; + kernel_callback_table[NtUserCallVulkanDebugReportCallback] = call_vulkan_debug_report_callback; + kernel_callback_table[NtUserCallVulkanDebugUtilsCallback] = call_vulkan_debug_utils_callback; break; } return TRUE; diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c index e57f8efef99..84146d4287b 100644 --- a/dlls/winevulkan/vulkan.c +++ b/dlls/winevulkan/vulkan.c @@ -27,8 +27,7 @@ #include "vulkan_private.h" #include "winreg.h" -#include "winuser.h" -#include "winternl.h" +#include "ntuser.h" WINE_DEFAULT_DEBUG_CHANNEL(vulkan); @@ -115,9 +114,11 @@ static VkBool32 debug_utils_callback_conversion(VkDebugUtilsMessageSeverityFlagB const VkDebugUtilsMessengerCallbackDataEXT_host *callback_data, void *user_data) { - struct VkDebugUtilsMessengerCallbackDataEXT wine_callback_data; + struct wine_vk_debug_utils_params params; VkDebugUtilsObjectNameInfoEXT *object_name_infos; struct wine_debug_utils_messenger *object; + void *ret_ptr; + ULONG ret_len; VkBool32 result; unsigned int i; @@ -131,11 +132,16 @@ static VkBool32 debug_utils_callback_conversion(VkDebugUtilsMessageSeverityFlagB return VK_FALSE; } - wine_callback_data = *((VkDebugUtilsMessengerCallbackDataEXT *) callback_data); + /* FIXME: we should pack all referenced structs instead of passing pointers */ + params.user_callback = object->user_callback; + params.user_data = object->user_data; + params.severity = severity; + params.message_types = message_types; + params.data = *((VkDebugUtilsMessengerCallbackDataEXT *) callback_data); - object_name_infos = calloc(wine_callback_data.objectCount, sizeof(*object_name_infos)); + object_name_infos = calloc(params.data.objectCount, sizeof(*object_name_infos)); - for (i = 0; i < wine_callback_data.objectCount; i++) + for (i = 0; i < params.data.objectCount; i++) { object_name_infos[i].sType = callback_data->pObjects[i].sType; object_name_infos[i].pNext = callback_data->pObjects[i].pNext; @@ -158,10 +164,11 @@ static VkBool32 debug_utils_callback_conversion(VkDebugUtilsMessageSeverityFlagB } } - wine_callback_data.pObjects = object_name_infos; + params.data.pObjects = object_name_infos; /* applications should always return VK_FALSE */ - result = object->user_callback(severity, message_types, &wine_callback_data, object->user_data); + result = KeUserModeCallback( NtUserCallVulkanDebugUtilsCallback, ¶ms, sizeof(params), + &ret_ptr, &ret_len ); free(object_name_infos); @@ -171,7 +178,10 @@ static VkBool32 debug_utils_callback_conversion(VkDebugUtilsMessageSeverityFlagB static VkBool32 debug_report_callback_conversion(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT object_type, uint64_t object_handle, size_t location, int32_t code, const char *layer_prefix, const char *message, void *user_data) { + struct wine_vk_debug_report_params params; struct wine_debug_report_callback *object; + void *ret_ptr; + ULONG ret_len; TRACE("%#x, %#x, 0x%s, 0x%s, %d, %p, %p, %p\n", flags, object_type, wine_dbgstr_longlong(object_handle), wine_dbgstr_longlong(location), code, layer_prefix, message, user_data); @@ -184,12 +194,22 @@ static VkBool32 debug_report_callback_conversion(VkDebugReportFlagsEXT flags, Vk return VK_FALSE; } - object_handle = wine_vk_get_wrapper(object->instance, object_handle); - if (!object_handle) - object_type = VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT; + /* FIXME: we should pack all referenced structs instead of passing pointers */ + params.user_callback = object->user_callback; + params.user_data = object->user_data; + params.flags = flags; + params.object_type = object_type; + params.location = location; + params.code = code; + params.layer_prefix = layer_prefix; + params.message = message; - return object->user_callback( - flags, object_type, object_handle, location, code, layer_prefix, message, object->user_data); + params.object_handle = wine_vk_get_wrapper(object->instance, object_handle); + if (!params.object_handle) + params.object_type = VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT; + + return KeUserModeCallback( NtUserCallVulkanDebugReportCallback, ¶ms, sizeof(params), + &ret_ptr, &ret_len ); } static void wine_vk_physical_device_free(struct VkPhysicalDevice_T *phys_dev) diff --git a/dlls/winevulkan/vulkan_loader.h b/dlls/winevulkan/vulkan_loader.h index e636de934fd..b589ba3ba6b 100644 --- a/dlls/winevulkan/vulkan_loader.h +++ b/dlls/winevulkan/vulkan_loader.h @@ -69,6 +69,32 @@ void *wine_vk_get_device_proc_addr(const char *name) DECLSPEC_HIDDEN; void *wine_vk_get_phys_dev_proc_addr(const char *name) DECLSPEC_HIDDEN; void *wine_vk_get_instance_proc_addr(const char *name) DECLSPEC_HIDDEN; +/* debug callbacks params */ + +struct wine_vk_debug_utils_params +{ + PFN_vkDebugUtilsMessengerCallbackEXT user_callback; + void *user_data; + + VkDebugUtilsMessageSeverityFlagBitsEXT severity; + VkDebugUtilsMessageTypeFlagsEXT message_types; + VkDebugUtilsMessengerCallbackDataEXT data; +}; + +struct wine_vk_debug_report_params +{ + PFN_vkDebugReportCallbackEXT user_callback; + void *user_data; + + VkDebugReportFlagsEXT flags; + VkDebugReportObjectTypeEXT object_type; + uint64_t object_handle; + size_t location; + int32_t code; + const char *layer_prefix; + const char *message; +}; + extern const struct unix_funcs *unix_funcs; extern unixlib_handle_t unix_handle DECLSPEC_HIDDEN; diff --git a/include/ntuser.h b/include/ntuser.h index 9583b78acf2..25505e701b8 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -27,6 +27,9 @@ enum { NtUserCallEnumDisplayMonitor, + NtUserCallVulkanDebugReportCallback, + NtUserCallVulkanDebugUtilsCallback, + NtUserCallCount }; /* NtUserCallEnumDisplayMonitor params */