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 |