[PATCH v2] winevulkan: Implement VK_EXT_debug_report.

Liam Middlebrook lmiddlebrook at nvidia.com
Wed Oct 28 18:24:23 CDT 2020


Signed-off-by: Liam Middlebrook <lmiddlebrook at nvidia.com>

On 10/27/20 1:18 PM, Georg Lehmann wrote:
> Messages from the driver/layers won't be reported twice.
> Messages during instance creation by the host loader won't be reported,
> since the information is partly wrong and the windows loader reports the
> correct information.
> Other messages by the loader will be reported twice if lunarg's vulkan-1.dll
> is used. This shouldn't be a problem because the messages are just used
> for logging/debugging.
> 
> Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49813
> 
> Needed for Quake2RTX.
> 
> Signed-off-by: Georg Lehmann <dadschoorse at 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 a07c1d77bf5..7e5bd030867 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.
> @@ -234,6 +229,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 = [
> @@ -955,6 +955,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;
>   
> 



More information about the wine-devel mailing list