From: Jacek Caban jacek@codeweavers.com
--- dlls/winevulkan/make_vulkan | 1 + dlls/winevulkan/vulkan.c | 81 +++++++++++++++++++++++++++++--- dlls/winevulkan/vulkan_private.h | 2 + dlls/winevulkan/vulkan_thunks.c | 4 +- dlls/winevulkan/vulkan_thunks.h | 1 + 5 files changed, 81 insertions(+), 8 deletions(-)
diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan index 97edd5625bc..9d66bb9f606 100755 --- a/dlls/winevulkan/make_vulkan +++ b/dlls/winevulkan/make_vulkan @@ -257,6 +257,7 @@ MANUAL_UNIX_THUNKS = { "vkGetPhysicalDeviceExternalFencePropertiesKHR", "vkGetPhysicalDeviceExternalSemaphoreProperties", "vkGetPhysicalDeviceExternalSemaphorePropertiesKHR", + "vkGetPhysicalDeviceFeatures2KHR", "vkGetPhysicalDeviceImageFormatProperties2", "vkGetPhysicalDeviceImageFormatProperties2KHR", "vkGetPhysicalDeviceSurfaceCapabilities2KHR", diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c index baac3cd8683..f875111d0d5 100644 --- a/dlls/winevulkan/vulkan.c +++ b/dlls/winevulkan/vulkan.c @@ -406,6 +406,7 @@ static VkResult wine_vk_device_convert_create_info(struct wine_phys_dev *phys_de { const char *extra_extensions[2], * const*extensions = src->ppEnabledExtensionNames; unsigned int i, extra_count = 0, extensions_count = src->enabledExtensionCount; + VkPhysicalDeviceMapMemoryPlacedFeaturesEXT *map_placed_features;
*dst = *src;
@@ -425,6 +426,8 @@ static VkResult wine_vk_device_convert_create_info(struct wine_phys_dev *phys_de } }
+ map_placed_features = find_next_struct(dst->pNext, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAP_MEMORY_PLACED_FEATURES_EXT); + if (phys_dev->external_memory_align) { if (!find_extension(extensions, extensions_count, "VK_KHR_external_memory")) @@ -444,6 +447,15 @@ static VkResult wine_vk_device_convert_create_info(struct wine_phys_dev *phys_de dst->ppEnabledExtensionNames = new_extensions; }
+ /* If memoryMapPlaced is enabled, we need also memoryUnmapReserve to support unmapping. */ + if (map_placed_features) + { + if (map_placed_features->memoryMapPlaced) + map_placed_features->memoryUnmapReserve = VK_TRUE; + if (map_placed_features->memoryMapRangePlaced) + return VK_ERROR_FEATURE_NOT_PRESENT; + } + return VK_SUCCESS; }
@@ -1218,6 +1230,23 @@ VkResult wine_vkEnumeratePhysicalDeviceGroupsKHR(VkInstance handle, uint32_t *co instance->funcs.p_vkEnumeratePhysicalDeviceGroupsKHR, count, properties); }
+void wine_vkGetPhysicalDeviceFeatures2KHR(VkPhysicalDevice phys_dev_handle, VkPhysicalDeviceFeatures2 *features) +{ + struct wine_phys_dev *phys_dev = wine_phys_dev_from_handle(phys_dev_handle); + VkPhysicalDeviceMapMemoryPlacedFeaturesEXT *map_placed_features; + + phys_dev->instance->funcs.p_vkGetPhysicalDeviceFeatures2KHR(phys_dev->host_physical_device, features); + + map_placed_features = find_next_struct(features->pNext, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAP_MEMORY_PLACED_PROPERTIES_EXT); + if (map_placed_features) + { + if (!map_placed_features->memoryUnmapReserve) + map_placed_features->memoryMapPlaced = VK_FALSE; + map_placed_features->memoryMapRangePlaced = VK_FALSE; + } +} + void wine_vkGetPhysicalDeviceExternalFenceProperties(VkPhysicalDevice phys_dev, const VkPhysicalDeviceExternalFenceInfo *fence_info, VkExternalFenceProperties *properties) @@ -1701,7 +1730,9 @@ VkResult wine_vkAllocateMemory(VkDevice handle, const VkMemoryAllocateInfo *allo }
WINE_VK_ADD_NON_DISPATCHABLE_MAPPING(device->phys_dev->instance, memory, memory->host_memory, memory); + memory->size = info.allocationSize; memory->vm_map = mapping; + memory->preserve_map = FALSE; *ret = (VkDeviceMemory)(uintptr_t)memory; return VK_SUCCESS; } @@ -1715,10 +1746,21 @@ void wine_vkFreeMemory(VkDevice handle, VkDeviceMemory memory_handle, const VkAl return; memory = wine_device_memory_from_handle(memory_handle);
+ if (memory->vm_map && !device->phys_dev->external_memory_align) + { + const VkMemoryUnmapInfoKHR info = + { + .sType = VK_STRUCTURE_TYPE_MEMORY_UNMAP_INFO_KHR, + .memory = memory->host_memory, + .flags = VK_MEMORY_UNMAP_RESERVE_BIT_EXT, + }; + device->funcs.p_vkUnmapMemory2KHR(device->host_device, &info); + } + WINE_VK_REMOVE_HANDLE_MAPPING(device->phys_dev->instance, memory); device->funcs.p_vkFreeMemory(device->host_device, memory->host_memory, NULL);
- if (memory->vm_map) + if (memory->vm_map && !memory->preserve_map) { SIZE_T alloc_size = 0; NtFreeVirtualMemory(GetCurrentProcess(), &memory->vm_map, &alloc_size, MEM_RELEASE); @@ -1747,16 +1789,21 @@ VkResult wine_vkMapMemory2KHR(VkDevice handle, const VkMemoryMapInfoKHR *map_inf struct wine_device *device = wine_device_from_handle(handle); struct wine_device_memory *memory = wine_device_memory_from_handle(map_info->memory); VkMemoryMapInfoKHR info = *map_info; + VkMemoryMapPlacedInfoEXT *placed_info_arg; VkResult result;
- info.memory = memory->host_memory; if (memory->vm_map) { - *data = (char *)memory->vm_map + info.offset; + *data = (char *)memory->vm_map + map_info->offset; TRACE("returning %p\n", *data); return VK_SUCCESS; }
+ info = *map_info; + info.memory = memory->host_memory; + + placed_info_arg = find_next_struct(info.pNext, VK_STRUCTURE_TYPE_MEMORY_MAP_PLACED_INFO_EXT); + if (device->funcs.p_vkMapMemory2KHR) { result = device->funcs.p_vkMapMemory2KHR(device->host_device, &info, data); @@ -1768,6 +1815,12 @@ VkResult wine_vkMapMemory2KHR(VkDevice handle, const VkMemoryMapInfoKHR *map_inf info.size, info.flags, data); }
+ if (info.flags & VK_MEMORY_MAP_PLACED_BIT_EXT) + { + memory->vm_map = placed_info_arg->pPlacedAddress; + memory->preserve_map = TRUE; + } + #ifdef _WIN64 if (NtCurrentTeb()->WowTebOffset && result == VK_SUCCESS && (UINT_PTR)*data >> 32) { @@ -1797,20 +1850,36 @@ VkResult wine_vkUnmapMemory2KHR(VkDevice handle, const VkMemoryUnmapInfoKHR *unm struct wine_device *device = wine_device_from_handle(handle); struct wine_device_memory *memory = wine_device_memory_from_handle(unmap_info->memory); VkMemoryUnmapInfoKHR info; + VkResult result;
- if (memory->vm_map) + if (memory->vm_map && device->phys_dev->external_memory_align) return VK_SUCCESS;
if (!device->funcs.p_vkUnmapMemory2KHR) { - assert(!unmap_info->pNext); + assert(!unmap_info->pNext && !memory->vm_map); device->funcs.p_vkUnmapMemory(device->host_device, memory->host_memory); return VK_SUCCESS; }
info = *unmap_info; info.memory = memory->host_memory; - return device->funcs.p_vkUnmapMemory2KHR(device->host_device, &info); + if (memory->vm_map) + info.flags |= VK_MEMORY_UNMAP_RESERVE_BIT_EXT; + + result = device->funcs.p_vkUnmapMemory2KHR(device->host_device, &info); + + if (result == VK_SUCCESS && memory->vm_map) + { + if (!(unmap_info->flags & VK_MEMORY_UNMAP_RESERVE_BIT_EXT)) + { + SIZE_T size = memory->size; + NtFreeVirtualMemory(GetCurrentProcess(), &memory->vm_map, &size, MEM_RELEASE); + } + memory->vm_map = NULL; + memory->preserve_map = FALSE; + } + return result; }
VkResult wine_vkCreateBuffer(VkDevice handle, const VkBufferCreateInfo *create_info, diff --git a/dlls/winevulkan/vulkan_private.h b/dlls/winevulkan/vulkan_private.h index fd5d58870cc..dde0af26ec7 100644 --- a/dlls/winevulkan/vulkan_private.h +++ b/dlls/winevulkan/vulkan_private.h @@ -175,7 +175,9 @@ static inline struct wine_cmd_pool *wine_cmd_pool_from_handle(VkCommandPool hand struct wine_device_memory { VkDeviceMemory host_memory; + VkDeviceSize size; void *vm_map; + BOOL preserve_map;
struct wine_vk_mapping mapping; }; diff --git a/dlls/winevulkan/vulkan_thunks.c b/dlls/winevulkan/vulkan_thunks.c index a6af0d2f5da..da5395ef06f 100644 --- a/dlls/winevulkan/vulkan_thunks.c +++ b/dlls/winevulkan/vulkan_thunks.c @@ -42777,7 +42777,7 @@ static NTSTATUS thunk64_vkGetPhysicalDeviceFeatures2KHR(void *args)
TRACE("%p, %p\n", params->physicalDevice, params->pFeatures);
- wine_phys_dev_from_handle(params->physicalDevice)->instance->funcs.p_vkGetPhysicalDeviceFeatures2KHR(wine_phys_dev_from_handle(params->physicalDevice)->host_physical_device, params->pFeatures); + wine_vkGetPhysicalDeviceFeatures2KHR(params->physicalDevice, params->pFeatures); return STATUS_SUCCESS; } #endif /* _WIN64 */ @@ -42797,7 +42797,7 @@ static NTSTATUS thunk32_vkGetPhysicalDeviceFeatures2KHR(void *args)
init_conversion_context(ctx); convert_VkPhysicalDeviceFeatures2_win32_to_host(ctx, (VkPhysicalDeviceFeatures232 *)UlongToPtr(params->pFeatures), &pFeatures_host); - wine_phys_dev_from_handle((VkPhysicalDevice)UlongToPtr(params->physicalDevice))->instance->funcs.p_vkGetPhysicalDeviceFeatures2KHR(wine_phys_dev_from_handle((VkPhysicalDevice)UlongToPtr(params->physicalDevice))->host_physical_device, &pFeatures_host); + wine_vkGetPhysicalDeviceFeatures2KHR((VkPhysicalDevice)UlongToPtr(params->physicalDevice), &pFeatures_host); convert_VkPhysicalDeviceFeatures2_host_to_win32(&pFeatures_host, (VkPhysicalDeviceFeatures232 *)UlongToPtr(params->pFeatures)); free_conversion_context(ctx); return STATUS_SUCCESS; diff --git a/dlls/winevulkan/vulkan_thunks.h b/dlls/winevulkan/vulkan_thunks.h index 2c2712291c1..19bca560ef8 100644 --- a/dlls/winevulkan/vulkan_thunks.h +++ b/dlls/winevulkan/vulkan_thunks.h @@ -56,6 +56,7 @@ void wine_vkGetPhysicalDeviceExternalFenceProperties(VkPhysicalDevice physicalDe void wine_vkGetPhysicalDeviceExternalFencePropertiesKHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalFenceInfo *pExternalFenceInfo, VkExternalFenceProperties *pExternalFenceProperties); void wine_vkGetPhysicalDeviceExternalSemaphoreProperties(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalSemaphoreInfo *pExternalSemaphoreInfo, VkExternalSemaphoreProperties *pExternalSemaphoreProperties); void wine_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalSemaphoreInfo *pExternalSemaphoreInfo, VkExternalSemaphoreProperties *pExternalSemaphoreProperties); +void wine_vkGetPhysicalDeviceFeatures2KHR(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures2 *pFeatures); VkResult wine_vkGetPhysicalDeviceImageFormatProperties2(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo, VkImageFormatProperties2 *pImageFormatProperties); VkResult wine_vkGetPhysicalDeviceImageFormatProperties2KHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo, VkImageFormatProperties2 *pImageFormatProperties); VkResult wine_vkGetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo, VkSurfaceCapabilities2KHR *pSurfaceCapabilities);