diff --git a/src/dawn_native/Buffer.cpp b/src/dawn_native/Buffer.cpp index 103db1aacd..4bef77fa80 100644 --- a/src/dawn_native/Buffer.cpp +++ b/src/dawn_native/Buffer.cpp @@ -261,30 +261,32 @@ namespace dawn_native { MaybeError BufferBase::MapAtCreationInternal() { ASSERT(!IsError()); - mState = BufferState::MappedAtCreation; mMapOffset = 0; mMapSize = mSize; - // 0-sized buffers are not supposed to be written to, Return back any non-null pointer. - // Handle 0-sized buffers first so we don't try to map them in the backend. - if (mSize == 0) { - return {}; - } - - // Mappable buffers don't use a staging buffer and are just as if mapped through MapAsync. - if (IsCPUWritableAtCreation()) { - DAWN_TRY(MapAtCreationImpl()); - } else { - // If any of these fail, the buffer will be deleted and replaced with an - // error buffer. - // The staging buffer is used to return mappable data to inititalize the buffer - // contents. Allocate one as large as the real buffer size so that every byte is - // initialized. - // TODO(crbug.com/dawn/828): Suballocate and reuse memory from a larger staging buffer - // so we don't create many small buffers. - DAWN_TRY_ASSIGN(mStagingBuffer, GetDevice()->CreateStagingBuffer(GetAllocatedSize())); + // 0-sized buffers are not supposed to be written to. Return back any non-null pointer. + // Skip handling 0-sized buffers so we don't try to map them in the backend. + if (mSize != 0) { + // Mappable buffers don't use a staging buffer and are just as if mapped through + // MapAsync. + if (IsCPUWritableAtCreation()) { + DAWN_TRY(MapAtCreationImpl()); + } else { + // If any of these fail, the buffer will be deleted and replaced with an error + // buffer. The staging buffer is used to return mappable data to inititalize the + // buffer contents. Allocate one as large as the real buffer size so that every byte + // is initialized. + // TODO(crbug.com/dawn/828): Suballocate and reuse memory from a larger staging + // buffer so we don't create many small buffers. + DAWN_TRY_ASSIGN(mStagingBuffer, + GetDevice()->CreateStagingBuffer(GetAllocatedSize())); + } } + // Only set the state to mapped at creation if we did no fail any point in this helper. + // Otherwise, if we override the default unmapped state before succeeding to create a + // staging buffer, we will have issues when we try to destroy the buffer. + mState = BufferState::MappedAtCreation; return {}; } diff --git a/src/dawn_native/d3d12/BufferD3D12.cpp b/src/dawn_native/d3d12/BufferD3D12.cpp index e157b411b1..91f2c00419 100644 --- a/src/dawn_native/d3d12/BufferD3D12.cpp +++ b/src/dawn_native/d3d12/BufferD3D12.cpp @@ -379,14 +379,8 @@ namespace dawn_native { namespace d3d12 { } void Buffer::DestroyApiObjectImpl() { - if (mMappedData != nullptr) { - // If the buffer is currently mapped, unmap without flushing the writes to the GPU - // since the buffer cannot be used anymore. UnmapImpl checks mWrittenRange to know - // which parts to flush, so we set it to an empty range to prevent flushes. - mWrittenMappedRange = {0, 0}; - UnmapImpl(); - } - + // TODO(crbug.com/dawn/1189) Reintroduce optimization to skip flushing the writes to the GPU + // memory when we unmap in destruction case since the buffer will be destroyed anyways. ToBackend(GetDevice())->DeallocateMemory(mResourceAllocation); }