@@ -2916,7 +2916,7 @@ class VmaList
2916
2916
}
2917
2917
else
2918
2918
{
2919
- VMA_HEAVY_ASSERT (!m_pList. IsEmpty ());
2919
+ VMA_HEAVY_ASSERT (!m_pList-> IsEmpty ());
2920
2920
m_pItem = m_pList->Back ();
2921
2921
}
2922
2922
return *this ;
@@ -3243,14 +3243,9 @@ struct VmaAllocation_T
3243
3243
}
3244
3244
3245
3245
void ChangeBlockAllocation (
3246
+ VmaAllocator hAllocator,
3246
3247
VmaDeviceMemoryBlock* block,
3247
- VkDeviceSize offset)
3248
- {
3249
- VMA_ASSERT (block != VMA_NULL);
3250
- VMA_ASSERT (m_Type == ALLOCATION_TYPE_BLOCK);
3251
- m_BlockAllocation.m_Block = block;
3252
- m_BlockAllocation.m_Offset = offset;
3253
- }
3248
+ VkDeviceSize offset);
3254
3249
3255
3250
// pMappedData not null means allocation is created with MAPPED flag.
3256
3251
void InitDedicatedAllocation (
@@ -3337,7 +3332,7 @@ struct VmaAllocation_T
3337
3332
uint8_t m_Type; // ALLOCATION_TYPE
3338
3333
uint8_t m_SuballocationType; // VmaSuballocationType
3339
3334
// Bit 0x80 is set when allocation was created with VMA_ALLOCATION_CREATE_MAPPED_BIT.
3340
- // Bits with mask 0x7F, used only when ALLOCATION_TYPE_DEDICATED, are reference counter for vmaMapMemory()/vmaUnmapMemory().
3335
+ // Bits with mask 0x7F are reference counter for vmaMapMemory()/vmaUnmapMemory().
3341
3336
uint8_t m_MapCount;
3342
3337
uint8_t m_Flags; // enum FLAGS
3343
3338
@@ -3472,6 +3467,7 @@ class VmaBlockMetadata
3472
3467
3473
3468
// Frees suballocation assigned to given memory region.
3474
3469
void Free (const VmaAllocation allocation);
3470
+ void FreeAtOffset (VkDeviceSize offset);
3475
3471
3476
3472
private:
3477
3473
VkDeviceSize m_Size;
@@ -3523,8 +3519,8 @@ class VmaDeviceMemoryMapping
3523
3519
void * GetMappedData () const { return m_pMappedData; }
3524
3520
3525
3521
// ppData can be null.
3526
- VkResult Map (VmaAllocator hAllocator, VkDeviceMemory hMemory, void **ppData);
3527
- void Unmap (VmaAllocator hAllocator, VkDeviceMemory hMemory);
3522
+ VkResult Map (VmaAllocator hAllocator, VkDeviceMemory hMemory, uint32_t count, void **ppData);
3523
+ void Unmap (VmaAllocator hAllocator, VkDeviceMemory hMemory, uint32_t count );
3528
3524
3529
3525
private:
3530
3526
VMA_MUTEX m_Mutex;
@@ -3565,8 +3561,8 @@ class VmaDeviceMemoryBlock
3565
3561
bool Validate () const ;
3566
3562
3567
3563
// ppData can be null.
3568
- VkResult Map (VmaAllocator hAllocator, void ** ppData);
3569
- void Unmap (VmaAllocator hAllocator);
3564
+ VkResult Map (VmaAllocator hAllocator, uint32_t count, void ** ppData);
3565
+ void Unmap (VmaAllocator hAllocator, uint32_t count );
3570
3566
};
3571
3567
3572
3568
struct VmaPointerLess
@@ -4388,6 +4384,28 @@ void VmaAllocation_T::SetUserData(VmaAllocator hAllocator, void* pUserData)
4388
4384
}
4389
4385
}
4390
4386
4387
+ void VmaAllocation_T::ChangeBlockAllocation (
4388
+ VmaAllocator hAllocator,
4389
+ VmaDeviceMemoryBlock* block,
4390
+ VkDeviceSize offset)
4391
+ {
4392
+ VMA_ASSERT (block != VMA_NULL);
4393
+ VMA_ASSERT (m_Type == ALLOCATION_TYPE_BLOCK);
4394
+
4395
+ // Move mapping reference counter from old block to new block.
4396
+ if (block != m_BlockAllocation.m_Block )
4397
+ {
4398
+ uint32_t mapRefCount = m_MapCount & ~MAP_COUNT_FLAG_PERSISTENT_MAP;
4399
+ if (IsPersistentMap ())
4400
+ ++mapRefCount;
4401
+ m_BlockAllocation.m_Block ->Unmap (hAllocator, mapRefCount);
4402
+ block->Map (hAllocator, mapRefCount, VMA_NULL);
4403
+ }
4404
+
4405
+ m_BlockAllocation.m_Block = block;
4406
+ m_BlockAllocation.m_Offset = offset;
4407
+ }
4408
+
4391
4409
VkDeviceSize VmaAllocation_T::GetOffset () const
4392
4410
{
4393
4411
switch (m_Type)
@@ -4754,7 +4772,6 @@ bool VmaBlockMetadata::Validate() const
4754
4772
{
4755
4773
return false ;
4756
4774
}
4757
- prevFree = currFree;
4758
4775
4759
4776
if (currFree != (subAlloc.hAllocation == VK_NULL_HANDLE))
4760
4777
{
@@ -4770,8 +4787,20 @@ bool VmaBlockMetadata::Validate() const
4770
4787
++freeSuballocationsToRegister;
4771
4788
}
4772
4789
}
4790
+ else
4791
+ {
4792
+ if (subAlloc.hAllocation ->GetOffset () != subAlloc.offset )
4793
+ {
4794
+ return false ;
4795
+ }
4796
+ if (subAlloc.hAllocation ->GetSize () != subAlloc.size )
4797
+ {
4798
+ return false ;
4799
+ }
4800
+ }
4773
4801
4774
4802
calculatedOffset += subAlloc.size ;
4803
+ prevFree = currFree;
4775
4804
}
4776
4805
4777
4806
// Number of free suballocations registered in m_FreeSuballocationsBySize doesn't
@@ -4801,11 +4830,15 @@ bool VmaBlockMetadata::Validate() const
4801
4830
}
4802
4831
4803
4832
// Check if totals match calculacted values.
4804
- return
4805
- ValidateFreeSuballocationList () &&
4806
- (calculatedOffset == m_Size) &&
4807
- (calculatedSumFreeSize == m_SumFreeSize) &&
4808
- (calculatedFreeCount == m_FreeCount);
4833
+ if (!ValidateFreeSuballocationList () ||
4834
+ (calculatedOffset != m_Size) ||
4835
+ (calculatedSumFreeSize != m_SumFreeSize) ||
4836
+ (calculatedFreeCount != m_FreeCount))
4837
+ {
4838
+ return false ;
4839
+ }
4840
+
4841
+ return true ;
4809
4842
}
4810
4843
4811
4844
VkDeviceSize VmaBlockMetadata::GetUnusedRangeSizeMax () const
@@ -5214,6 +5247,22 @@ void VmaBlockMetadata::Free(const VmaAllocation allocation)
5214
5247
VMA_ASSERT (0 && " Not found!" );
5215
5248
}
5216
5249
5250
+ void VmaBlockMetadata::FreeAtOffset (VkDeviceSize offset)
5251
+ {
5252
+ for (VmaSuballocationList::iterator suballocItem = m_Suballocations.begin ();
5253
+ suballocItem != m_Suballocations.end ();
5254
+ ++suballocItem)
5255
+ {
5256
+ VmaSuballocation& suballoc = *suballocItem;
5257
+ if (suballoc.offset == offset)
5258
+ {
5259
+ FreeSuballocation (suballocItem);
5260
+ return ;
5261
+ }
5262
+ }
5263
+ VMA_ASSERT (0 && " Not found!" );
5264
+ }
5265
+
5217
5266
bool VmaBlockMetadata::ValidateFreeSuballocationList () const
5218
5267
{
5219
5268
VkDeviceSize lastSize = 0 ;
@@ -5663,12 +5712,17 @@ VmaDeviceMemoryMapping::~VmaDeviceMemoryMapping()
5663
5712
VMA_ASSERT (m_MapCount == 0 && " VkDeviceMemory block is being destroyed while it is still mapped." );
5664
5713
}
5665
5714
5666
- VkResult VmaDeviceMemoryMapping::Map (VmaAllocator hAllocator, VkDeviceMemory hMemory, void **ppData)
5715
+ VkResult VmaDeviceMemoryMapping::Map (VmaAllocator hAllocator, VkDeviceMemory hMemory, uint32_t count, void **ppData)
5667
5716
{
5717
+ if (count == 0 )
5718
+ {
5719
+ return VK_SUCCESS;
5720
+ }
5721
+
5668
5722
VmaMutexLock lock (m_Mutex, hAllocator->m_UseMutex );
5669
5723
if (m_MapCount != 0 )
5670
5724
{
5671
- ++ m_MapCount;
5725
+ m_MapCount += count ;
5672
5726
VMA_ASSERT (m_pMappedData != VMA_NULL);
5673
5727
if (ppData != VMA_NULL)
5674
5728
{
@@ -5691,18 +5745,24 @@ VkResult VmaDeviceMemoryMapping::Map(VmaAllocator hAllocator, VkDeviceMemory hMe
5691
5745
{
5692
5746
*ppData = m_pMappedData;
5693
5747
}
5694
- m_MapCount = 1 ;
5748
+ m_MapCount = count ;
5695
5749
}
5696
5750
return result;
5697
5751
}
5698
5752
}
5699
5753
5700
- void VmaDeviceMemoryMapping::Unmap (VmaAllocator hAllocator, VkDeviceMemory hMemory)
5754
+ void VmaDeviceMemoryMapping::Unmap (VmaAllocator hAllocator, VkDeviceMemory hMemory, uint32_t count )
5701
5755
{
5756
+ if (count == 0 )
5757
+ {
5758
+ return ;
5759
+ }
5760
+
5702
5761
VmaMutexLock lock (m_Mutex, hAllocator->m_UseMutex );
5703
- if (m_MapCount != 0 )
5762
+ if (m_MapCount >= count )
5704
5763
{
5705
- if (--m_MapCount == 0 )
5764
+ m_MapCount -= count;
5765
+ if (m_MapCount == 0 )
5706
5766
{
5707
5767
m_pMappedData = VMA_NULL;
5708
5768
(*hAllocator->GetVulkanFunctions ().vkUnmapMemory )(hAllocator->m_hDevice , hMemory);
@@ -5759,14 +5819,14 @@ bool VmaDeviceMemoryBlock::Validate() const
5759
5819
return m_Metadata.Validate ();
5760
5820
}
5761
5821
5762
- VkResult VmaDeviceMemoryBlock::Map (VmaAllocator hAllocator, void ** ppData)
5822
+ VkResult VmaDeviceMemoryBlock::Map (VmaAllocator hAllocator, uint32_t count, void ** ppData)
5763
5823
{
5764
- return m_Mapping.Map (hAllocator, m_hMemory, ppData);
5824
+ return m_Mapping.Map (hAllocator, m_hMemory, count, ppData);
5765
5825
}
5766
5826
5767
- void VmaDeviceMemoryBlock::Unmap (VmaAllocator hAllocator)
5827
+ void VmaDeviceMemoryBlock::Unmap (VmaAllocator hAllocator, uint32_t count )
5768
5828
{
5769
- m_Mapping.Unmap (hAllocator, m_hMemory);
5829
+ m_Mapping.Unmap (hAllocator, m_hMemory, count );
5770
5830
}
5771
5831
5772
5832
static void InitStatInfo (VmaStatInfo& outInfo)
@@ -5924,7 +5984,7 @@ VkResult VmaBlockVector::Allocate(
5924
5984
5925
5985
if (mapped)
5926
5986
{
5927
- VkResult res = pCurrBlock->Map (m_hAllocator, nullptr );
5987
+ VkResult res = pCurrBlock->Map (m_hAllocator, 1 , VMA_NULL );
5928
5988
if (res != VK_SUCCESS)
5929
5989
{
5930
5990
return res;
@@ -6016,7 +6076,7 @@ VkResult VmaBlockVector::Allocate(
6016
6076
6017
6077
if (mapped)
6018
6078
{
6019
- res = pBlock->Map (m_hAllocator, nullptr );
6079
+ res = pBlock->Map (m_hAllocator, 1 , VMA_NULL );
6020
6080
if (res != VK_SUCCESS)
6021
6081
{
6022
6082
return res;
@@ -6093,7 +6153,7 @@ VkResult VmaBlockVector::Allocate(
6093
6153
{
6094
6154
if (mapped)
6095
6155
{
6096
- VkResult res = pBestRequestBlock->Map (m_hAllocator, nullptr );
6156
+ VkResult res = pBestRequestBlock->Map (m_hAllocator, 1 , VMA_NULL );
6097
6157
if (res != VK_SUCCESS)
6098
6158
{
6099
6159
return res;
@@ -6122,7 +6182,7 @@ VkResult VmaBlockVector::Allocate(
6122
6182
suballocType,
6123
6183
mapped,
6124
6184
(createInfo.flags & VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT) != 0 );
6125
- VMA_HEAVY_ASSERT (pBlock ->Validate ());
6185
+ VMA_HEAVY_ASSERT (pBestRequestBlock ->Validate ());
6126
6186
VMA_DEBUG_LOG (" Returned from existing allocation #%u" , (uint32_t )blockIndex);
6127
6187
(*pAllocation)->SetUserData (m_hAllocator, createInfo.pUserData );
6128
6188
return VK_SUCCESS;
@@ -6160,7 +6220,7 @@ void VmaBlockVector::Free(
6160
6220
6161
6221
if (hAllocation->IsPersistentMap ())
6162
6222
{
6163
- pBlock->m_Mapping .Unmap (m_hAllocator, pBlock->m_hMemory );
6223
+ pBlock->m_Mapping .Unmap (m_hAllocator, pBlock->m_hMemory , 1 );
6164
6224
}
6165
6225
6166
6226
pBlock->m_Metadata .Free (hAllocation);
@@ -6505,7 +6565,7 @@ VkResult VmaDefragmentator::BlockInfo::EnsureMapping(VmaAllocator hAllocator, vo
6505
6565
}
6506
6566
6507
6567
// Map on first usage.
6508
- VkResult res = m_pBlock->Map (hAllocator, &m_pMappedDataForDefragmentation);
6568
+ VkResult res = m_pBlock->Map (hAllocator, 1 , &m_pMappedDataForDefragmentation);
6509
6569
*ppMappedData = m_pMappedDataForDefragmentation;
6510
6570
return res;
6511
6571
}
@@ -6514,7 +6574,7 @@ void VmaDefragmentator::BlockInfo::Unmap(VmaAllocator hAllocator)
6514
6574
{
6515
6575
if (m_pMappedDataForDefragmentation != VMA_NULL)
6516
6576
{
6517
- m_pBlock->Unmap (hAllocator);
6577
+ m_pBlock->Unmap (hAllocator, 1 );
6518
6578
}
6519
6579
}
6520
6580
@@ -6610,10 +6670,10 @@ VkResult VmaDefragmentator::DefragmentRound(
6610
6670
static_cast <size_t >(size));
6611
6671
6612
6672
pDstBlockInfo->m_pBlock ->m_Metadata .Alloc (dstAllocRequest, suballocType, size, allocInfo.m_hAllocation );
6613
- pSrcBlockInfo->m_pBlock ->m_Metadata .Free (allocInfo.m_hAllocation );
6614
-
6615
- allocInfo.m_hAllocation ->ChangeBlockAllocation (pDstBlockInfo->m_pBlock , dstAllocRequest.offset );
6673
+ pSrcBlockInfo->m_pBlock ->m_Metadata .FreeAtOffset (srcOffset);
6616
6674
6675
+ allocInfo.m_hAllocation ->ChangeBlockAllocation (m_hAllocator, pDstBlockInfo->m_pBlock , dstAllocRequest.offset );
6676
+
6617
6677
if (allocInfo.m_pChanged != VMA_NULL)
6618
6678
{
6619
6679
*allocInfo.m_pChanged = VK_TRUE;
@@ -7055,7 +7115,7 @@ VkResult VmaAllocator_T::AllocateDedicatedMemory(
7055
7115
return res;
7056
7116
}
7057
7117
7058
- void * pMappedData = nullptr ;
7118
+ void * pMappedData = VMA_NULL ;
7059
7119
if (map)
7060
7120
{
7061
7121
res = (*m_VulkanFunctions.vkMapMemory )(
@@ -7391,7 +7451,7 @@ VkResult VmaAllocator_T::Defragment(
7391
7451
// Lost allocation cannot be defragmented.
7392
7452
(hAlloc->GetLastUseFrameIndex () != VMA_FRAME_INDEX_LOST))
7393
7453
{
7394
- VmaBlockVector* pAllocBlockVector = nullptr ;
7454
+ VmaBlockVector* pAllocBlockVector = VMA_NULL ;
7395
7455
7396
7456
const VmaPool hAllocPool = hAlloc->GetPool ();
7397
7457
// This allocation belongs to custom pool.
@@ -7655,8 +7715,8 @@ VkResult VmaAllocator_T::Map(VmaAllocation hAllocation, void** ppData)
7655
7715
case VmaAllocation_T::ALLOCATION_TYPE_BLOCK:
7656
7716
{
7657
7717
VmaDeviceMemoryBlock* const pBlock = hAllocation->GetBlock ();
7658
- char *pBytes = nullptr ;
7659
- VkResult res = pBlock->Map (this , (void **)&pBytes);
7718
+ char *pBytes = VMA_NULL ;
7719
+ VkResult res = pBlock->Map (this , 1 , (void **)&pBytes);
7660
7720
if (res == VK_SUCCESS)
7661
7721
{
7662
7722
*ppData = pBytes + (ptrdiff_t )hAllocation->GetOffset ();
@@ -7680,7 +7740,7 @@ void VmaAllocator_T::Unmap(VmaAllocation hAllocation)
7680
7740
{
7681
7741
VmaDeviceMemoryBlock* const pBlock = hAllocation->GetBlock ();
7682
7742
hAllocation->BlockAllocUnmap ();
7683
- pBlock->Unmap (this );
7743
+ pBlock->Unmap (this , 1 );
7684
7744
}
7685
7745
break ;
7686
7746
case VmaAllocation_T::ALLOCATION_TYPE_DEDICATED:
0 commit comments