Fix VmaAllocator_T::AllocateMemory for case when VMA_ALLOCATION_CREATE_MAPPED_BIT is used with custom memory pool created in memory type that is not VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT

Also add test for it - function TestDeviceLocalMapped.
This commit is contained in:
Adam Sawicki 2019-06-25 15:26:37 +02:00
parent 0198e4b3ad
commit daa6a551f8
2 changed files with 56 additions and 1 deletions

View File

@ -4107,6 +4107,51 @@ static void TestMapping()
}
}
// Test CREATE_MAPPED with required DEVICE_LOCAL. There was a bug with it.
static void TestDeviceLocalMapped()
{
VkResult res;
for(uint32_t testIndex = 0; testIndex < 3; ++testIndex)
{
VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
bufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
bufCreateInfo.size = 4096;
VmaPool pool = VK_NULL_HANDLE;
VmaAllocationCreateInfo allocCreateInfo = {};
allocCreateInfo.requiredFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
allocCreateInfo.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT;
if(testIndex == 2)
{
VmaPoolCreateInfo poolCreateInfo = {};
res = vmaFindMemoryTypeIndexForBufferInfo(g_hAllocator, &bufCreateInfo, &allocCreateInfo, &poolCreateInfo.memoryTypeIndex);
TEST(res == VK_SUCCESS);
res = vmaCreatePool(g_hAllocator, &poolCreateInfo, &pool);
TEST(res == VK_SUCCESS);
allocCreateInfo.pool = pool;
}
else if(testIndex == 1)
{
allocCreateInfo.flags |= VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT;
}
VkBuffer buf = VK_NULL_HANDLE;
VmaAllocation alloc = VK_NULL_HANDLE;
VmaAllocationInfo allocInfo = {};
res = vmaCreateBuffer(g_hAllocator, &bufCreateInfo, &allocCreateInfo, &buf, &alloc, &allocInfo);
TEST(res == VK_SUCCESS && alloc);
VkMemoryPropertyFlags memTypeFlags = 0;
vmaGetMemoryTypeProperties(g_hAllocator, allocInfo.memoryType, &memTypeFlags);
const bool shouldBeMapped = (memTypeFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0;
TEST((allocInfo.pMappedData != nullptr) == shouldBeMapped);
vmaDestroyBuffer(g_hAllocator, buf, alloc);
vmaDestroyPool(g_hAllocator, pool);
}
}
static void TestMappingMultithreaded()
{
wprintf(L"Testing mapping multithreaded...\n");
@ -5206,6 +5251,7 @@ void Test()
TestAllocationsInitialization();
#endif
TestMapping();
TestDeviceLocalMapped();
TestMappingMultithreaded();
TestLinearAllocator();
ManuallyTestLinearAllocator();

View File

@ -14812,11 +14812,20 @@ VkResult VmaAllocator_T::AllocateMemory(
const VkDeviceSize alignmentForPool = VMA_MAX(
vkMemReq.alignment,
GetMemoryTypeMinAlignment(createInfo.pool->m_BlockVector.GetMemoryTypeIndex()));
VmaAllocationCreateInfo createInfoForPool = createInfo;
// If memory type is not HOST_VISIBLE, disable MAPPED.
if((createInfoForPool.flags & VMA_ALLOCATION_CREATE_MAPPED_BIT) != 0 &&
(m_MemProps.memoryTypes[createInfo.pool->m_BlockVector.GetMemoryTypeIndex()].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == 0)
{
createInfoForPool.flags &= ~VMA_ALLOCATION_CREATE_MAPPED_BIT;
}
return createInfo.pool->m_BlockVector.Allocate(
m_CurrentFrameIndex.load(),
vkMemReq.size,
alignmentForPool,
createInfo,
createInfoForPool,
suballocType,
allocationCount,
pAllocations);