[PATCH v6 2/3] winevulkan: Store a mapping from native handles to wrappers.

Liam Middlebrook lmiddlebrook at nvidia.com
Tue Oct 13 20:33:25 CDT 2020


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

On 10/13/20 10:28 AM, Georg Lehmann wrote:
> Signed-off-by: Georg Lehmann <dadschoorse at gmail.com>
> ---
>   dlls/winevulkan/vulkan.c         | 74 ++++++++++++++++++++++++++++++++
>   dlls/winevulkan/vulkan_private.h | 26 +++++++++++
>   2 files changed, 100 insertions(+)
> 
> diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c
> index 3d1e8bd0abd..c140ff3a0e8 100644
> --- a/dlls/winevulkan/vulkan.c
> +++ b/dlls/winevulkan/vulkan.c
> @@ -66,11 +66,59 @@ static VkResult (*p_vkEnumerateInstanceVersion)(uint32_t *version);
>   void WINAPI wine_vkGetPhysicalDeviceProperties(VkPhysicalDevice physical_device,
>           VkPhysicalDeviceProperties *properties);
>   
> +#define WINE_VK_ADD_DISPATCHABLE_MAPPING(instance, object, native_handle) \
> +    wine_vk_add_handle_mapping((instance), (uint64_t) (uintptr_t) (object), (uint64_t) (uintptr_t) (native_handle), &(object)->mapping)
> +#define WINE_VK_ADD_NON_DISPATCHABLE_MAPPING(instance, object, native_handle) \
> +    wine_vk_add_handle_mapping((instance), (uint64_t) (uintptr_t) (object), (uint64_t) (native_handle), &(object)->mapping)
> +static void  wine_vk_add_handle_mapping(struct VkInstance_T *instance, uint64_t wrapped_handle,
> +        uint64_t native_handle, struct wine_vk_mapping *mapping)
> +{
> +    if (instance->enable_wrapper_list)
> +    {
> +        mapping->native_handle = native_handle;
> +        mapping->wine_wrapped_handle = wrapped_handle;
> +        AcquireSRWLockExclusive(&instance->wrapper_lock);
> +        list_add_tail(&instance->wrappers, &mapping->link);
> +        ReleaseSRWLockExclusive(&instance->wrapper_lock);
> +    }
> +}
> +
> +#define WINE_VK_REMOVE_HANDLE_MAPPING(instance, object) \
> +    wine_vk_remove_handle_mapping((instance), &(object)->mapping)
> +static void wine_vk_remove_handle_mapping(struct VkInstance_T *instance, struct wine_vk_mapping *mapping)
> +{
> +    if (instance->enable_wrapper_list)
> +    {
> +        AcquireSRWLockExclusive(&instance->wrapper_lock);
> +        list_remove(&mapping->link);
> +        ReleaseSRWLockExclusive(&instance->wrapper_lock);
> +    }
> +}
> +
> +static uint64_t wine_vk_get_wrapper(struct VkInstance_T *instance, uint64_t native_handle)
> +{
> +    struct wine_vk_mapping *mapping;
> +    uint64_t result = 0;
> +
> +    AcquireSRWLockShared(&instance->wrapper_lock);
> +    LIST_FOR_EACH_ENTRY(mapping, &instance->wrappers, struct wine_vk_mapping, link)
> +    {
> +        if (mapping->native_handle == native_handle)
> +        {
> +            result = mapping->wine_wrapped_handle;
> +            break;
> +        }
> +    }
> +    ReleaseSRWLockShared(&instance->wrapper_lock);
> +    return result;
> +}
> +
>   static void wine_vk_physical_device_free(struct VkPhysicalDevice_T *phys_dev)
>   {
>       if (!phys_dev)
>           return;
>   
> +    WINE_VK_REMOVE_HANDLE_MAPPING(phys_dev->instance, phys_dev);
>       heap_free(phys_dev->extensions);
>       heap_free(phys_dev);
>   }
> @@ -91,6 +139,8 @@ static struct VkPhysicalDevice_T *wine_vk_physical_device_alloc(struct VkInstanc
>       object->instance = instance;
>       object->phys_dev = phys_dev;
>   
> +    WINE_VK_ADD_DISPATCHABLE_MAPPING(instance, object, phys_dev);
> +
>       res = instance->funcs.p_vkEnumerateDeviceExtensionProperties(phys_dev,
>               NULL, &num_host_properties, NULL);
>       if (res != VK_SUCCESS)
> @@ -169,6 +219,7 @@ static void wine_vk_free_command_buffers(struct VkDevice_T *device,
>   
>           device->funcs.p_vkFreeCommandBuffers(device->device, pool->command_pool, 1, &buffers[i]->command_buffer);
>           list_remove(&buffers[i]->pool_link);
> +        WINE_VK_REMOVE_HANDLE_MAPPING(device->phys_dev->instance, buffers[i]);
>           heap_free(buffers[i]);
>       }
>   }
> @@ -212,6 +263,8 @@ static struct VkQueue_T *wine_vk_device_alloc_queues(struct VkDevice_T *device,
>           {
>               device->funcs.p_vkGetDeviceQueue(device->device, family_index, i, &queue->queue);
>           }
> +
> +        WINE_VK_ADD_DISPATCHABLE_MAPPING(device->phys_dev->instance, queue, queue->queue);
>       }
>   
>       return queues;
> @@ -294,6 +347,8 @@ static void wine_vk_device_free(struct VkDevice_T *device)
>           unsigned int i;
>           for (i = 0; i < device->max_queue_families; i++)
>           {
> +            if (device->queues[i] && device->queues[i]->queue)
> +                WINE_VK_REMOVE_HANDLE_MAPPING(device->phys_dev->instance, device->queues[i]);
>               heap_free(device->queues[i]);
>           }
>           heap_free(device->queues);
> @@ -302,6 +357,7 @@ static void wine_vk_device_free(struct VkDevice_T *device)
>   
>       if (device->device && device->funcs.p_vkDestroyDevice)
>       {
> +        WINE_VK_REMOVE_HANDLE_MAPPING(device->phys_dev->instance, device);
>           device->funcs.p_vkDestroyDevice(device->device, NULL /* pAllocator */);
>       }
>   
> @@ -466,7 +522,10 @@ static void wine_vk_instance_free(struct VkInstance_T *instance)
>       }
>   
>       if (instance->instance)
> +    {
>           vk_funcs->p_vkDestroyInstance(instance->instance, NULL /* allocator */);
> +        WINE_VK_REMOVE_HANDLE_MAPPING(instance, instance);
> +    }
>   
>       heap_free(instance);
>   }
> @@ -512,6 +571,7 @@ VkResult WINAPI wine_vkAllocateCommandBuffers(VkDevice device,
>           list_add_tail(&pool->command_buffers, &buffers[i]->pool_link);
>           res = device->funcs.p_vkAllocateCommandBuffers(device->device,
>                   &allocate_info_host, &buffers[i]->command_buffer);
> +        WINE_VK_ADD_DISPATCHABLE_MAPPING(device->phys_dev->instance, buffers[i], buffers[i]->command_buffer);
>           if (res != VK_SUCCESS)
>           {
>               ERR("Failed to allocate command buffer, res=%d.\n", res);
> @@ -589,6 +649,7 @@ VkResult WINAPI wine_vkCreateDevice(VkPhysicalDevice phys_dev,
>           return VK_ERROR_OUT_OF_HOST_MEMORY;
>   
>       object->base.loader_magic = VULKAN_ICD_MAGIC_VALUE;
> +    object->phys_dev = phys_dev;
>   
>       res = wine_vk_device_convert_create_info(create_info, &create_info_host);
>       if (res != VK_SUCCESS)
> @@ -597,6 +658,7 @@ VkResult WINAPI wine_vkCreateDevice(VkPhysicalDevice phys_dev,
>       res = phys_dev->instance->funcs.p_vkCreateDevice(phys_dev->phys_dev,
>               &create_info_host, NULL /* allocator */, &object->device);
>       wine_vk_device_free_create_info(&create_info_host);
> +    WINE_VK_ADD_DISPATCHABLE_MAPPING(phys_dev->instance, object, object->device);
>       if (res != VK_SUCCESS)
>       {
>           WARN("Failed to create device, res=%d.\n", res);
> @@ -678,6 +740,8 @@ VkResult WINAPI wine_vkCreateInstance(const VkInstanceCreateInfo *create_info,
>           return VK_ERROR_OUT_OF_HOST_MEMORY;
>       }
>       object->base.loader_magic = VULKAN_ICD_MAGIC_VALUE;
> +    list_init(&object->wrappers);
> +    InitializeSRWLock(&object->wrapper_lock);
>   
>       res = wine_vk_instance_convert_create_info(create_info, &create_info_host, object);
>       if (res != VK_SUCCESS)
> @@ -695,6 +759,8 @@ VkResult WINAPI wine_vkCreateInstance(const VkInstanceCreateInfo *create_info,
>           return res;
>       }
>   
> +    WINE_VK_ADD_DISPATCHABLE_MAPPING(object, object, object->instance);
> +
>       /* Load all instance functions we are aware of. Note the loader takes care
>        * of any filtering for extensions which were not requested, but which the
>        * ICD may support.
> @@ -1129,9 +1195,14 @@ VkResult WINAPI wine_vkCreateCommandPool(VkDevice device, const VkCommandPoolCre
>       res = device->funcs.p_vkCreateCommandPool(device->device, info, NULL, &object->command_pool);
>   
>       if (res == VK_SUCCESS)
> +    {
> +        WINE_VK_ADD_NON_DISPATCHABLE_MAPPING(device->phys_dev->instance, object, object->command_pool);
>           *command_pool = wine_cmd_pool_to_handle(object);
> +    }
>       else
> +    {
>           heap_free(object);
> +    }
>   
>       return res;
>   }
> @@ -1156,9 +1227,12 @@ void WINAPI wine_vkDestroyCommandPool(VkDevice device, VkCommandPool handle,
>        */
>       LIST_FOR_EACH_ENTRY_SAFE(buffer, cursor, &pool->command_buffers, struct VkCommandBuffer_T, pool_link)
>       {
> +        WINE_VK_REMOVE_HANDLE_MAPPING(device->phys_dev->instance, buffer);
>           heap_free(buffer);
>       }
>   
> +    WINE_VK_REMOVE_HANDLE_MAPPING(device->phys_dev->instance, pool);
> +
>       device->funcs.p_vkDestroyCommandPool(device->device, pool->command_pool, NULL);
>       heap_free(pool);
>   }
> diff --git a/dlls/winevulkan/vulkan_private.h b/dlls/winevulkan/vulkan_private.h
> index bf09401c52a..959a813a213 100644
> --- a/dlls/winevulkan/vulkan_private.h
> +++ b/dlls/winevulkan/vulkan_private.h
> @@ -60,6 +60,16 @@ struct wine_vk_base
>       UINT_PTR loader_magic;
>   };
>   
> +/* Some extensions have callbacks for those we need to be able to
> + * get the wine wrapper for a native handle
> + */
> +struct wine_vk_mapping
> +{
> +    struct list link;
> +    uint64_t native_handle;
> +    uint64_t wine_wrapped_handle;
> +};
> +
>   struct VkCommandBuffer_T
>   {
>       struct wine_vk_base base;
> @@ -67,18 +77,22 @@ struct VkCommandBuffer_T
>       VkCommandBuffer command_buffer; /* native command buffer */
>   
>       struct list pool_link;
> +    struct wine_vk_mapping mapping;
>   };
>   
>   struct VkDevice_T
>   {
>       struct wine_vk_base base;
>       struct vulkan_device_funcs funcs;
> +    struct VkPhysicalDevice_T *phys_dev; /* parent */
>       VkDevice device; /* native device */
>   
>       struct VkQueue_T **queues;
>       uint32_t max_queue_families;
>   
>       unsigned int quirks;
> +
> +    struct wine_vk_mapping mapping;
>   };
>   
>   struct VkInstance_T
> @@ -93,7 +107,13 @@ struct VkInstance_T
>       struct VkPhysicalDevice_T **phys_devs;
>       uint32_t phys_dev_count;
>   
> +    VkBool32 enable_wrapper_list;
> +    struct list wrappers;
> +    SRWLOCK wrapper_lock;
> +
>       unsigned int quirks;
> +
> +    struct wine_vk_mapping mapping;
>   };
>   
>   struct VkPhysicalDevice_T
> @@ -104,6 +124,8 @@ struct VkPhysicalDevice_T
>   
>       VkExtensionProperties *extensions;
>       uint32_t extension_count;
> +
> +    struct wine_vk_mapping mapping;
>   };
>   
>   struct VkQueue_T
> @@ -113,6 +135,8 @@ struct VkQueue_T
>       VkQueue queue; /* native queue */
>   
>       VkDeviceQueueCreateFlags flags;
> +
> +    struct wine_vk_mapping mapping;
>   };
>   
>   struct wine_cmd_pool
> @@ -120,6 +144,8 @@ struct wine_cmd_pool
>       VkCommandPool command_pool;
>   
>       struct list command_buffers;
> +
> +    struct wine_vk_mapping mapping;
>   };
>   
>   static inline struct wine_cmd_pool *wine_cmd_pool_from_handle(VkCommandPool handle)
> 



More information about the wine-devel mailing list