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@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@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;
>������ ������
>