Pull out freelist allocation from GrVkSubHeap
BUG=skia:5031 GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2128673002 Review-Url: https://codereview.chromium.org/2128673002
This commit is contained in:
parent
552882f768
commit
82356cc41f
@ -242,50 +242,9 @@ VkAccessFlags GrVkMemory::LayoutToSrcAccessMask(const VkImageLayout layout) {
|
|||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
GrVkSubHeap::GrVkSubHeap(const GrVkGpu* gpu, uint32_t memoryTypeIndex,
|
bool GrVkFreeListAlloc::alloc(VkDeviceSize requestedSize,
|
||||||
VkDeviceSize size, VkDeviceSize alignment)
|
VkDeviceSize* allocOffset, VkDeviceSize* allocSize) {
|
||||||
: fGpu(gpu)
|
VkDeviceSize alignedSize = align_size(requestedSize, fAlignment);
|
||||||
, fMemoryTypeIndex(memoryTypeIndex) {
|
|
||||||
|
|
||||||
VkMemoryAllocateInfo allocInfo = {
|
|
||||||
VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, // sType
|
|
||||||
NULL, // pNext
|
|
||||||
size, // allocationSize
|
|
||||||
memoryTypeIndex, // memoryTypeIndex
|
|
||||||
};
|
|
||||||
|
|
||||||
VkResult err = GR_VK_CALL(gpu->vkInterface(), AllocateMemory(gpu->device(),
|
|
||||||
&allocInfo,
|
|
||||||
nullptr,
|
|
||||||
&fAlloc));
|
|
||||||
|
|
||||||
if (VK_SUCCESS == err) {
|
|
||||||
fSize = size;
|
|
||||||
fAlignment = alignment;
|
|
||||||
fFreeSize = size;
|
|
||||||
fLargestBlockSize = size;
|
|
||||||
fLargestBlockOffset = 0;
|
|
||||||
|
|
||||||
Block* block = fFreeList.addToTail();
|
|
||||||
block->fOffset = 0;
|
|
||||||
block->fSize = fSize;
|
|
||||||
} else {
|
|
||||||
fSize = 0;
|
|
||||||
fAlignment = 0;
|
|
||||||
fFreeSize = 0;
|
|
||||||
fLargestBlockSize = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GrVkSubHeap::~GrVkSubHeap() {
|
|
||||||
const GrVkInterface* iface = fGpu->vkInterface();
|
|
||||||
GR_VK_CALL(iface, FreeMemory(fGpu->device(), fAlloc, nullptr));
|
|
||||||
|
|
||||||
fFreeList.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GrVkSubHeap::alloc(VkDeviceSize size, GrVkAlloc* alloc) {
|
|
||||||
VkDeviceSize alignedSize = align_size(size, fAlignment);
|
|
||||||
|
|
||||||
// find the smallest block big enough for our allocation
|
// find the smallest block big enough for our allocation
|
||||||
FreeList::Iter iter = fFreeList.headIter();
|
FreeList::Iter iter = fFreeList.headIter();
|
||||||
@ -311,10 +270,9 @@ bool GrVkSubHeap::alloc(VkDeviceSize size, GrVkAlloc* alloc) {
|
|||||||
|
|
||||||
Block* bestFit = bestFitIter.get();
|
Block* bestFit = bestFitIter.get();
|
||||||
if (bestFit) {
|
if (bestFit) {
|
||||||
alloc->fMemory = fAlloc;
|
|
||||||
SkASSERT(align_size(bestFit->fOffset, fAlignment) == bestFit->fOffset);
|
SkASSERT(align_size(bestFit->fOffset, fAlignment) == bestFit->fOffset);
|
||||||
alloc->fOffset = bestFit->fOffset;
|
*allocOffset = bestFit->fOffset;
|
||||||
alloc->fSize = alignedSize;
|
*allocSize = alignedSize;
|
||||||
// adjust or remove current block
|
// adjust or remove current block
|
||||||
VkDeviceSize originalBestFitOffset = bestFit->fOffset;
|
VkDeviceSize originalBestFitOffset = bestFit->fOffset;
|
||||||
if (bestFit->fSize > alignedSize) {
|
if (bestFit->fSize > alignedSize) {
|
||||||
@ -362,38 +320,35 @@ bool GrVkSubHeap::alloc(VkDeviceSize size, GrVkAlloc* alloc) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
fFreeSize -= alignedSize;
|
fFreeSize -= alignedSize;
|
||||||
SkASSERT(alloc->fSize > 0);
|
SkASSERT(allocSize > 0);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
SkDebugf("Can't allocate %d bytes, %d bytes available, largest free block %d\n", alignedSize, fFreeSize, fLargestBlockSize);
|
SkDebugf("Can't allocate %d bytes, %d bytes available, largest free block %d\n", alignedSize, fFreeSize, fLargestBlockSize);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GrVkFreeListAlloc::free(VkDeviceSize allocOffset, VkDeviceSize allocSize) {
|
||||||
void GrVkSubHeap::free(const GrVkAlloc& alloc) {
|
|
||||||
SkASSERT(alloc.fMemory == fAlloc);
|
|
||||||
|
|
||||||
// find the block right after this allocation
|
// find the block right after this allocation
|
||||||
FreeList::Iter iter = fFreeList.headIter();
|
FreeList::Iter iter = fFreeList.headIter();
|
||||||
FreeList::Iter prev;
|
FreeList::Iter prev;
|
||||||
while (iter.get() && iter.get()->fOffset < alloc.fOffset) {
|
while (iter.get() && iter.get()->fOffset < allocOffset) {
|
||||||
prev = iter;
|
prev = iter;
|
||||||
iter.next();
|
iter.next();
|
||||||
}
|
}
|
||||||
// we have four cases:
|
// we have four cases:
|
||||||
// we exactly follow the previous one
|
// we exactly follow the previous one
|
||||||
Block* block;
|
Block* block;
|
||||||
if (prev.get() && prev.get()->fOffset + prev.get()->fSize == alloc.fOffset) {
|
if (prev.get() && prev.get()->fOffset + prev.get()->fSize == allocOffset) {
|
||||||
block = prev.get();
|
block = prev.get();
|
||||||
block->fSize += alloc.fSize;
|
block->fSize += allocSize;
|
||||||
if (block->fOffset == fLargestBlockOffset) {
|
if (block->fOffset == fLargestBlockOffset) {
|
||||||
fLargestBlockSize = block->fSize;
|
fLargestBlockSize = block->fSize;
|
||||||
}
|
}
|
||||||
// and additionally we may exactly precede the next one
|
// and additionally we may exactly precede the next one
|
||||||
if (iter.get() && iter.get()->fOffset == alloc.fOffset + alloc.fSize) {
|
if (iter.get() && iter.get()->fOffset == allocOffset + allocSize) {
|
||||||
block->fSize += iter.get()->fSize;
|
block->fSize += iter.get()->fSize;
|
||||||
if (iter.get()->fOffset == fLargestBlockOffset) {
|
if (iter.get()->fOffset == fLargestBlockOffset) {
|
||||||
fLargestBlockOffset = block->fOffset;
|
fLargestBlockOffset = block->fOffset;
|
||||||
@ -402,21 +357,21 @@ void GrVkSubHeap::free(const GrVkAlloc& alloc) {
|
|||||||
fFreeList.remove(iter.get());
|
fFreeList.remove(iter.get());
|
||||||
}
|
}
|
||||||
// or we only exactly proceed the next one
|
// or we only exactly proceed the next one
|
||||||
} else if (iter.get() && iter.get()->fOffset == alloc.fOffset + alloc.fSize) {
|
} else if (iter.get() && iter.get()->fOffset == allocOffset + allocSize) {
|
||||||
block = iter.get();
|
block = iter.get();
|
||||||
block->fSize += alloc.fSize;
|
block->fSize += allocSize;
|
||||||
if (block->fOffset == fLargestBlockOffset) {
|
if (block->fOffset == fLargestBlockOffset) {
|
||||||
fLargestBlockOffset = alloc.fOffset;
|
fLargestBlockOffset = allocOffset;
|
||||||
fLargestBlockSize = block->fSize;
|
fLargestBlockSize = block->fSize;
|
||||||
}
|
}
|
||||||
block->fOffset = alloc.fOffset;
|
block->fOffset = allocOffset;
|
||||||
// or we fall somewhere in between, with gaps
|
// or we fall somewhere in between, with gaps
|
||||||
} else {
|
} else {
|
||||||
block = fFreeList.addBefore(iter);
|
block = fFreeList.addBefore(iter);
|
||||||
block->fOffset = alloc.fOffset;
|
block->fOffset = allocOffset;
|
||||||
block->fSize = alloc.fSize;
|
block->fSize = allocSize;
|
||||||
}
|
}
|
||||||
fFreeSize += alloc.fSize;
|
fFreeSize += allocSize;
|
||||||
if (block->fSize > fLargestBlockSize) {
|
if (block->fSize > fLargestBlockSize) {
|
||||||
fLargestBlockSize = block->fSize;
|
fLargestBlockSize = block->fSize;
|
||||||
fLargestBlockOffset = block->fOffset;
|
fLargestBlockOffset = block->fOffset;
|
||||||
@ -436,7 +391,42 @@ void GrVkSubHeap::free(const GrVkAlloc& alloc) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
GrVkHeap::~GrVkHeap() {
|
GrVkSubHeap::GrVkSubHeap(const GrVkGpu* gpu, uint32_t memoryTypeIndex,
|
||||||
|
VkDeviceSize size, VkDeviceSize alignment)
|
||||||
|
: INHERITED(size, alignment)
|
||||||
|
, fGpu(gpu)
|
||||||
|
, fMemoryTypeIndex(memoryTypeIndex) {
|
||||||
|
|
||||||
|
VkMemoryAllocateInfo allocInfo = {
|
||||||
|
VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, // sType
|
||||||
|
NULL, // pNext
|
||||||
|
size, // allocationSize
|
||||||
|
memoryTypeIndex, // memoryTypeIndex
|
||||||
|
};
|
||||||
|
|
||||||
|
VkResult err = GR_VK_CALL(gpu->vkInterface(), AllocateMemory(gpu->device(),
|
||||||
|
&allocInfo,
|
||||||
|
nullptr,
|
||||||
|
&fAlloc));
|
||||||
|
if (VK_SUCCESS != err) {
|
||||||
|
this->reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GrVkSubHeap::~GrVkSubHeap() {
|
||||||
|
const GrVkInterface* iface = fGpu->vkInterface();
|
||||||
|
GR_VK_CALL(iface, FreeMemory(fGpu->device(), fAlloc, nullptr));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GrVkSubHeap::alloc(VkDeviceSize size, GrVkAlloc* alloc) {
|
||||||
|
alloc->fMemory = fAlloc;
|
||||||
|
return INHERITED::alloc(size, &alloc->fOffset, &alloc->fSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GrVkSubHeap::free(const GrVkAlloc& alloc) {
|
||||||
|
SkASSERT(alloc.fMemory == fAlloc);
|
||||||
|
|
||||||
|
INHERITED::free(alloc.fOffset, alloc.fSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GrVkHeap::subAlloc(VkDeviceSize size, VkDeviceSize alignment,
|
bool GrVkHeap::subAlloc(VkDeviceSize size, VkDeviceSize alignment,
|
||||||
|
@ -39,42 +39,75 @@ namespace GrVkMemory {
|
|||||||
VkAccessFlags LayoutToSrcAccessMask(const VkImageLayout layout);
|
VkAccessFlags LayoutToSrcAccessMask(const VkImageLayout layout);
|
||||||
}
|
}
|
||||||
|
|
||||||
class GrVkSubHeap {
|
class GrVkFreeListAlloc {
|
||||||
public:
|
public:
|
||||||
GrVkSubHeap(const GrVkGpu* gpu, uint32_t memoryTypeIndex,
|
GrVkFreeListAlloc(VkDeviceSize size, VkDeviceSize alignment)
|
||||||
VkDeviceSize size, VkDeviceSize alignment);
|
: fSize(size)
|
||||||
~GrVkSubHeap();
|
, fAlignment(alignment)
|
||||||
|
, fFreeSize(size)
|
||||||
|
, fLargestBlockSize(size)
|
||||||
|
, fLargestBlockOffset(0) {
|
||||||
|
Block* block = fFreeList.addToTail();
|
||||||
|
block->fOffset = 0;
|
||||||
|
block->fSize = fSize;
|
||||||
|
}
|
||||||
|
~GrVkFreeListAlloc() {
|
||||||
|
this->reset();
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t memoryTypeIndex() const { return fMemoryTypeIndex; }
|
|
||||||
VkDeviceSize size() const { return fSize; }
|
VkDeviceSize size() const { return fSize; }
|
||||||
VkDeviceSize alignment() const { return fAlignment; }
|
VkDeviceSize alignment() const { return fAlignment; }
|
||||||
VkDeviceSize freeSize() const { return fFreeSize; }
|
VkDeviceSize freeSize() const { return fFreeSize; }
|
||||||
VkDeviceSize largestBlockSize() const { return fLargestBlockSize; }
|
VkDeviceSize largestBlockSize() const { return fLargestBlockSize; }
|
||||||
VkDeviceMemory memory() { return fAlloc; }
|
|
||||||
|
|
||||||
bool unallocated() const { return fSize == fFreeSize; }
|
bool unallocated() const { return fSize == fFreeSize; }
|
||||||
|
|
||||||
bool alloc(VkDeviceSize size, GrVkAlloc* alloc);
|
protected:
|
||||||
void free(const GrVkAlloc& alloc);
|
bool alloc(VkDeviceSize requestedSize, VkDeviceSize* allocOffset, VkDeviceSize* allocSize);
|
||||||
|
void free(VkDeviceSize allocOffset, VkDeviceSize allocSize);
|
||||||
|
|
||||||
|
void reset() {
|
||||||
|
fSize = 0;
|
||||||
|
fAlignment = 0;
|
||||||
|
fFreeSize = 0;
|
||||||
|
fLargestBlockSize = 0;
|
||||||
|
fFreeList.reset();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
struct Block {
|
struct Block {
|
||||||
VkDeviceSize fOffset;
|
VkDeviceSize fOffset;
|
||||||
VkDeviceSize fSize;
|
VkDeviceSize fSize;
|
||||||
};
|
};
|
||||||
typedef SkTLList<Block, 16> FreeList;
|
typedef SkTLList<Block, 16> FreeList;
|
||||||
|
|
||||||
const GrVkGpu* fGpu;
|
|
||||||
uint32_t fMemoryTypeIndex;
|
|
||||||
VkDeviceSize fSize;
|
VkDeviceSize fSize;
|
||||||
VkDeviceSize fAlignment;
|
VkDeviceSize fAlignment;
|
||||||
VkDeviceSize fFreeSize;
|
VkDeviceSize fFreeSize;
|
||||||
VkDeviceSize fLargestBlockSize;
|
VkDeviceSize fLargestBlockSize;
|
||||||
VkDeviceSize fLargestBlockOffset;
|
VkDeviceSize fLargestBlockOffset;
|
||||||
VkDeviceMemory fAlloc;
|
|
||||||
FreeList fFreeList;
|
FreeList fFreeList;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class GrVkSubHeap : public GrVkFreeListAlloc {
|
||||||
|
public:
|
||||||
|
GrVkSubHeap(const GrVkGpu* gpu, uint32_t memoryTypeIndex,
|
||||||
|
VkDeviceSize size, VkDeviceSize alignment);
|
||||||
|
~GrVkSubHeap();
|
||||||
|
|
||||||
|
uint32_t memoryTypeIndex() const { return fMemoryTypeIndex; }
|
||||||
|
VkDeviceMemory memory() { return fAlloc; }
|
||||||
|
|
||||||
|
bool alloc(VkDeviceSize requestedSize, GrVkAlloc* alloc);
|
||||||
|
void free(const GrVkAlloc& alloc);
|
||||||
|
|
||||||
|
private:
|
||||||
|
const GrVkGpu* fGpu;
|
||||||
|
uint32_t fMemoryTypeIndex;
|
||||||
|
VkDeviceMemory fAlloc;
|
||||||
|
|
||||||
|
typedef GrVkFreeListAlloc INHERITED;
|
||||||
|
};
|
||||||
|
|
||||||
class GrVkHeap {
|
class GrVkHeap {
|
||||||
public:
|
public:
|
||||||
enum Strategy {
|
enum Strategy {
|
||||||
@ -94,7 +127,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~GrVkHeap();
|
~GrVkHeap() {}
|
||||||
|
|
||||||
VkDeviceSize allocSize() const { return fAllocSize; }
|
VkDeviceSize allocSize() const { return fAllocSize; }
|
||||||
VkDeviceSize usedSize() const { return fUsedSize; }
|
VkDeviceSize usedSize() const { return fUsedSize; }
|
||||||
|
Loading…
Reference in New Issue
Block a user