mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-29 21:30:53 +00:00
Handle multiple pages in a row being too full
* When resetting pagesets in a granular fashion from the chunk allocator, it's possible to almost (or completely) exhaust a page but not have it be bumped out of the free list, then one more new full free pages is pushed. When that free page is exhausted we'll retire it then assume the next one is usable - but it is still not valid. We need to loop until we find a page with enough space.
This commit is contained in:
@@ -1142,18 +1142,19 @@ byte *ChunkAllocator::AllocateFromPages(bool chunkAlloc, size_t size)
|
||||
if(size > BufferPageSize)
|
||||
return NULL;
|
||||
|
||||
if(!freePages.empty())
|
||||
while(!freePages.empty())
|
||||
{
|
||||
// if the last free page can't satisfy this allocation, retire it to the full list
|
||||
if((chunkAlloc && GetRemainingChunkBytes(freePages.back()) < size) ||
|
||||
(!chunkAlloc && GetRemainingBufferBytes(freePages.back()) < size))
|
||||
{
|
||||
// mark this page as used in the current set
|
||||
usedPages.push_back(freePages.back().ID);
|
||||
// if the last free page can satisfy this allocation, stop iterating as we'll use it.
|
||||
if(GetRemainingBytes(chunkAlloc, freePages.back()) >= size)
|
||||
break;
|
||||
|
||||
fullPages.push_back(freePages.back());
|
||||
freePages.pop_back();
|
||||
}
|
||||
// otherwise the last page doesn't have enough free, so remove it from the free list
|
||||
|
||||
// mark this page as used in the current set
|
||||
usedPages.push_back(freePages.back().ID);
|
||||
|
||||
fullPages.push_back(freePages.back());
|
||||
freePages.pop_back();
|
||||
}
|
||||
|
||||
// if there are no free pages, allocate a new one
|
||||
|
||||
@@ -1585,14 +1585,18 @@ private:
|
||||
// includes it there
|
||||
rdcarray<uint32_t> usedPages;
|
||||
|
||||
size_t GetRemainingBufferBytes(const Page &p)
|
||||
inline size_t GetRemainingBufferBytes(const Page &p)
|
||||
{
|
||||
return BufferPageSize - (p.bufferHead - p.bufferBase);
|
||||
}
|
||||
size_t GetRemainingChunkBytes(const Page &p)
|
||||
inline size_t GetRemainingChunkBytes(const Page &p)
|
||||
{
|
||||
return ChunkPageSize - (p.chunkHead - p.chunkBase);
|
||||
}
|
||||
inline size_t GetRemainingBytes(bool chunkAlloc, const Page &p)
|
||||
{
|
||||
return chunkAlloc ? GetRemainingChunkBytes(p) : GetRemainingBufferBytes(p);
|
||||
}
|
||||
byte *AllocateFromPages(bool chunkAlloc, size_t size);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user