Bubble up potential errors during buffer.unmap().

Bug: dawn:1336
Change-Id: I715904874311349b4e996665dccc9d2d31959717
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/122022
Reviewed-by: Austin Eng <enga@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Loko Kung <lokokung@google.com>
diff --git a/src/dawn/native/BlitBufferToDepthStencil.cpp b/src/dawn/native/BlitBufferToDepthStencil.cpp
index cd50391..bb86769 100644
--- a/src/dawn/native/BlitBufferToDepthStencil.cpp
+++ b/src/dawn/native/BlitBufferToDepthStencil.cpp
@@ -268,7 +268,7 @@
                 static_cast<uint32_t*>(paramsBuffer->GetMappedRange(0, bufferDesc.size));
             params[0] = dst.origin.x;
             params[1] = dst.origin.y;
-            paramsBuffer->Unmap();
+            DAWN_TRY(paramsBuffer->Unmap());
         }
 
         Ref<BindGroupBase> bindGroup;
@@ -357,7 +357,7 @@
         uint32_t* params = static_cast<uint32_t*>(paramsBuffer->GetMappedRange(0, bufferDesc.size));
         params[0] = dst.origin.x;
         params[1] = dst.origin.y;
-        paramsBuffer->Unmap();
+        DAWN_TRY(paramsBuffer->Unmap());
     }
 
     // For each layer, blit the stencil data.
diff --git a/src/dawn/native/Buffer.cpp b/src/dawn/native/Buffer.cpp
index 9f99a71..c7124e5 100644
--- a/src/dawn/native/Buffer.cpp
+++ b/src/dawn/native/Buffer.cpp
@@ -506,29 +506,36 @@
     if (GetDevice()->ConsumedError(ValidateUnmap(), "calling %s.Unmap().", this)) {
         return;
     }
-    Unmap();
-}
-
-void BufferBase::Unmap() {
-    if (mState == BufferState::Destroyed) {
+    if (GetDevice()->ConsumedError(Unmap(), "calling %s.Unmap().", this)) {
         return;
     }
+}
+
+MaybeError BufferBase::Unmap() {
+    if (mState == BufferState::Destroyed) {
+        return {};
+    }
+
+    // Make sure writes are now visibile to the GPU if we used a staging buffer.
+    if (mState == BufferState::MappedAtCreation && mStagingBuffer != nullptr) {
+        DAWN_TRY(CopyFromStagingBuffer());
+    }
     UnmapInternal(WGPUBufferMapAsyncStatus_UnmappedBeforeCallback).Call();
+    return {};
 }
 
 BufferBase::PendingMappingCallback BufferBase::UnmapInternal(
     WGPUBufferMapAsyncStatus callbackStatus) {
     PendingMappingCallback toCall;
 
+    // Unmaps resources on the backend and returns the callback.
     if (mState == BufferState::PendingMap) {
         toCall = WillCallMappingCallback(mLastMapID, callbackStatus);
         UnmapImpl();
     } else if (mState == BufferState::Mapped) {
         UnmapImpl();
     } else if (mState == BufferState::MappedAtCreation) {
-        if (mStagingBuffer != nullptr) {
-            GetDevice()->ConsumedError(CopyFromStagingBuffer());
-        } else if (mSize != 0) {
+        if (!IsError() && mSize != 0 && IsCPUWritableAtCreation()) {
             UnmapImpl();
         }
     }
diff --git a/src/dawn/native/Buffer.h b/src/dawn/native/Buffer.h
index 8e86055..343aa7f 100644
--- a/src/dawn/native/Buffer.h
+++ b/src/dawn/native/Buffer.h
@@ -77,7 +77,7 @@
 
     virtual void* GetMappedPointer() = 0;
     void* GetMappedRange(size_t offset, size_t size, bool writable = true);
-    void Unmap();
+    MaybeError Unmap();
 
     // Dawn API
     void APIMapAsync(wgpu::MapMode mode,
diff --git a/src/dawn/native/opengl/TextureGL.cpp b/src/dawn/native/opengl/TextureGL.cpp
index 95f7f99..906e398 100644
--- a/src/dawn/native/opengl/TextureGL.cpp
+++ b/src/dawn/native/opengl/TextureGL.cpp
@@ -498,7 +498,7 @@
 
         // Fill the buffer with clear color
         memset(srcBuffer->GetMappedRange(0, bufferSize), clearColor, bufferSize);
-        srcBuffer->Unmap();
+        DAWN_TRY(srcBuffer->Unmap());
 
         gl.BindBuffer(GL_PIXEL_UNPACK_BUFFER, srcBuffer->GetHandle());
         for (uint32_t level = range.baseMipLevel; level < range.baseMipLevel + range.levelCount;
diff --git a/src/dawn/native/utils/WGPUHelpers.cpp b/src/dawn/native/utils/WGPUHelpers.cpp
index ffa2980..deee395 100644
--- a/src/dawn/native/utils/WGPUHelpers.cpp
+++ b/src/dawn/native/utils/WGPUHelpers.cpp
@@ -53,7 +53,7 @@
     Ref<BufferBase> buffer;
     DAWN_TRY_ASSIGN(buffer, device->CreateBuffer(&descriptor));
     memcpy(buffer->GetMappedRange(0, size), data, size);
-    buffer->Unmap();
+    DAWN_TRY(buffer->Unmap());
     return buffer;
 }