winevulkan: Use VK_EXT_map_memory_placed for memory mapping on wow64.
This commit is contained in:
parent
d8e0c8adea
commit
1999e4f3f5
2 changed files with 119 additions and 5 deletions
|
@ -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( "Using placed map with alignment %u\n", object->map_placed_align );
|
||||
}
|
||||
}
|
||||
|
||||
if (zero_bits && have_external_memory_host && !object->map_placed_align)
|
||||
{
|
||||
VkPhysicalDeviceExternalMemoryHostPropertiesEXT host_mem_props =
|
||||
{
|
||||
|
@ -425,7 +461,23 @@ static VkResult wine_vk_device_convert_create_info(struct wine_phys_dev *phys_de
|
|||
}
|
||||
}
|
||||
|
||||
if (phys_dev->external_memory_align)
|
||||
if (phys_dev->map_placed_align)
|
||||
{
|
||||
VkPhysicalDeviceMapMemoryPlacedFeaturesEXT *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;
|
||||
map_placed_features->memoryMapPlaced = VK_TRUE;
|
||||
map_placed_features->memoryMapRangePlaced = VK_FALSE;
|
||||
map_placed_features->memoryUnmapReserve = VK_TRUE;
|
||||
dst->pNext = map_placed_features;
|
||||
|
||||
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";
|
||||
}
|
||||
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";
|
||||
|
@ -1721,6 +1773,7 @@ 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;
|
||||
*ret = (VkDeviceMemory)(uintptr_t)memory;
|
||||
return VK_SUCCESS;
|
||||
|
@ -1735,6 +1788,17 @@ 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);
|
||||
|
||||
|
@ -1767,6 +1831,10 @@ 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 =
|
||||
{
|
||||
.sType = VK_STRUCTURE_TYPE_MEMORY_MAP_PLACED_INFO_EXT,
|
||||
};
|
||||
VkResult result;
|
||||
|
||||
info.memory = memory->host_memory;
|
||||
|
@ -1777,6 +1845,24 @@ VkResult wine_vkMapMemory2KHR(VkDevice handle, const VkMemoryMapInfoKHR *map_inf
|
|||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
if (device->phys_dev->map_placed_align)
|
||||
{
|
||||
SIZE_T alloc_size = memory->size;
|
||||
|
||||
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)
|
||||
{
|
||||
result = device->funcs.p_vkMapMemory2KHR(device->host_device, &info, data);
|
||||
|
@ -1788,6 +1874,20 @@ VkResult wine_vkMapMemory2KHR(VkDevice handle, const VkMemoryMapInfoKHR *map_inf
|
|||
info.size, info.flags, data);
|
||||
}
|
||||
|
||||
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 placed mapping %p\n", memory->vm_map);
|
||||
}
|
||||
|
||||
#ifdef _WIN64
|
||||
if (NtCurrentTeb()->WowTebOffset && result == VK_SUCCESS && (UINT_PTR)*data >> 32)
|
||||
{
|
||||
|
@ -1817,20 +1917,32 @@ 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)
|
||||
{
|
||||
SIZE_T size = 0;
|
||||
NtFreeVirtualMemory(GetCurrentProcess(), &memory->vm_map, &size, MEM_RELEASE);
|
||||
memory->vm_map = NULL;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
VkResult wine_vkCreateBuffer(VkDevice handle, const VkBufferCreateInfo *create_info,
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
@ -175,6 +176,7 @@ 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;
|
||||
|
||||
struct wine_vk_mapping mapping;
|
||||
|
|
Loading…
Add table
Reference in a new issue