| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "GrVkMemory.h" | 8 #include "GrVkMemory.h" |
| 9 | 9 |
| 10 #include "GrVkGpu.h" | 10 #include "GrVkGpu.h" |
| (...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 353 Block* block = iter.get(); | 353 Block* block = iter.get(); |
| 354 if (largestSize < block->fSize) { | 354 if (largestSize < block->fSize) { |
| 355 largestSize = block->fSize; | 355 largestSize = block->fSize; |
| 356 } | 356 } |
| 357 iter.next(); | 357 iter.next(); |
| 358 } | 358 } |
| 359 SkASSERT(largestSize == fLargestBlockSize); | 359 SkASSERT(largestSize == fLargestBlockSize); |
| 360 #endif | 360 #endif |
| 361 } | 361 } |
| 362 fFreeSize -= alignedSize; | 362 fFreeSize -= alignedSize; |
| 363 SkASSERT(alloc->fSize > 0); |
| 363 | 364 |
| 364 return true; | 365 return true; |
| 365 } | 366 } |
| 366 | 367 |
| 367 SkDebugf("Can't allocate %d bytes, %d bytes available, largest free block %d
\n", alignedSize, fFreeSize, fLargestBlockSize); | 368 SkDebugf("Can't allocate %d bytes, %d bytes available, largest free block %d
\n", alignedSize, fFreeSize, fLargestBlockSize); |
| 368 | 369 |
| 369 return false; | 370 return false; |
| 370 } | 371 } |
| 371 | 372 |
| 372 | 373 |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 433 #endif | 434 #endif |
| 434 } | 435 } |
| 435 | 436 |
| 436 GrVkHeap::~GrVkHeap() { | 437 GrVkHeap::~GrVkHeap() { |
| 437 } | 438 } |
| 438 | 439 |
| 439 bool GrVkHeap::subAlloc(VkDeviceSize size, VkDeviceSize alignment, | 440 bool GrVkHeap::subAlloc(VkDeviceSize size, VkDeviceSize alignment, |
| 440 uint32_t memoryTypeIndex, GrVkAlloc* alloc) { | 441 uint32_t memoryTypeIndex, GrVkAlloc* alloc) { |
| 441 VkDeviceSize alignedSize = align_size(size, alignment); | 442 VkDeviceSize alignedSize = align_size(size, alignment); |
| 442 | 443 |
| 444 // if requested is larger than our subheap allocation, just alloc directly |
| 445 if (alignedSize > fSubHeapSize) { |
| 446 VkMemoryAllocateInfo allocInfo = { |
| 447 VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, // sType |
| 448 NULL, // pNext |
| 449 size, // allocationSize |
| 450 memoryTypeIndex, // memoryTypeIndex |
| 451 }; |
| 452 |
| 453 VkResult err = GR_VK_CALL(fGpu->vkInterface(), AllocateMemory(fGpu->devi
ce(), |
| 454 &allocInfo
, |
| 455 nullptr, |
| 456 &alloc->fM
emory)); |
| 457 if (VK_SUCCESS != err) { |
| 458 return false; |
| 459 } |
| 460 alloc->fOffset = 0; |
| 461 alloc->fSize = 0; // hint that this is not a subheap allocation |
| 462 |
| 463 return true; |
| 464 } |
| 465 |
| 443 // first try to find a subheap that fits our allocation request | 466 // first try to find a subheap that fits our allocation request |
| 444 int bestFitIndex = -1; | 467 int bestFitIndex = -1; |
| 445 VkDeviceSize bestFitSize = 0x7FFFFFFF; | 468 VkDeviceSize bestFitSize = 0x7FFFFFFF; |
| 446 for (auto i = 0; i < fSubHeaps.count(); ++i) { | 469 for (auto i = 0; i < fSubHeaps.count(); ++i) { |
| 447 if (fSubHeaps[i]->memoryTypeIndex() == memoryTypeIndex) { | 470 if (fSubHeaps[i]->memoryTypeIndex() == memoryTypeIndex) { |
| 448 VkDeviceSize heapSize = fSubHeaps[i]->largestBlockSize(); | 471 VkDeviceSize heapSize = fSubHeaps[i]->largestBlockSize(); |
| 449 if (heapSize >= alignedSize && heapSize < bestFitSize) { | 472 if (heapSize >= alignedSize && heapSize < bestFitSize) { |
| 450 bestFitIndex = i; | 473 bestFitIndex = i; |
| 451 bestFitSize = heapSize; | 474 bestFitSize = heapSize; |
| 452 } | 475 } |
| 453 } | 476 } |
| 454 } | 477 } |
| 455 | 478 |
| 456 if (bestFitIndex >= 0) { | 479 if (bestFitIndex >= 0) { |
| 457 SkASSERT(fSubHeaps[bestFitIndex]->alignment() == alignment); | 480 SkASSERT(fSubHeaps[bestFitIndex]->alignment() == alignment); |
| 458 if (fSubHeaps[bestFitIndex]->alloc(size, alloc)) { | 481 if (fSubHeaps[bestFitIndex]->alloc(size, alloc)) { |
| 459 fUsedSize += alloc->fSize; | 482 fUsedSize += alloc->fSize; |
| 460 return true; | 483 return true; |
| 461 } | 484 } |
| 462 return false; | 485 return false; |
| 463 } | 486 } |
| 464 | 487 |
| 465 // need to allocate a new subheap | 488 // need to allocate a new subheap |
| 466 SkAutoTDelete<GrVkSubHeap>& subHeap = fSubHeaps.push_back(); | 489 SkAutoTDelete<GrVkSubHeap>& subHeap = fSubHeaps.push_back(); |
| 467 subHeap.reset(new GrVkSubHeap(fGpu, memoryTypeIndex, fSubHeapSize, alignment
)); | 490 subHeap.reset(new GrVkSubHeap(fGpu, memoryTypeIndex, fSubHeapSize, alignment
)); |
| 491 // try to recover from failed allocation by only allocating what we need |
| 492 if (subHeap->size() == 0) { |
| 493 VkDeviceSize alignedSize = align_size(size, alignment); |
| 494 subHeap.reset(new GrVkSubHeap(fGpu, memoryTypeIndex, alignedSize, alignm
ent)); |
| 495 if (subHeap->size() == 0) { |
| 496 return false; |
| 497 } |
| 498 } |
| 468 fAllocSize += fSubHeapSize; | 499 fAllocSize += fSubHeapSize; |
| 469 if (subHeap->alloc(size, alloc)) { | 500 if (subHeap->alloc(size, alloc)) { |
| 470 fUsedSize += alloc->fSize; | 501 fUsedSize += alloc->fSize; |
| 471 return true; | 502 return true; |
| 472 } | 503 } |
| 473 | 504 |
| 474 return false; | 505 return false; |
| 475 } | 506 } |
| 476 | 507 |
| 477 bool GrVkHeap::singleAlloc(VkDeviceSize size, VkDeviceSize alignment, | 508 bool GrVkHeap::singleAlloc(VkDeviceSize size, VkDeviceSize alignment, |
| (...skipping 28 matching lines...) Expand all Loading... |
| 506 fAllocSize += alignedSize; | 537 fAllocSize += alignedSize; |
| 507 if (subHeap->alloc(size, alloc)) { | 538 if (subHeap->alloc(size, alloc)) { |
| 508 fUsedSize += alloc->fSize; | 539 fUsedSize += alloc->fSize; |
| 509 return true; | 540 return true; |
| 510 } | 541 } |
| 511 | 542 |
| 512 return false; | 543 return false; |
| 513 } | 544 } |
| 514 | 545 |
| 515 bool GrVkHeap::free(const GrVkAlloc& alloc) { | 546 bool GrVkHeap::free(const GrVkAlloc& alloc) { |
| 547 // a size of 0 means we're using the system heap |
| 548 if (0 == alloc.fSize) { |
| 549 const GrVkInterface* iface = fGpu->vkInterface(); |
| 550 GR_VK_CALL(iface, FreeMemory(fGpu->device(), alloc.fMemory, nullptr)); |
| 551 return true; |
| 552 } |
| 553 |
| 516 for (auto i = 0; i < fSubHeaps.count(); ++i) { | 554 for (auto i = 0; i < fSubHeaps.count(); ++i) { |
| 517 if (fSubHeaps[i]->memory() == alloc.fMemory) { | 555 if (fSubHeaps[i]->memory() == alloc.fMemory) { |
| 518 fSubHeaps[i]->free(alloc); | 556 fSubHeaps[i]->free(alloc); |
| 519 fUsedSize -= alloc.fSize; | 557 fUsedSize -= alloc.fSize; |
| 520 return true; | 558 return true; |
| 521 } | 559 } |
| 522 } | 560 } |
| 523 | 561 |
| 524 return false; | 562 return false; |
| 525 } | 563 } |
| 526 | 564 |
| 527 | 565 |
| OLD | NEW |