Needed for Quake2RTX.
Signed-off-by: Georg Lehmann <dadschoorse(a)gmail.com>
---
dlls/winevulkan/make_vulkan | 14 +++--
dlls/winevulkan/vulkan.c | 105 ++++++++++++++++++++++++++++++-
dlls/winevulkan/vulkan_private.h | 26 ++++++++
3 files changed, 138 insertions(+), 7 deletions(-)
diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan
index f3f2da7548c..5304a139bae 100755
--- a/dlls/winevulkan/make_vulkan
+++ b/dlls/winevulkan/make_vulkan
@@ -86,12 +86,7 @@ EXT_BLOCK_SIZE = 1000
UNSUPPORTED_EXTENSIONS = [
# Instance extensions
- "VK_EXT_debug_report",
- # Handling of VK_EXT_debug_report requires some consideration. The win32
- # loader already provides it for us and it is somewhat usable. If we add
- # plumbing down to the native layer, we will get each message twice as we
- # use 2 loaders (win32+native), but we may get output from the driver.
- # In any case callback conversion is required.
+ "VK_EXT_debug_marker", # Needs handle unwrapping
"VK_EXT_validation_features",
"VK_EXT_validation_flags",
"VK_KHR_display", # Needs WSI work.
@@ -231,6 +226,11 @@ FUNCTION_OVERRIDES = {
"vkSubmitDebugUtilsMessageEXT" : {"dispatch": True, "driver" : False, "thunk" : True, "private_thunk" : True},
"vkSetDebugUtilsObjectTagEXT" : {"dispatch": True, "driver" : False, "thunk" : True, "private_thunk" : True},
"vkSetDebugUtilsObjectNameEXT" : {"dispatch": True, "driver" : False, "thunk" : True, "private_thunk" : True},
+
+ # VK_EXT_debug_report
+ "vkCreateDebugReportCallbackEXT" : {"dispatch": True, "driver" : False, "thunk" : False},
+ "vkDestroyDebugReportCallbackEXT" : {"dispatch": True, "driver" : False, "thunk" : False},
+ "vkDebugReportMessageEXT" : {"dispatch": True, "driver" : False, "thunk" : False},
}
STRUCT_CHAIN_CONVERSIONS = [
@@ -952,6 +952,8 @@ class VkHandle(object):
return "wine_cmd_pool_from_handle({0})->command_pool".format(name)
if self.name == "VkDebugUtilsMessengerEXT":
return "wine_debug_utils_messenger_from_handle({0})->debug_messenger".format(name)
+ if self.name == "VkDebugReportCallbackEXT":
+ return "wine_debug_report_callback_from_handle({0})->debug_callback".format(name)
native_handle_name = None
diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c
index 92c26be1fc0..d486f43e66c 100644
--- a/dlls/winevulkan/vulkan.c
+++ b/dlls/winevulkan/vulkan.c
@@ -190,6 +190,30 @@ static VkBool32 debug_utils_callback_conversion(VkDebugUtilsMessageSeverityFlagB
return result;
}
+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_debug_report_callback *object;
+
+ 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);
+
+ object = user_data;
+
+ if (!object->instance->instance)
+ {
+ /* instance wasn't yet created, this is a message from the native loader */
+ 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;
+
+ return object->user_callback(
+ flags, object_type, object_handle, location, code, layer_prefix, message, object->user_data);
+}
+
static void wine_vk_physical_device_free(struct VkPhysicalDevice_T *phys_dev)
{
if (!phys_dev)
@@ -471,6 +495,7 @@ static VkResult wine_vk_instance_convert_create_info(const VkInstanceCreateInfo
VkInstanceCreateInfo *dst, struct VkInstance_T *object)
{
VkDebugUtilsMessengerCreateInfoEXT *debug_utils_messenger;
+ VkDebugReportCallbackCreateInfoEXT *debug_report_callback;
VkBaseInStructure *header;
unsigned int i;
VkResult res;
@@ -503,6 +528,18 @@ static VkResult wine_vk_instance_convert_create_info(const VkInstanceCreateInfo
debug_utils_messenger->pUserData = &object->utils_messengers[i];
}
+ debug_report_callback = wine_vk_find_struct(header->pNext, DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT);
+ if (debug_report_callback)
+ {
+ object->default_callback.instance = object;
+ object->default_callback.debug_callback = VK_NULL_HANDLE;
+ object->default_callback.user_callback = debug_report_callback->pfnCallback;
+ object->default_callback.user_data = debug_report_callback->pUserData;
+
+ debug_report_callback->pfnCallback = (void *) &debug_report_callback_conversion;
+ debug_report_callback->pUserData = &object->default_callback;
+ }
+
/* ICDs don't support any layers, so nothing to copy. Modern versions of the loader
* filter this data out as well.
*/
@@ -526,7 +563,7 @@ static VkResult wine_vk_instance_convert_create_info(const VkInstanceCreateInfo
free_VkInstanceCreateInfo_struct_chain(dst);
return VK_ERROR_EXTENSION_NOT_PRESENT;
}
- if (!strcmp(extension_name, "VK_EXT_debug_utils"))
+ if (!strcmp(extension_name, "VK_EXT_debug_utils") || !strcmp(extension_name, "VK_EXT_debug_report"))
{
object->enable_wrapper_list = VK_TRUE;
}
@@ -1880,6 +1917,72 @@ VkResult WINAPI wine_vkSetDebugUtilsObjectNameEXT(VkDevice device, const VkDebug
return thunk_vkSetDebugUtilsObjectNameEXT(device, &wine_name_info);
}
+VkResult WINAPI wine_vkCreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *create_info,
+ const VkAllocationCallbacks *allocator, VkDebugReportCallbackEXT *callback)
+{
+ VkDebugReportCallbackCreateInfoEXT wine_create_info;
+ struct wine_debug_report_callback *object;
+ VkResult res;
+
+ TRACE("%p, %p, %p, %p\n", instance, create_info, allocator, callback);
+
+ if (allocator)
+ FIXME("Support for allocation callbacks not implemented yet\n");
+
+ if (!(object = heap_alloc_zero(sizeof(*object))))
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+
+ object->instance = instance;
+ object->user_callback = create_info->pfnCallback;
+ object->user_data = create_info->pUserData;
+
+ wine_create_info = *create_info;
+
+ wine_create_info.pfnCallback = (void *) debug_report_callback_conversion;
+ wine_create_info.pUserData = object;
+
+ res = instance->funcs.p_vkCreateDebugReportCallbackEXT(instance->instance, &wine_create_info, NULL, &object->debug_callback);
+
+ if (res != VK_SUCCESS)
+ {
+ heap_free(object);
+ return res;
+ }
+
+ WINE_VK_ADD_NON_DISPATCHABLE_MAPPING(instance, object, object->debug_callback);
+ *callback = wine_debug_report_callback_to_handle(object);
+
+ return VK_SUCCESS;
+}
+
+void WINAPI wine_vkDestroyDebugReportCallbackEXT(
+ VkInstance instance, VkDebugReportCallbackEXT callback, const VkAllocationCallbacks *allocator)
+{
+ struct wine_debug_report_callback *object;
+
+ TRACE("%p, 0x%s, %p\n", instance, wine_dbgstr_longlong(callback), allocator);
+
+ object = wine_debug_report_callback_from_handle(callback);
+
+ instance->funcs.p_vkDestroyDebugReportCallbackEXT(instance->instance, object->debug_callback, NULL);
+
+ WINE_VK_REMOVE_HANDLE_MAPPING(instance, object);
+
+ heap_free(object);
+}
+
+void WINAPI wine_vkDebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT object_type,
+ uint64_t object, size_t location, int32_t code, const char *layer_prefix, const char *message)
+{
+ TRACE("%p, %#x, %#x, 0x%s, 0x%s, %d, %p, %p\n", instance, flags, object_type, wine_dbgstr_longlong(object),
+ wine_dbgstr_longlong(location), code, layer_prefix, message);
+
+ object = wine_vk_unwrap_handle(object_type, object);
+
+ instance->funcs.p_vkDebugReportMessageEXT(
+ instance->instance, flags, object_type, object, location, code, layer_prefix, message);
+}
+
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, void *reserved)
{
TRACE("%p, %u, %p\n", hinst, reason, reserved);
diff --git a/dlls/winevulkan/vulkan_private.h b/dlls/winevulkan/vulkan_private.h
index eec0ef595d0..92c04543587 100644
--- a/dlls/winevulkan/vulkan_private.h
+++ b/dlls/winevulkan/vulkan_private.h
@@ -97,6 +97,18 @@ struct VkDevice_T
struct wine_debug_utils_messenger;
+struct wine_debug_report_callback
+{
+ struct VkInstance_T *instance; /* parent */
+ VkDebugReportCallbackEXT debug_callback; /* native callback object */
+
+ /* application callback + data */
+ PFN_vkDebugReportCallbackEXT user_callback;
+ void *user_data;
+
+ struct wine_vk_mapping mapping;
+};
+
struct VkInstance_T
{
struct wine_vk_base base;
@@ -116,6 +128,8 @@ struct VkInstance_T
struct wine_debug_utils_messenger *utils_messengers;
uint32_t utils_messenger_count;
+ struct wine_debug_report_callback default_callback;
+
unsigned int quirks;
struct wine_vk_mapping mapping;
@@ -187,6 +201,18 @@ static inline VkDebugUtilsMessengerEXT wine_debug_utils_messenger_to_handle(
return (VkDebugUtilsMessengerEXT)(uintptr_t)debug_messenger;
}
+static inline struct wine_debug_report_callback *wine_debug_report_callback_from_handle(
+ VkDebugReportCallbackEXT handle)
+{
+ return (struct wine_debug_report_callback *)(uintptr_t)handle;
+}
+
+static inline VkDebugReportCallbackEXT wine_debug_report_callback_to_handle(
+ struct wine_debug_report_callback *debug_messenger)
+{
+ return (VkDebugReportCallbackEXT)(uintptr_t)debug_messenger;
+}
+
void *wine_vk_get_device_proc_addr(const char *name) DECLSPEC_HIDDEN;
void *wine_vk_get_instance_proc_addr(const char *name) DECLSPEC_HIDDEN;
--
2.28.0