From: Jacek Caban jacek@codeweavers.com
--- dlls/winevulkan/vulkan.c | 98 ++++++++++++++++++++++++++++++-- dlls/winevulkan/vulkan_private.h | 1 + 2 files changed, 94 insertions(+), 5 deletions(-)
diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c index f875111d0d5..4f1980c0ac0 100644 --- a/dlls/winevulkan/vulkan.c +++ b/dlls/winevulkan/vulkan.c @@ -223,6 +223,7 @@ static void wine_vk_physical_device_free(struct wine_phys_dev *phys_dev) static struct wine_phys_dev *wine_vk_physical_device_alloc(struct wine_instance *instance, VkPhysicalDevice phys_dev, VkPhysicalDevice handle) { + BOOL have_memory_placed = FALSE, have_map_memory2 = FALSE; struct wine_phys_dev *object; uint32_t num_host_properties, num_properties = 0; VkExtensionProperties *host_properties = NULL; @@ -281,6 +282,10 @@ static struct wine_phys_dev *wine_vk_physical_device_alloc(struct wine_instance } if (!strcmp(host_properties[i].extensionName, "VK_EXT_external_memory_host")) have_external_memory_host = TRUE; + else if (!strcmp(host_properties[i].extensionName, "VK_EXT_map_memory_placed")) + have_memory_placed = TRUE; + else if (!strcmp(host_properties[i].extensionName, "VK_KHR_map_memory2")) + have_map_memory2 = TRUE; }
TRACE("Host supported extensions %u, Wine supported extensions %u\n", num_host_properties, num_properties); @@ -301,7 +306,38 @@ static struct wine_phys_dev *wine_vk_physical_device_alloc(struct wine_instance } object->extension_count = num_properties;
- if (use_external_memory() && have_external_memory_host) + if (zero_bits && have_memory_placed && have_map_memory2) + { + VkPhysicalDeviceMapMemoryPlacedFeaturesEXT map_placed_feature = + { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAP_MEMORY_PLACED_FEATURES_EXT, + }; + VkPhysicalDeviceFeatures2 features = + { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2, + .pNext = &map_placed_feature, + }; + + instance->funcs.p_vkGetPhysicalDeviceFeatures2KHR(phys_dev, &features); + if (map_placed_feature.memoryMapPlaced && map_placed_feature.memoryUnmapReserve) + { + VkPhysicalDeviceMapMemoryPlacedPropertiesEXT map_placed_props = + { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAP_MEMORY_PLACED_PROPERTIES_EXT, + }; + VkPhysicalDeviceProperties2 props = + { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, + .pNext = &map_placed_props, + }; + + instance->funcs.p_vkGetPhysicalDeviceProperties2(phys_dev, &props); + object->map_placed_align = map_placed_props.minPlacedMemoryMapAlignment; + TRACE("map_placed_align %u\n", object->map_placed_align); + } + } + + if (zero_bits && have_external_memory_host && !object->map_placed_align) { VkPhysicalDeviceExternalMemoryHostPropertiesEXT host_mem_props = { @@ -428,7 +464,25 @@ 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 (phys_dev->map_placed_align) + { + if (!find_extension(extensions, extensions_count, "VK_EXT_map_memory_placed")) + extra_extensions[extra_count++] = "VK_EXT_map_memory_placed"; + if (!find_extension(extensions, extensions_count, "VK_KHR_map_memory2")) + extra_extensions[extra_count++] = "VK_KHR_map_memory2"; + + if (!map_placed_features) + { + map_placed_features = conversion_context_alloc(ctx, sizeof(*map_placed_features)); + map_placed_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAP_MEMORY_PLACED_FEATURES_EXT; + map_placed_features->pNext = (void *)dst->pNext; + dst->pNext = map_placed_features; + } + map_placed_features->memoryMapPlaced = VK_TRUE; + map_placed_features->memoryMapRangePlaced = VK_FALSE; + map_placed_features->memoryUnmapReserve = VK_TRUE; + } + else if (phys_dev->external_memory_align) { if (!find_extension(extensions, extensions_count, "VK_KHR_external_memory")) extra_extensions[extra_count++] = "VK_KHR_external_memory"; @@ -1788,8 +1842,11 @@ 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; + VkMemoryMapInfoKHR info; + VkMemoryMapPlacedInfoEXT *placed_info_arg, placed_info = + { + .sType = VK_STRUCTURE_TYPE_MEMORY_MAP_PLACED_INFO_EXT, + }; VkResult result;
if (memory->vm_map) @@ -1803,6 +1860,24 @@ VkResult wine_vkMapMemory2KHR(VkDevice handle, const VkMemoryMapInfoKHR *map_inf info.memory = memory->host_memory;
placed_info_arg = find_next_struct(info.pNext, VK_STRUCTURE_TYPE_MEMORY_MAP_PLACED_INFO_EXT); + if (device->phys_dev->map_placed_align && !placed_info_arg) + { + SIZE_T alloc_size = memory->size; + + placed_info_arg = &placed_info; + placed_info.pNext = info.pNext; + info.pNext = &placed_info; + info.offset = 0; + info.size = VK_WHOLE_SIZE; + info.flags |= VK_MEMORY_MAP_PLACED_BIT_EXT; + + if (NtAllocateVirtualMemory(GetCurrentProcess(), &placed_info.pPlacedAddress, zero_bits, &alloc_size, + MEM_RESERVE, PAGE_READWRITE)) + { + ERR("NtAllocateVirtualMemory failed\n"); + return VK_ERROR_OUT_OF_HOST_MEMORY; + } + }
if (device->funcs.p_vkMapMemory2KHR) { @@ -1815,7 +1890,20 @@ VkResult wine_vkMapMemory2KHR(VkDevice handle, const VkMemoryMapInfoKHR *map_inf info.size, info.flags, data); }
- if (info.flags & VK_MEMORY_MAP_PLACED_BIT_EXT) + if (placed_info.pPlacedAddress) + { + if (result != VK_SUCCESS) + { + SIZE_T alloc_size = 0; + ERR("vkMapMemory2EXT failed: %d\n", result); + NtFreeVirtualMemory(GetCurrentProcess(), &placed_info.pPlacedAddress, &alloc_size, MEM_RELEASE); + return result; + } + memory->vm_map = placed_info.pPlacedAddress; + *data = (char *)memory->vm_map + map_info->offset; + TRACE("Using VK_EXT_map_memory_placed mapping %p\n", memory->vm_map); + } + else if (info.flags & VK_MEMORY_MAP_PLACED_BIT_EXT) { memory->vm_map = placed_info_arg->pPlacedAddress; memory->preserve_map = TRUE; diff --git a/dlls/winevulkan/vulkan_private.h b/dlls/winevulkan/vulkan_private.h index dde0af26ec7..de63fbf4ba6 100644 --- a/dlls/winevulkan/vulkan_private.h +++ b/dlls/winevulkan/vulkan_private.h @@ -130,6 +130,7 @@ struct wine_phys_dev uint32_t extension_count;
uint32_t external_memory_align; + uint32_t map_placed_align;
struct wine_vk_mapping mapping; };