@@ -1839,14 +1839,139 @@ static void TestLinearAllocator()
18391839 bufInfo.clear ();
18401840 }
18411841
1842- // Try to create pool with maxBlockCount higher than 1. It should fail.
1842+ vmaDestroyPool (g_hAllocator, pool);
1843+ }
1844+
1845+ static void TestLinearAllocatorMultiBlock ()
1846+ {
1847+ wprintf (L" Test linear allocator multi block\n " );
1848+
1849+ RandomNumberGenerator rand{345673 };
1850+
1851+ VkBufferCreateInfo sampleBufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
1852+ sampleBufCreateInfo.size = 1024 * 1024 ;
1853+ sampleBufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
1854+
1855+ VmaAllocationCreateInfo sampleAllocCreateInfo = {};
1856+ sampleAllocCreateInfo.usage = VMA_MEMORY_USAGE_CPU_ONLY;
1857+
1858+ VmaPoolCreateInfo poolCreateInfo = {};
1859+ poolCreateInfo.flags = VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT;
1860+ VkResult res = vmaFindMemoryTypeIndexForBufferInfo (g_hAllocator, &sampleBufCreateInfo, &sampleAllocCreateInfo, &poolCreateInfo.memoryTypeIndex );
1861+ assert (res == VK_SUCCESS);
1862+
1863+ VmaPool pool = nullptr ;
1864+ res = vmaCreatePool (g_hAllocator, &poolCreateInfo, &pool);
1865+ assert (res == VK_SUCCESS);
1866+
1867+ VkBufferCreateInfo bufCreateInfo = sampleBufCreateInfo;
1868+
1869+ VmaAllocationCreateInfo allocCreateInfo = {};
1870+ allocCreateInfo.pool = pool;
1871+
1872+ std::vector<BufferInfo> bufInfo;
1873+ VmaAllocationInfo allocInfo;
1874+
1875+ // Test one-time free.
18431876 {
1844- VmaPoolCreateInfo altPoolCreateInfo = poolCreateInfo;
1845- altPoolCreateInfo.maxBlockCount = 2 ;
1877+ // Allocate buffers until we move to a second block.
1878+ VkDeviceMemory lastMem = VK_NULL_HANDLE;
1879+ for (uint32_t i = 0 ; ; ++i)
1880+ {
1881+ BufferInfo newBufInfo;
1882+ res = vmaCreateBuffer (g_hAllocator, &bufCreateInfo, &allocCreateInfo,
1883+ &newBufInfo.Buffer , &newBufInfo.Allocation , &allocInfo);
1884+ assert (res == VK_SUCCESS);
1885+ bufInfo.push_back (newBufInfo);
1886+ if (lastMem && allocInfo.deviceMemory != lastMem)
1887+ {
1888+ break ;
1889+ }
1890+ lastMem = allocInfo.deviceMemory ;
1891+ }
1892+
1893+ assert (bufInfo.size () > 2 );
18461894
1847- VmaPool altPool = nullptr ;
1848- res = vmaCreatePool (g_hAllocator, &altPoolCreateInfo, &altPool);
1849- assert (res != VK_SUCCESS);
1895+ // Make sure that pool has now two blocks.
1896+ VmaPoolStats poolStats = {};
1897+ vmaGetPoolStats (g_hAllocator, pool, &poolStats);
1898+ assert (poolStats.blockCount == 2 );
1899+
1900+ // Destroy all the buffers in random order.
1901+ while (!bufInfo.empty ())
1902+ {
1903+ const size_t indexToDestroy = rand.Generate () % bufInfo.size ();
1904+ const BufferInfo& currBufInfo = bufInfo[indexToDestroy];
1905+ vmaDestroyBuffer (g_hAllocator, currBufInfo.Buffer , currBufInfo.Allocation );
1906+ bufInfo.erase (bufInfo.begin () + indexToDestroy);
1907+ }
1908+
1909+ // Make sure that pool has now at most one block.
1910+ vmaGetPoolStats (g_hAllocator, pool, &poolStats);
1911+ assert (poolStats.blockCount <= 1 );
1912+ }
1913+
1914+ // Test stack.
1915+ {
1916+ // Allocate buffers until we move to a second block.
1917+ VkDeviceMemory lastMem = VK_NULL_HANDLE;
1918+ for (uint32_t i = 0 ; ; ++i)
1919+ {
1920+ BufferInfo newBufInfo;
1921+ res = vmaCreateBuffer (g_hAllocator, &bufCreateInfo, &allocCreateInfo,
1922+ &newBufInfo.Buffer , &newBufInfo.Allocation , &allocInfo);
1923+ assert (res == VK_SUCCESS);
1924+ bufInfo.push_back (newBufInfo);
1925+ if (lastMem && allocInfo.deviceMemory != lastMem)
1926+ {
1927+ break ;
1928+ }
1929+ lastMem = allocInfo.deviceMemory ;
1930+ }
1931+
1932+ assert (bufInfo.size () > 2 );
1933+
1934+ // Add few more buffers.
1935+ for (uint32_t i = 0 ; i < 5 ; ++i)
1936+ {
1937+ BufferInfo newBufInfo;
1938+ res = vmaCreateBuffer (g_hAllocator, &bufCreateInfo, &allocCreateInfo,
1939+ &newBufInfo.Buffer , &newBufInfo.Allocation , &allocInfo);
1940+ assert (res == VK_SUCCESS);
1941+ bufInfo.push_back (newBufInfo);
1942+ }
1943+
1944+ // Make sure that pool has now two blocks.
1945+ VmaPoolStats poolStats = {};
1946+ vmaGetPoolStats (g_hAllocator, pool, &poolStats);
1947+ assert (poolStats.blockCount == 2 );
1948+
1949+ // Delete half of buffers, LIFO.
1950+ for (size_t i = 0 , countToDelete = bufInfo.size () / 2 ; i < countToDelete; ++i)
1951+ {
1952+ const BufferInfo& currBufInfo = bufInfo.back ();
1953+ vmaDestroyBuffer (g_hAllocator, currBufInfo.Buffer , currBufInfo.Allocation );
1954+ bufInfo.pop_back ();
1955+ }
1956+
1957+ // Add one more buffer.
1958+ BufferInfo newBufInfo;
1959+ res = vmaCreateBuffer (g_hAllocator, &bufCreateInfo, &allocCreateInfo,
1960+ &newBufInfo.Buffer , &newBufInfo.Allocation , &allocInfo);
1961+ assert (res == VK_SUCCESS);
1962+ bufInfo.push_back (newBufInfo);
1963+
1964+ // Make sure that pool has now one block.
1965+ vmaGetPoolStats (g_hAllocator, pool, &poolStats);
1966+ assert (poolStats.blockCount == 1 );
1967+
1968+ // Delete all the remaining buffers, LIFO.
1969+ while (!bufInfo.empty ())
1970+ {
1971+ const BufferInfo& currBufInfo = bufInfo.back ();
1972+ vmaDestroyBuffer (g_hAllocator, currBufInfo.Buffer , currBufInfo.Allocation );
1973+ bufInfo.pop_back ();
1974+ }
18501975 }
18511976
18521977 vmaDestroyPool (g_hAllocator, pool);
@@ -3841,6 +3966,16 @@ void Test()
38413966{
38423967 wprintf (L" TESTING:\n " );
38433968
3969+ if (false )
3970+ {
3971+ // # Temporarily insert custom tests here
3972+ TestLinearAllocator ();
3973+ ManuallyTestLinearAllocator ();
3974+ TestLinearAllocatorMultiBlock ();
3975+ BenchmarkLinearAllocator ();
3976+ return ;
3977+ }
3978+
38443979 // # Simple tests
38453980
38463981 TestBasics ();
@@ -3857,6 +3992,7 @@ void Test()
38573992 TestMappingMultithreaded ();
38583993 TestLinearAllocator ();
38593994 ManuallyTestLinearAllocator ();
3995+ TestLinearAllocatorMultiBlock ();
38603996 BenchmarkLinearAllocator ();
38613997 TestDefragmentationSimple ();
38623998 TestDefragmentationFull ();
0 commit comments