@@ -1839,14 +1839,139 @@ static void TestLinearAllocator()
1839
1839
bufInfo.clear ();
1840
1840
}
1841
1841
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.
1843
1876
{
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 );
1846
1894
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
+ }
1850
1975
}
1851
1976
1852
1977
vmaDestroyPool (g_hAllocator, pool);
@@ -3841,6 +3966,16 @@ void Test()
3841
3966
{
3842
3967
wprintf (L" TESTING:\n " );
3843
3968
3969
+ if (false )
3970
+ {
3971
+ // # Temporarily insert custom tests here
3972
+ TestLinearAllocator ();
3973
+ ManuallyTestLinearAllocator ();
3974
+ TestLinearAllocatorMultiBlock ();
3975
+ BenchmarkLinearAllocator ();
3976
+ return ;
3977
+ }
3978
+
3844
3979
// # Simple tests
3845
3980
3846
3981
TestBasics ();
@@ -3857,6 +3992,7 @@ void Test()
3857
3992
TestMappingMultithreaded ();
3858
3993
TestLinearAllocator ();
3859
3994
ManuallyTestLinearAllocator ();
3995
+ TestLinearAllocatorMultiBlock ();
3860
3996
BenchmarkLinearAllocator ();
3861
3997
TestDefragmentationSimple ();
3862
3998
TestDefragmentationFull ();
0 commit comments