aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/vk
diff options
context:
space:
mode:
authorGravatar jvanverth <jvanverth@google.com>2016-06-16 14:05:09 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-06-16 14:05:09 -0700
commit6dc3af4499893045f7b187d5d85bc785b6e44baa (patch)
treea039e1db7c94da1bc4629784c42f50395a9ede1f /src/gpu/vk
parentb6095ae05bab1ca3b05c6eca091295cdc922d184 (diff)
Check for some potential subheap allocation failures.
Need to make sure we can allocate areas larger than our specified subheap sizes, and deal with potential fragmentation in the main system heap. GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2072763002 Review-Url: https://codereview.chromium.org/2072763002
Diffstat (limited to 'src/gpu/vk')
-rw-r--r--src/gpu/vk/GrVkMemory.cpp40
-rw-r--r--src/gpu/vk/GrVkMemory.h1
2 files changed, 40 insertions, 1 deletions
diff --git a/src/gpu/vk/GrVkMemory.cpp b/src/gpu/vk/GrVkMemory.cpp
index 984e3271b0..7ad9b45987 100644
--- a/src/gpu/vk/GrVkMemory.cpp
+++ b/src/gpu/vk/GrVkMemory.cpp
@@ -360,6 +360,7 @@ bool GrVkSubHeap::alloc(VkDeviceSize size, GrVkAlloc* alloc) {
#endif
}
fFreeSize -= alignedSize;
+ SkASSERT(alloc->fSize > 0);
return true;
}
@@ -440,6 +441,28 @@ bool GrVkHeap::subAlloc(VkDeviceSize size, VkDeviceSize alignment,
uint32_t memoryTypeIndex, GrVkAlloc* alloc) {
VkDeviceSize alignedSize = align_size(size, alignment);
+ // if requested is larger than our subheap allocation, just alloc directly
+ if (alignedSize > fSubHeapSize) {
+ VkMemoryAllocateInfo allocInfo = {
+ VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, // sType
+ NULL, // pNext
+ size, // allocationSize
+ memoryTypeIndex, // memoryTypeIndex
+ };
+
+ VkResult err = GR_VK_CALL(fGpu->vkInterface(), AllocateMemory(fGpu->device(),
+ &allocInfo,
+ nullptr,
+ &alloc->fMemory));
+ if (VK_SUCCESS != err) {
+ return false;
+ }
+ alloc->fOffset = 0;
+ alloc->fSize = 0; // hint that this is not a subheap allocation
+
+ return true;
+ }
+
// first try to find a subheap that fits our allocation request
int bestFitIndex = -1;
VkDeviceSize bestFitSize = 0x7FFFFFFF;
@@ -460,11 +483,19 @@ bool GrVkHeap::subAlloc(VkDeviceSize size, VkDeviceSize alignment,
return true;
}
return false;
- }
+ }
// need to allocate a new subheap
SkAutoTDelete<GrVkSubHeap>& subHeap = fSubHeaps.push_back();
subHeap.reset(new GrVkSubHeap(fGpu, memoryTypeIndex, fSubHeapSize, alignment));
+ // try to recover from failed allocation by only allocating what we need
+ if (subHeap->size() == 0) {
+ VkDeviceSize alignedSize = align_size(size, alignment);
+ subHeap.reset(new GrVkSubHeap(fGpu, memoryTypeIndex, alignedSize, alignment));
+ if (subHeap->size() == 0) {
+ return false;
+ }
+ }
fAllocSize += fSubHeapSize;
if (subHeap->alloc(size, alloc)) {
fUsedSize += alloc->fSize;
@@ -513,6 +544,13 @@ bool GrVkHeap::singleAlloc(VkDeviceSize size, VkDeviceSize alignment,
}
bool GrVkHeap::free(const GrVkAlloc& alloc) {
+ // a size of 0 means we're using the system heap
+ if (0 == alloc.fSize) {
+ const GrVkInterface* iface = fGpu->vkInterface();
+ GR_VK_CALL(iface, FreeMemory(fGpu->device(), alloc.fMemory, nullptr));
+ return true;
+ }
+
for (auto i = 0; i < fSubHeaps.count(); ++i) {
if (fSubHeaps[i]->memory() == alloc.fMemory) {
fSubHeaps[i]->free(alloc);
diff --git a/src/gpu/vk/GrVkMemory.h b/src/gpu/vk/GrVkMemory.h
index 417fb5a1e0..44c8286721 100644
--- a/src/gpu/vk/GrVkMemory.h
+++ b/src/gpu/vk/GrVkMemory.h
@@ -100,6 +100,7 @@ public:
bool alloc(VkDeviceSize size, VkDeviceSize alignment, uint32_t memoryTypeIndex,
GrVkAlloc* alloc) {
+ SkASSERT(size > 0);
return (*this.*fAllocFunc)(size, alignment, memoryTypeIndex, alloc);
}
bool free(const GrVkAlloc& alloc);