Check if allocation is valid before deallocating.

Ensure deallocate does not assert should allocation fail but still be used.

BUG=dawn:227

Change-Id: I5edd4c160bced7934970c5d59e541a3a8f7a8afb
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/11380
Commit-Queue: Bryan Bernhart <bryan.bernhart@intel.com>
Reviewed-by: Austin Eng <enga@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/dawn_native/ResourceMemoryAllocation.cpp b/src/dawn_native/ResourceMemoryAllocation.cpp
index 5d26f21..8f30bc2 100644
--- a/src/dawn_native/ResourceMemoryAllocation.cpp
+++ b/src/dawn_native/ResourceMemoryAllocation.cpp
@@ -49,7 +49,6 @@
     }
 
     AllocationMethod ResourceMemoryAllocation::GetAllocationMethod() const {
-        ASSERT(mMethod != AllocationMethod::kInvalid);
         return mMethod;
     }
 
diff --git a/src/dawn_native/d3d12/DeviceD3D12.cpp b/src/dawn_native/d3d12/DeviceD3D12.cpp
index d9bb0a8..ffc5a7ed 100644
--- a/src/dawn_native/d3d12/DeviceD3D12.cpp
+++ b/src/dawn_native/d3d12/DeviceD3D12.cpp
@@ -345,6 +345,9 @@
     }
 
     void Device::DeallocateMemory(ResourceMemoryAllocation& allocation) {
+        if (allocation.GetAllocationMethod() == AllocationMethod::kInvalid) {
+            return;
+        }
         CommittedResourceAllocator* allocator = nullptr;
         D3D12_HEAP_PROPERTIES heapProp;
         ToBackend(allocation.GetResourceHeap())
diff --git a/src/dawn_native/vulkan/DeviceVk.cpp b/src/dawn_native/vulkan/DeviceVk.cpp
index bd63b11..d1ec330 100644
--- a/src/dawn_native/vulkan/DeviceVk.cpp
+++ b/src/dawn_native/vulkan/DeviceVk.cpp
@@ -698,6 +698,9 @@
     }
 
     void Device::DeallocateMemory(ResourceMemoryAllocation& allocation) {
+        if (allocation.GetAllocationMethod() == AllocationMethod::kInvalid) {
+            return;
+        }
         mResourceAllocator->Deallocate(allocation);
 
         // Invalidate the underlying resource heap in case the client accidentally
diff --git a/src/tests/end2end/BufferTests.cpp b/src/tests/end2end/BufferTests.cpp
index f955270..0e1b561 100644
--- a/src/tests/end2end/BufferTests.cpp
+++ b/src/tests/end2end/BufferTests.cpp
@@ -627,6 +627,17 @@
     EXPECT_BUFFER_U32_EQ(myData, result.buffer, 0);
 }
 
+// Test that creating a very large buffers fails gracefully.
+TEST_P(CreateBufferMappedTests, LargeBufferFails) {
+    // TODO(http://crbug.com/dawn/27): Missing support.
+    DAWN_SKIP_TEST_IF(IsMetal() || IsOpenGL());
+
+    dawn::BufferDescriptor descriptor;
+    descriptor.size = std::numeric_limits<uint64_t>::max();
+    descriptor.usage = dawn::BufferUsage::MapRead | dawn::BufferUsage::CopyDst;
+    ASSERT_DEVICE_ERROR(device.CreateBuffer(&descriptor));
+}
+
 DAWN_INSTANTIATE_TEST(CreateBufferMappedTests,
                       D3D12Backend,
                       MetalBackend,