Skip to content

Commit e833b3e

Browse files
Fixed VmaDeviceMemoryBlock::Map for mapping hysteresis to work correctly when the mapping fails
Also added test for it. Fixes #407 - thanks @matusfedorko
1 parent 2f4a2d2 commit e833b3e

File tree

2 files changed

+36
-3
lines changed

2 files changed

+36
-3
lines changed

include/vk_mem_alloc.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10443,11 +10443,11 @@ VkResult VmaDeviceMemoryBlock::Map(VmaAllocator hAllocator, uint32_t count, void
1044310443

1044410444
VmaMutexLock lock(m_MapAndBindMutex, hAllocator->m_UseMutex);
1044510445
const uint32_t oldTotalMapCount = m_MapCount + m_MappingHysteresis.GetExtraMapping();
10446-
m_MappingHysteresis.PostMap();
1044710446
if (oldTotalMapCount != 0)
1044810447
{
10449-
m_MapCount += count;
1045010448
VMA_ASSERT(m_pMappedData != VMA_NULL);
10449+
m_MappingHysteresis.PostMap();
10450+
m_MapCount += count;
1045110451
if (ppData != VMA_NULL)
1045210452
{
1045310453
*ppData = m_pMappedData;
@@ -10465,11 +10465,13 @@ VkResult VmaDeviceMemoryBlock::Map(VmaAllocator hAllocator, uint32_t count, void
1046510465
&m_pMappedData);
1046610466
if (result == VK_SUCCESS)
1046710467
{
10468+
VMA_ASSERT(m_pMappedData != VMA_NULL);
10469+
m_MappingHysteresis.PostMap();
10470+
m_MapCount = count;
1046810471
if (ppData != VMA_NULL)
1046910472
{
1047010473
*ppData = m_pMappedData;
1047110474
}
10472-
m_MapCount = count;
1047310475
}
1047410476
return result;
1047510477
}

src/Tests.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8079,6 +8079,37 @@ static void TestMappingHysteresis()
80798079

80808080
vmaDestroyPool(g_hAllocator, pool);
80818081
}
8082+
8083+
// Test hysteresis working currectly in case the mapping fails. See issue #407.
8084+
{
8085+
VkBufferCreateInfo bufCreateInfo = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
8086+
bufCreateInfo.size = 1 * MEGABYTE;
8087+
bufCreateInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
8088+
8089+
VmaAllocationCreateInfo allocCreateInfo = {};
8090+
allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;
8091+
8092+
VkBuffer buf;
8093+
VmaAllocation alloc;
8094+
TEST(vmaCreateBuffer(g_hAllocator, &bufCreateInfo, &allocCreateInfo,
8095+
&buf, &alloc, nullptr) == VK_SUCCESS);
8096+
8097+
VkMemoryPropertyFlags memProps = 0;
8098+
vmaGetAllocationMemoryProperties(g_hAllocator, alloc, &memProps);
8099+
8100+
// It makes sense to test only if this buffer ended up in a non-HOST_VISIBLE memory,
8101+
// which may not be the case on some integrated graphics.
8102+
if((memProps & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == 0)
8103+
{
8104+
void* ptr;
8105+
for (size_t i = 0; i < 10; ++i)
8106+
{
8107+
TEST(vmaMapMemory(g_hAllocator, alloc, &ptr) == VK_ERROR_MEMORY_MAP_FAILED);
8108+
}
8109+
}
8110+
8111+
vmaDestroyBuffer(g_hAllocator, buf, alloc);
8112+
}
80828113
}
80838114

80848115
void Test()

0 commit comments

Comments
 (0)