aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu
diff options
context:
space:
mode:
authorGravatar jvanverth <jvanverth@google.com>2016-07-07 07:16:42 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-07-07 07:16:42 -0700
commit82356cc41f360c607a1612cb9aead2423c0846a0 (patch)
tree62fa62c3ba9d47b38a75215bc60bef48f3624fe2 /src/gpu
parent552882f768b02a2aa20552a765913187851e382b (diff)
Pull out freelist allocation from GrVkSubHeap
Diffstat (limited to 'src/gpu')
-rw-r--r--src/gpu/vk/GrVkMemory.cpp122
-rw-r--r--src/gpu/vk/GrVkMemory.h59
2 files changed, 102 insertions, 79 deletions
diff --git a/src/gpu/vk/GrVkMemory.cpp b/src/gpu/vk/GrVkMemory.cpp
index 1983db5c4c..76b449c150 100644
--- a/src/gpu/vk/GrVkMemory.cpp
+++ b/src/gpu/vk/GrVkMemory.cpp
@@ -242,50 +242,9 @@ VkAccessFlags GrVkMemory::LayoutToSrcAccessMask(const VkImageLayout layout) {
return flags;
}
-GrVkSubHeap::GrVkSubHeap(const GrVkGpu* gpu, uint32_t memoryTypeIndex,
- VkDeviceSize size, VkDeviceSize 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) {
- 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);
+bool GrVkFreeListAlloc::alloc(VkDeviceSize requestedSize,
+ VkDeviceSize* allocOffset, VkDeviceSize* allocSize) {
+ VkDeviceSize alignedSize = align_size(requestedSize, fAlignment);
// find the smallest block big enough for our allocation
FreeList::Iter iter = fFreeList.headIter();
@@ -311,10 +270,9 @@ bool GrVkSubHeap::alloc(VkDeviceSize size, GrVkAlloc* alloc) {
Block* bestFit = bestFitIter.get();
if (bestFit) {
- alloc->fMemory = fAlloc;
SkASSERT(align_size(bestFit->fOffset, fAlignment) == bestFit->fOffset);
- alloc->fOffset = bestFit->fOffset;
- alloc->fSize = alignedSize;
+ *allocOffset = bestFit->fOffset;
+ *allocSize = alignedSize;
// adjust or remove current block
VkDeviceSize originalBestFitOffset = bestFit->fOffset;
if (bestFit->fSize > alignedSize) {
@@ -362,38 +320,35 @@ bool GrVkSubHeap::alloc(VkDeviceSize size, GrVkAlloc* alloc) {
#endif
}
fFreeSize -= alignedSize;
- SkASSERT(alloc->fSize > 0);
+ SkASSERT(allocSize > 0);
return true;
}
-
+
SkDebugf("Can't allocate %d bytes, %d bytes available, largest free block %d\n", alignedSize, fFreeSize, fLargestBlockSize);
return false;
}
-
-void GrVkSubHeap::free(const GrVkAlloc& alloc) {
- SkASSERT(alloc.fMemory == fAlloc);
-
+void GrVkFreeListAlloc::free(VkDeviceSize allocOffset, VkDeviceSize allocSize) {
// find the block right after this allocation
FreeList::Iter iter = fFreeList.headIter();
FreeList::Iter prev;
- while (iter.get() && iter.get()->fOffset < alloc.fOffset) {
+ while (iter.get() && iter.get()->fOffset < allocOffset) {
prev = iter;
iter.next();
- }
+ }
// we have four cases:
// we exactly follow the previous one
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->fSize += alloc.fSize;
+ block->fSize += allocSize;
if (block->fOffset == fLargestBlockOffset) {
fLargestBlockSize = block->fSize;
}
// 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;
if (iter.get()->fOffset == fLargestBlockOffset) {
fLargestBlockOffset = block->fOffset;
@@ -402,21 +357,21 @@ void GrVkSubHeap::free(const GrVkAlloc& alloc) {
fFreeList.remove(iter.get());
}
// 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->fSize += alloc.fSize;
+ block->fSize += allocSize;
if (block->fOffset == fLargestBlockOffset) {
- fLargestBlockOffset = alloc.fOffset;
+ fLargestBlockOffset = allocOffset;
fLargestBlockSize = block->fSize;
}
- block->fOffset = alloc.fOffset;
+ block->fOffset = allocOffset;
// or we fall somewhere in between, with gaps
} else {
block = fFreeList.addBefore(iter);
- block->fOffset = alloc.fOffset;
- block->fSize = alloc.fSize;
+ block->fOffset = allocOffset;
+ block->fSize = allocSize;
}
- fFreeSize += alloc.fSize;
+ fFreeSize += allocSize;
if (block->fSize > fLargestBlockSize) {
fLargestBlockSize = block->fSize;
fLargestBlockOffset = block->fOffset;
@@ -436,7 +391,42 @@ void GrVkSubHeap::free(const GrVkAlloc& alloc) {
#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,
diff --git a/src/gpu/vk/GrVkMemory.h b/src/gpu/vk/GrVkMemory.h
index 2b9feda7b5..644d7d4198 100644
--- a/src/gpu/vk/GrVkMemory.h
+++ b/src/gpu/vk/GrVkMemory.h
@@ -39,42 +39,75 @@ namespace GrVkMemory {
VkAccessFlags LayoutToSrcAccessMask(const VkImageLayout layout);
}
-class GrVkSubHeap {
+class GrVkFreeListAlloc {
public:
- GrVkSubHeap(const GrVkGpu* gpu, uint32_t memoryTypeIndex,
- VkDeviceSize size, VkDeviceSize alignment);
- ~GrVkSubHeap();
+ GrVkFreeListAlloc(VkDeviceSize size, VkDeviceSize alignment)
+ : fSize(size)
+ , 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 alignment() const { return fAlignment; }
VkDeviceSize freeSize() const { return fFreeSize; }
VkDeviceSize largestBlockSize() const { return fLargestBlockSize; }
- VkDeviceMemory memory() { return fAlloc; }
bool unallocated() const { return fSize == fFreeSize; }
- bool alloc(VkDeviceSize size, GrVkAlloc* alloc);
- void free(const GrVkAlloc& alloc);
+protected:
+ 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 {
VkDeviceSize fOffset;
VkDeviceSize fSize;
};
typedef SkTLList<Block, 16> FreeList;
- const GrVkGpu* fGpu;
- uint32_t fMemoryTypeIndex;
VkDeviceSize fSize;
VkDeviceSize fAlignment;
VkDeviceSize fFreeSize;
VkDeviceSize fLargestBlockSize;
VkDeviceSize fLargestBlockOffset;
- VkDeviceMemory fAlloc;
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 {
public:
enum Strategy {
@@ -94,7 +127,7 @@ public:
}
}
- ~GrVkHeap();
+ ~GrVkHeap() {}
VkDeviceSize allocSize() const { return fAllocSize; }
VkDeviceSize usedSize() const { return fUsedSize; }