| Index: src/gpu/vk/GrVkMemory.cpp
|
| diff --git a/src/gpu/vk/GrVkMemory.cpp b/src/gpu/vk/GrVkMemory.cpp
|
| index 984e3271b0716df82d9c6a22912b9a783af609e4..7ad9b45987f9e5637c909596607237238cbc3dd1 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);
|
|
|