[PATCH v5 3/3] winevulkan: Implement VK_EXT_debug_utils.

Thomas Crider gloriouseggroll at gmail.com
Mon Oct 5 22:35:20 CDT 2020


Just a heads up, I was testing these patches and found they cause Horizon
Zero Dawn to crash on startup on nvidia. works fine on AMD/radv

On Tue, Sep 29, 2020 at 5:21 PM Liam Middlebrook <lmiddlebrook at nvidia.com>
wrote:

> This looks good to me, but given the requested changes to dependent
> patches 1/3 and 2/3, I'll wait to sign-off on this one.
>
>
> Thanks,
>
> Liam Middlebrook
>
> On 9/25/20 8:16 AM, Georg Lehmann wrote:
> > Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49813
> >
> > Signed-off-by: Georg Lehmann <dadschoorse at gmail.com>
> > ---
> >   dlls/winevulkan/make_vulkan      |   8 +-
> >   dlls/winevulkan/vulkan.c         | 183 +++++++++++++++++++++++++++++++
> >   dlls/winevulkan/vulkan_private.h |  31 ++++++
> >   3 files changed, 221 insertions(+), 1 deletion(-)
> >
> > diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan
> > index afea087a92..623d1b9cde 100755
> > --- a/dlls/winevulkan/make_vulkan
> > +++ b/dlls/winevulkan/make_vulkan
> > @@ -92,7 +92,6 @@ UNSUPPORTED_EXTENSIONS = [
> >       # 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_utils",
> >       "VK_EXT_validation_features",
> >       "VK_EXT_validation_flags",
> >       "VK_KHR_display", # Needs WSI work.
> > @@ -225,6 +224,11 @@ FUNCTION_OVERRIDES = {
> >       # VK_EXT_calibrated_timestamps
> >       "vkGetPhysicalDeviceCalibrateableTimeDomainsEXT" : {"dispatch" :
> True, "driver" : False, "thunk" : False},
> >       "vkGetCalibratedTimestampsEXT" : {"dispatch" : True, "driver" :
> False, "thunk" : False},
> > +
> > +    # VK_EXT_debug_utils
> > +    "vkCreateDebugUtilsMessengerEXT" : {"dispatch": True, "driver" :
> False, "thunk" : False},
> > +    "vkDestroyDebugUtilsMessengerEXT" : {"dispatch": True, "driver" :
> False, "thunk" : False},
> > +    "vkSubmitDebugUtilsMessageEXT" : {"dispatch": True, "driver" :
> False, "thunk" : True, "private_thunk" : True},
> >   }
> >
> >   STRUCT_CHAIN_CONVERSIONS = [
> > @@ -941,6 +945,8 @@ class VkHandle(object):
> >
> >           if self.name == "VkCommandPool":
> >               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)
> >
> >           native_handle_name = None
> >
> > diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c
> > index 54b910c5e5..f831d486d0 100644
> > --- a/dlls/winevulkan/vulkan.c
> > +++ b/dlls/winevulkan/vulkan.c
> > @@ -57,6 +57,21 @@ static void *wine_vk_find_struct_(void *s,
> VkStructureType t)
> >       return NULL;
> >   }
> >
> > +#define wine_vk_count_struct(s, t) wine_vk_count_struct_((void *)s,
> VK_STRUCTURE_TYPE_##t)
> > +static uint32_t wine_vk_count_struct_(void *s, VkStructureType t)
> > +{
> > +    const VkBaseInStructure *header;
> > +    uint32_t result = 0;
> > +
> > +    for (header = s; header; header = header->pNext)
> > +    {
> > +        if (header->sType == t)
> > +            result++;
> > +    }
> > +
> > +    return result;
> > +}
> > +
> >   static void *wine_vk_get_global_proc_addr(const char *name);
> >
> >   static HINSTANCE hinstance;
> > @@ -113,6 +128,68 @@ static uint64_t wine_vk_get_wrapper(struct
> VkInstance_T *instance, uint64_t nati
> >       return result;
> >   }
> >
> > +static VkBool32
> debug_utils_callback_conversion(VkDebugUtilsMessageSeverityFlagBitsEXT
> severity,
> > +    VkDebugUtilsMessageTypeFlagsEXT message_types,
> > +#if defined(USE_STRUCT_CONVERSION)
> > +    const VkDebugUtilsMessengerCallbackDataEXT_host *callback_data,
> > +#else
> > +    const VkDebugUtilsMessengerCallbackDataEXT *callback_data,
> > +#endif
> > +    void *user_data)
> > +{
> > +    struct VkDebugUtilsMessengerCallbackDataEXT wine_callback_data;
> > +    VkDebugUtilsObjectNameInfoEXT *object_name_infos;
> > +    struct wine_debug_utils_messenger *object;
> > +    VkBool32 result;
> > +    int i;
> > +
> > +    TRACE("%i, %u, %p, %p\n", severity, message_types, callback_data,
> 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;
> > +    }
> > +
> > +    wine_callback_data = *((VkDebugUtilsMessengerCallbackDataEXT *)
> callback_data);
> > +
> > +    object_name_infos = heap_calloc(wine_callback_data.objectCount,
> sizeof(*object_name_infos));
> > +
> > +    for (i = 0; i < wine_callback_data.objectCount; i++)
> > +    {
> > +        object_name_infos[i].sType = callback_data->pObjects[i].sType;
> > +        object_name_infos[i].pNext = callback_data->pObjects[i].pNext;
> > +        object_name_infos[i].objectType =
> callback_data->pObjects[i].objectType;
> > +        object_name_infos[i].pObjectName =
> callback_data->pObjects[i].pObjectName;
> > +
> > +        if
> (wine_vk_is_type_wrapped(callback_data->pObjects[i].objectType))
> > +        {
> > +            object_name_infos[i].objectHandle =
> wine_vk_get_wrapper(object->instance,
> callback_data->pObjects[i].objectHandle);
> > +            if (!object_name_infos[i].objectHandle)
> > +            {
> > +                WARN("handle conversion failed 0x%s\n",
> wine_dbgstr_longlong(callback_data->pObjects[i].objectHandle));
> > +                heap_free(object_name_infos);
> > +                return VK_FALSE;
> > +            }
> > +        }
> > +        else
> > +        {
> > +            object_name_infos[i].objectHandle =
> callback_data->pObjects[i].objectHandle;
> > +        }
> > +    }
> > +
> > +    wine_callback_data.pObjects = object_name_infos;
> > +
> > +    /* applications should always return VK_FALSE */
> > +    result = object->user_callback(severity, message_types,
> &wine_callback_data, object->user_data);
> > +
> > +    heap_free(object_name_infos);
> > +
> > +    return result;
> > +}
> > +
> >   static void wine_vk_physical_device_free(struct VkPhysicalDevice_T
> *phys_dev)
> >   {
> >       if (!phys_dev)
> > @@ -393,6 +470,8 @@ static void wine_vk_init_once(void)
> >   static VkResult wine_vk_instance_convert_create_info(const
> VkInstanceCreateInfo *src,
> >           VkInstanceCreateInfo *dst, struct VkInstance_T *object)
> >   {
> > +    VkDebugUtilsMessengerCreateInfoEXT *debug_utils_messenger;
> > +    VkBaseInStructure *header;
> >       unsigned int i;
> >       VkResult res;
> >
> > @@ -404,6 +483,26 @@ static VkResult
> wine_vk_instance_convert_create_info(const VkInstanceCreateInfo
> >           return res;
> >       }
> >
> > +    object->utils_messenger_count = wine_vk_count_struct(dst,
> DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT);
> > +    object->utils_messengers =
> heap_calloc(object->utils_messenger_count,
> sizeof(*object->utils_messengers));
> > +    header = (VkBaseInStructure *) dst;
> > +    for (i = 0; i < object->utils_messenger_count; i++)
> > +    {
> > +        header = wine_vk_find_struct(header->pNext,
> DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT);
> > +        debug_utils_messenger = (VkDebugUtilsMessengerCreateInfoEXT *)
> header;
> > +
> > +        object->utils_messengers[i].instance = object;
> > +        object->utils_messengers[i].debug_messenger = VK_NULL_HANDLE;
> > +        object->utils_messengers[i].user_callback =
> debug_utils_messenger->pfnUserCallback;
> > +        object->utils_messengers[i].user_data =
> debug_utils_messenger->pUserData;
> > +
> > +        /* convert_VkInstanceCreateInfo_struct_chain already copied the
> chain,
> > +         * so we can modify it in-place.
> > +         */
> > +        debug_utils_messenger->pfnUserCallback = (void *)
> &debug_utils_callback_conversion;
> > +        debug_utils_messenger->pUserData = &object->utils_messengers[i];
> > +    }
> > +
> >       /* ICDs don't support any layers, so nothing to copy. Modern
> versions of the loader
> >        * filter this data out as well.
> >        */
> > @@ -427,6 +526,10 @@ 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"))
> > +        {
> > +            object->enable_wrapper_list = VK_TRUE;
> > +        }
> >       }
> >
> >       return VK_SUCCESS;
> > @@ -527,6 +630,8 @@ static void wine_vk_instance_free(struct
> VkInstance_T *instance)
> >           WINE_VK_REMOVE_HANDLE_MAPPING(instance, instance);
> >       }
> >
> > +    heap_free(instance->utils_messengers);
> > +
> >       heap_free(instance);
> >   }
> >
> > @@ -1673,6 +1778,84 @@ VkResult WINAPI
> wine_vkGetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice
> >       return res;
> >   }
> >
> > +VkResult WINAPI wine_vkCreateDebugUtilsMessengerEXT(VkInstance
> instance, const VkDebugUtilsMessengerCreateInfoEXT *create_info,
> > +        const VkAllocationCallbacks *allocator,
> VkDebugUtilsMessengerEXT *messenger)
> > +{
> > +    VkDebugUtilsMessengerCreateInfoEXT wine_create_info;
> > +    struct wine_debug_utils_messenger *object;
> > +    VkResult res;
> > +
> > +    TRACE("%p, %p, %p, %p\n", instance, create_info, allocator,
> messenger);
> > +
> > +    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->pfnUserCallback;
> > +    object->user_data = create_info->pUserData;
> > +
> > +    wine_create_info = *create_info;
> > +
> > +    wine_create_info.pfnUserCallback = (void *)
> &debug_utils_callback_conversion;
> > +    wine_create_info.pUserData = object;
> > +
> > +    res =
> instance->funcs.p_vkCreateDebugUtilsMessengerEXT(instance->instance,
> &wine_create_info, NULL,  &object->debug_messenger);
> > +
> > +    if (res != VK_SUCCESS)
> > +    {
> > +        heap_free(object);
> > +        return res;
> > +    }
> > +
> > +    WINE_VK_ADD_NON_DISPATCHABLE_MAPPING(instance, object,
> object->debug_messenger);
> > +    *messenger = wine_debug_utils_messenger_to_handle(object);
> > +
> > +    return VK_SUCCESS;
> > +}
> > +
> > +void WINAPI wine_vkDestroyDebugUtilsMessengerEXT(
> > +        VkInstance instance, VkDebugUtilsMessengerEXT messenger, const
> VkAllocationCallbacks *allocator)
> > +{
> > +    struct wine_debug_utils_messenger *object;
> > +
> > +    TRACE("%p, 0x%s, %p\n", instance, wine_dbgstr_longlong(messenger),
> allocator);
> > +
> > +    object = wine_debug_utils_messenger_from_handle(messenger);
> > +
> > +
> instance->funcs.p_vkDestroyDebugUtilsMessengerEXT(instance->instance,
> object->debug_messenger, NULL);
> > +    WINE_VK_REMOVE_HANDLE_MAPPING(instance, object);
> > +
> > +    heap_free(object);
> > +}
> > +
> > +void WINAPI wine_vkSubmitDebugUtilsMessageEXT(VkInstance instance,
> VkDebugUtilsMessageSeverityFlagBitsEXT severity,
> > +        VkDebugUtilsMessageTypeFlagsEXT types, const
> VkDebugUtilsMessengerCallbackDataEXT *callback_data)
> > +{
> > +    VkDebugUtilsMessengerCallbackDataEXT native_callback_data;
> > +    VkDebugUtilsObjectNameInfoEXT *object_names;
> > +    int i;
> > +
> > +    TRACE("%p, %#x, %#x, %p\n", instance, severity, types,
> callback_data);
> > +
> > +    native_callback_data = *callback_data;
> > +    object_names = heap_calloc(callback_data->objectCount,
> sizeof(*object_names));
> > +    memcpy(object_names, callback_data->pObjects,
> callback_data->objectCount * sizeof(*object_names));
> > +    native_callback_data.pObjects = object_names;
> > +
> > +    for (i = 0; i < callback_data->objectCount; i++)
> > +    {
> > +        object_names[i].objectHandle =
> > +
> wine_vk_unwrap_handle(callback_data->pObjects[i].objectType,
> callback_data->pObjects[i].objectHandle);
> > +    }
> > +
> > +    thunk_vkSubmitDebugUtilsMessageEXT(instance->instance, severity,
> types, &native_callback_data);
> > +
> > +    heap_free(object_names);
> > +}
> > +
> >   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 7000da7133..8379fafecf 100644
> > --- a/dlls/winevulkan/vulkan_private.h
> > +++ b/dlls/winevulkan/vulkan_private.h
> > @@ -95,6 +95,8 @@ struct VkDevice_T
> >       struct wine_vk_mapping mapping;
> >   };
> >
> > +struct wine_debug_utils_messenger;
> > +
> >   struct VkInstance_T
> >   {
> >       struct wine_vk_base base;
> > @@ -111,6 +113,9 @@ struct VkInstance_T
> >       struct list wrappers;
> >       SRWLOCK wrapper_lock;
> >
> > +    struct wine_debug_utils_messenger *utils_messengers;
> > +    uint32_t utils_messenger_count;
> > +
> >       unsigned int quirks;
> >
> >       struct wine_vk_mapping mapping;
> > @@ -158,6 +163,32 @@ static inline VkCommandPool
> wine_cmd_pool_to_handle(struct wine_cmd_pool *cmd_po
> >       return (VkCommandPool)(uintptr_t)cmd_pool;
> >   }
> >
> > +struct wine_debug_utils_messenger
> > +{
> > +    struct VkInstance_T *instance; /* parent */
> > +    VkDebugUtilsMessengerEXT debug_messenger; /* native messenger */
> > +
> > +    /* application callback + data */
> > +    PFN_vkDebugUtilsMessengerCallbackEXT user_callback;
> > +    void *user_data;
> > +
> > +    struct wine_vk_mapping mapping;
> > +};
> > +
> > +static inline struct wine_debug_utils_messenger
> *wine_debug_utils_messenger_from_handle(
> > +        VkDebugUtilsMessengerEXT handle)
> > +{
> > +    return (struct wine_debug_utils_messenger *)(uintptr_t)handle;
> > +}
> > +
> > +static inline VkDebugUtilsMessengerEXT
> wine_debug_utils_messenger_to_handle(
> > +        struct wine_debug_utils_messenger *debug_messenger)
> > +{
> > +    return (VkDebugUtilsMessengerEXT)(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;
> >
> >
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.winehq.org/pipermail/wine-devel/attachments/20201005/e6b506e6/attachment-0001.htm>


More information about the wine-devel mailing list