Vulkan: attempt sub-allocation before direct allocation.

Falling-back to direct allocation ensures allocation failure returns OOM.
If no OOM, the resource could be left then used while in an invalid state.

BUG=chromium:1045811,chromium:1047220,chromium:1047048

Change-Id: I927962b1dc6a7422a7d6eac114d82f28a42794a2
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/15600
Commit-Queue: Bryan Bernhart <bryan.bernhart@intel.com>
Reviewed-by: Austin Eng <enga@chromium.org>
This commit is contained in:
Bryan Bernhart 2020-02-03 19:17:34 +00:00 committed by Commit Bot service account
parent 97c3be2699
commit 525ef86c2e

View File

@ -112,31 +112,35 @@ namespace dawn_native { namespace vulkan {
VkDeviceSize size = requirements.size; VkDeviceSize size = requirements.size;
// If the resource is too big, allocate memory just for it. // Sub-allocate non-mappable resources because at the moment the mapped pointer
// Also allocate mappable resources separately because at the moment the mapped pointer
// is part of the resource and not the heap, which doesn't match the Vulkan model. // is part of the resource and not the heap, which doesn't match the Vulkan model.
// TODO(cwallez@chromium.org): allow sub-allocating mappable resources, maybe. // TODO(cwallez@chromium.org): allow sub-allocating mappable resources, maybe.
if (requirements.size >= kMaxSizeForSubAllocation || mappable) { if (requirements.size < kMaxSizeForSubAllocation && !mappable) {
std::unique_ptr<ResourceHeapBase> resourceHeap; ResourceMemoryAllocation subAllocation;
DAWN_TRY_ASSIGN(resourceHeap, DAWN_TRY_ASSIGN(subAllocation,
mAllocatorsPerType[memoryType]->AllocateResourceHeap(size)); mAllocatorsPerType[memoryType]->AllocateMemory(requirements));
if (subAllocation.GetInfo().mMethod != AllocationMethod::kInvalid) {
void* mappedPointer = nullptr; return subAllocation;
if (mappable) {
DAWN_TRY(
CheckVkSuccess(mDevice->fn.MapMemory(mDevice->GetVkDevice(),
ToBackend(resourceHeap.get())->GetMemory(),
0, size, 0, &mappedPointer),
"vkMapMemory"));
} }
AllocationInfo info;
info.mMethod = AllocationMethod::kDirect;
return ResourceMemoryAllocation(info, /*offset*/ 0, resourceHeap.release(),
static_cast<uint8_t*>(mappedPointer));
} else {
return mAllocatorsPerType[memoryType]->AllocateMemory(requirements);
} }
// If sub-allocation failed, allocate memory just for it.
std::unique_ptr<ResourceHeapBase> resourceHeap;
DAWN_TRY_ASSIGN(resourceHeap, mAllocatorsPerType[memoryType]->AllocateResourceHeap(size));
void* mappedPointer = nullptr;
if (mappable) {
DAWN_TRY(
CheckVkSuccess(mDevice->fn.MapMemory(mDevice->GetVkDevice(),
ToBackend(resourceHeap.get())->GetMemory(), 0,
size, 0, &mappedPointer),
"vkMapMemory"));
}
AllocationInfo info;
info.mMethod = AllocationMethod::kDirect;
return ResourceMemoryAllocation(info, /*offset*/ 0, resourceHeap.release(),
static_cast<uint8_t*>(mappedPointer));
} }
void ResourceMemoryAllocator::Deallocate(ResourceMemoryAllocation* allocation) { void ResourceMemoryAllocator::Deallocate(ResourceMemoryAllocation* allocation) {