From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/vulkan.c | 126 +++++++++++++++++++++++-------------------- 1 file changed, 68 insertions(+), 58 deletions(-)
diff --git a/dlls/win32u/vulkan.c b/dlls/win32u/vulkan.c index 1c397db76c4..6503b217d1c 100644 --- a/dlls/win32u/vulkan.c +++ b/dlls/win32u/vulkan.c @@ -92,6 +92,71 @@ static inline const void *find_next_struct( const void *head, VkStructureType ty return NULL; }
+static VkResult allocate_external_host_memory( struct vulkan_device *device, VkMemoryAllocateInfo *alloc_info, + VkImportMemoryHostPointerInfoEXT *import_info ) +{ + struct vulkan_physical_device *physical_device = device->physical_device; + VkMemoryHostPointerPropertiesEXT props = + { + .sType = VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT, + }; + uint32_t i, mem_flags, align = physical_device->external_memory_align - 1; + SIZE_T alloc_size = alloc_info->allocationSize; + static int once; + void *mapping; + VkResult res; + + if (!once++) FIXME( "Using VK_EXT_external_memory_host\n" ); + + mem_flags = physical_device->memory_properties.memoryTypes[alloc_info->memoryTypeIndex].propertyFlags; + + if (NtAllocateVirtualMemory( GetCurrentProcess(), &mapping, zero_bits, &alloc_size, MEM_COMMIT, PAGE_READWRITE )) + { + ERR( "NtAllocateVirtualMemory failed\n" ); + return VK_ERROR_OUT_OF_HOST_MEMORY; + } + + if ((res = device->p_vkGetMemoryHostPointerPropertiesEXT( device->host.device, VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT, + mapping, &props ))) + { + ERR( "vkGetMemoryHostPointerPropertiesEXT failed: %d\n", res ); + return res; + } + + if (!(props.memoryTypeBits & (1u << alloc_info->memoryTypeIndex))) + { + /* If requested memory type is not allowed to use external memory, try to find a supported compatible type. */ + uint32_t mask = mem_flags & ~VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; + for (i = 0; i < physical_device->memory_properties.memoryTypeCount; i++) + { + if (!(props.memoryTypeBits & (1u << i))) continue; + if ((physical_device->memory_properties.memoryTypes[i].propertyFlags & mask) != mask) continue; + + TRACE( "Memory type not compatible with host memory, using %u instead\n", i ); + alloc_info->memoryTypeIndex = i; + break; + } + if (i == physical_device->memory_properties.memoryTypeCount) + { + FIXME( "Not found compatible memory type\n" ); + alloc_size = 0; + NtFreeVirtualMemory( GetCurrentProcess(), &mapping, &alloc_size, MEM_RELEASE ); + } + } + + if (props.memoryTypeBits & (1u << alloc_info->memoryTypeIndex)) + { + import_info->sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT; + import_info->handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT; + import_info->pHostPointer = mapping; + import_info->pNext = alloc_info->pNext; + alloc_info->pNext = import_info; + alloc_info->allocationSize = (alloc_info->allocationSize + align) & ~align; + } + + return VK_SUCCESS; +} + static VkResult win32u_vkAllocateMemory( VkDevice client_device, const VkMemoryAllocateInfo *alloc_info, const VkAllocationCallbacks *allocator, VkDeviceMemory *ret ) { @@ -109,64 +174,9 @@ static VkResult win32u_vkAllocateMemory( VkDevice client_device, const VkMemoryA /* For host visible memory, we try to use VK_EXT_external_memory_host on wow64 to ensure that mapped pointer is 32-bit. */ mem_flags = physical_device->memory_properties.memoryTypes[alloc_info->memoryTypeIndex].propertyFlags; if (physical_device->external_memory_align && (mem_flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) && - !find_next_struct( alloc_info->pNext, VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT )) - { - VkMemoryHostPointerPropertiesEXT props = - { - .sType = VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT, - }; - uint32_t i, align = physical_device->external_memory_align - 1; - SIZE_T alloc_size = info.allocationSize; - static int once; - - if (!once++) FIXME( "Using VK_EXT_external_memory_host\n" ); - - if (NtAllocateVirtualMemory( GetCurrentProcess(), &mapping, zero_bits, &alloc_size, MEM_COMMIT, PAGE_READWRITE )) - { - ERR( "NtAllocateVirtualMemory failed\n" ); - return VK_ERROR_OUT_OF_HOST_MEMORY; - } - - if ((res = device->p_vkGetMemoryHostPointerPropertiesEXT( device->host.device, VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT, - mapping, &props ))) - { - ERR( "vkGetMemoryHostPointerPropertiesEXT failed: %d\n", res ); - return res; - } - - if (!(props.memoryTypeBits & (1u << info.memoryTypeIndex))) - { - /* If requested memory type is not allowed to use external memory, - * try to find a supported compatible type. */ - uint32_t mask = mem_flags & ~VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; - for (i = 0; i < physical_device->memory_properties.memoryTypeCount; i++) - { - if (!(props.memoryTypeBits & (1u << i))) continue; - if ((physical_device->memory_properties.memoryTypes[i].propertyFlags & mask) != mask) continue; - - TRACE( "Memory type not compatible with host memory, using %u instead\n", i ); - info.memoryTypeIndex = i; - break; - } - if (i == physical_device->memory_properties.memoryTypeCount) - { - FIXME( "Not found compatible memory type\n" ); - alloc_size = 0; - NtFreeVirtualMemory( GetCurrentProcess(), &mapping, &alloc_size, MEM_RELEASE ); - } - } - - if (props.memoryTypeBits & (1u << info.memoryTypeIndex)) - { - host_pointer_info.sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT; - host_pointer_info.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT; - host_pointer_info.pHostPointer = mapping; - host_pointer_info.pNext = info.pNext; - info.pNext = &host_pointer_info; - - info.allocationSize = (info.allocationSize + align) & ~align; - } - } + !find_next_struct( alloc_info->pNext, VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT ) && + (res = allocate_external_host_memory( device, &info, &host_pointer_info ))) + return res;
if (!(memory = malloc( sizeof(*memory) ))) return VK_ERROR_OUT_OF_HOST_MEMORY; if ((res = device->p_vkAllocateMemory( device->host.device, &info, NULL, &host_device_memory )))