@ -2651,32 +2651,89 @@ bool VulkanDevice::TryImportHostMemory(void* data, size_t data_size, VkBufferUsa
// Full amount of data that must be imported, including the pages
const size_t data_size_aligned = Common : : AlignUpPow2 ( data_offset + data_size , HOST_PAGE_SIZE ) ;
const VkExternalMemoryBufferCreateInfo external_info = { VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO , nullptr ,
VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT } ;
const VkBufferCreateInfo buffer_info = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO ,
& external_info ,
0 ,
data_size_aligned ,
buffer_usage ,
VK_SHARING_MODE_EXCLUSIVE ,
0 ,
nullptr } ;
VkBuffer imported_buffer = VK_NULL_HANDLE ;
VkResult res = vkCreateBuffer ( m_device , & buffer_info , nullptr , & imported_buffer ) ;
if ( res ! = VK_SUCCESS )
{
Vulkan : : SetErrorObject ( error , " vkCreateBuffer() failed: " , res ) ;
return false ;
}
VkMemoryDedicatedRequirements dedicated_requirements = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS , nullptr ,
VK_FALSE , VK_FALSE } ;
VkMemoryRequirements buffer_requirements ;
if ( vkGetBufferMemoryRequirements2 )
{
const VkBufferMemoryRequirementsInfo2 requirements_info = { VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2 ,
nullptr , imported_buffer } ;
VkMemoryRequirements2 requirements = { VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2 , & dedicated_requirements , { } } ;
vkGetBufferMemoryRequirements2 ( m_device , & requirements_info , & requirements ) ;
buffer_requirements = requirements . memoryRequirements ;
}
else
{
vkGetBufferMemoryRequirements ( m_device , imported_buffer , & buffer_requirements ) ;
}
if ( buffer_requirements . size > data_size_aligned )
{
Error : : SetStringFmt ( error , " Imported host allocation is too small for buffer requirements ({} < {}). " ,
data_size_aligned , buffer_requirements . size ) ;
vkDestroyBuffer ( m_device , imported_buffer , nullptr ) ;
return false ;
}
VkMemoryHostPointerPropertiesEXT pointer_properties = { VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT , nullptr ,
0 } ;
VkResult res = vkGetMemoryHostPointerPropertiesEXT ( m_device , VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT ,
data_aligned , & pointer_properties ) ;
res = vkGetMemoryHostPointerPropertiesEXT ( m_device , VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT ,
data_aligned , & pointer_properties ) ;
if ( res ! = VK_SUCCESS | | pointer_properties . memoryTypeBits = = 0 )
{
Vulkan : : SetErrorObject ( error , " vkGetMemoryHostPointerPropertiesEXT() failed: " , res ) ;
vkDestroyBuffer ( m_device , imported_buffer , nullptr ) ;
return false ;
}
const u32 memory_type_bits = pointer_properties . memoryTypeBits & buffer_requirements . memoryTypeBits ;
if ( memory_type_bits = = 0 )
{
Error : : SetStringView ( error , " Imported host allocation has no buffer-compatible memory type. " ) ;
vkDestroyBuffer ( m_device , imported_buffer , nullptr ) ;
return false ;
}
VmaAllocationCreateInfo vma_alloc_info = { } ;
vma_alloc_info . preferredFlags =
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT ;
vma_alloc_info . memoryTypeBits = pointer_properties . memoryTypeBits ;
vma_alloc_info . requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT ;
vma_alloc_info . preferredFlags = VK_MEMORY_PROPERTY_HOST_CACHED_BIT ;
vma_alloc_info . memoryTypeBits = memory_type_b its;
u32 memory_index = 0 ;
res = vmaFindMemoryTypeIndex ( m_allocator , pointer_properties . memoryTypeBits , & vma_alloc_info , & memory_index ) ;
res = vmaFindMemoryTypeIndex ( m_allocator , memory_type_b its, & vma_alloc_info , & memory_index ) ;
if ( res ! = VK_SUCCESS )
{
Vulkan : : SetErrorObject ( error , " vmaFindMemoryTypeIndex() failed: " , res ) ;
vkDestroyBuffer ( m_device , imported_buffer , nullptr ) ;
return false ;
}
const VkImportMemoryHostPointerInfoEXT import_info = { VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT , nullptr ,
VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT ,
const_cast < void * > ( data_aligned ) } ;
const VkMemoryDedicatedAllocateInfo dedicated_info = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO , nullptr ,
VK_NULL_HANDLE , imported_buffer } ;
const VkImportMemoryHostPointerInfoEXT import_info = {
VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT ,
dedicated_requirements . requiresDedicatedAllocation ? & dedicated_info : nullptr ,
VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT , const_cast < void * > ( data_aligned ) } ;
const VkMemoryAllocateInfo alloc_info = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO , & import_info , data_size_aligned ,
memory_index } ;
@ -2687,34 +2744,19 @@ bool VulkanDevice::TryImportHostMemory(void* data, size_t data_size, VkBufferUsa
if ( res ! = VK_SUCCESS )
{
Vulkan : : SetErrorObject ( error , " vkAllocateMemory() failed: " , res ) ;
vkDestroyBuffer ( m_device , imported_buffer , nullptr ) ;
return false ;
}
const VkExternalMemoryBufferCreateInfo external_info = { VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO , nullptr ,
VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT } ;
const VkBufferCreateInfo buffer_info = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO ,
& external_info ,
0 ,
data_size_aligned ,
buffer_usage ,
VK_SHARING_MODE_EXCLUSIVE ,
0 ,
nullptr } ;
VkBuffer imported_buffer = VK_NULL_HANDLE ;
res = vkCreateBuffer ( m_device , & buffer_info , nullptr , & imported_buffer ) ;
res = vkBindBufferMemory ( m_device , imported_buffer , imported_memory , 0 ) ;
if ( res ! = VK_SUCCESS )
{
Vulkan : : SetErrorObject ( error , " vkCreateBuffer() failed: " , res ) ;
if ( imported_memory ! = VK_NULL_HANDLE )
vkFreeMemory ( m_device , imported_memory , nullptr ) ;
Vulkan : : SetErrorObject ( error , " vkBindBufferMemory() failed: " , res ) ;
vkFreeMemory ( m_device , imported_memory , nullptr ) ;
vkDestroyBuffer ( m_device , imported_buffer , nullptr ) ;
return false ;
}
vkBindBufferMemory ( m_device , imported_buffer , imported_memory , 0 ) ;
* out_memory = imported_memory ;
* out_buffer = imported_buffer ;
* out_offset = data_offset ;