Move src/backend to src/dawn_native
diff --git a/src/dawn_native/Buffer.cpp b/src/dawn_native/Buffer.cpp
new file mode 100644
index 0000000..31ed2d8
--- /dev/null
+++ b/src/dawn_native/Buffer.cpp
@@ -0,0 +1,295 @@
+// Copyright 2017 The Dawn Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "dawn_native/Buffer.h"
+
+#include "common/Assert.h"
+#include "dawn_native/Device.h"
+
+#include <cstdio>
+#include <utility>
+
+namespace backend {
+
+    // Buffer
+
+    BufferBase::BufferBase(BufferBuilder* builder)
+        : mDevice(builder->mDevice), mSize(builder->mSize), mAllowedUsage(builder->mAllowedUsage) {
+    }
+
+    BufferBase::~BufferBase() {
+        if (mIsMapped) {
+            CallMapReadCallback(mMapSerial, DAWN_BUFFER_MAP_ASYNC_STATUS_UNKNOWN, nullptr);
+            CallMapWriteCallback(mMapSerial, DAWN_BUFFER_MAP_ASYNC_STATUS_UNKNOWN, nullptr);
+        }
+    }
+
+    BufferViewBuilder* BufferBase::CreateBufferViewBuilder() {
+        return new BufferViewBuilder(mDevice, this);
+    }
+
+    DeviceBase* BufferBase::GetDevice() const {
+        return mDevice;
+    }
+
+    uint32_t BufferBase::GetSize() const {
+        return mSize;
+    }
+
+    dawn::BufferUsageBit BufferBase::GetAllowedUsage() const {
+        return mAllowedUsage;
+    }
+
+    void BufferBase::CallMapReadCallback(uint32_t serial,
+                                         dawnBufferMapAsyncStatus status,
+                                         const void* pointer) {
+        if (mMapReadCallback != nullptr && serial == mMapSerial) {
+            ASSERT(mMapWriteCallback == nullptr);
+            // Tag the callback as fired before firing it, otherwise it could fire a second time if
+            // for example buffer.Unmap() is called inside the application-provided callback.
+            dawnBufferMapReadCallback callback = mMapReadCallback;
+            mMapReadCallback = nullptr;
+            callback(status, pointer, mMapUserdata);
+        }
+    }
+
+    void BufferBase::CallMapWriteCallback(uint32_t serial,
+                                          dawnBufferMapAsyncStatus status,
+                                          void* pointer) {
+        if (mMapWriteCallback != nullptr && serial == mMapSerial) {
+            ASSERT(mMapReadCallback == nullptr);
+            // Tag the callback as fired before firing it, otherwise it could fire a second time if
+            // for example buffer.Unmap() is called inside the application-provided callback.
+            dawnBufferMapWriteCallback callback = mMapWriteCallback;
+            mMapWriteCallback = nullptr;
+            callback(status, pointer, mMapUserdata);
+        }
+    }
+
+    void BufferBase::SetSubData(uint32_t start, uint32_t count, const uint8_t* data) {
+        if (mDevice->ConsumedError(ValidateSetSubData(start, count))) {
+            return;
+        }
+
+        SetSubDataImpl(start, count, data);
+    }
+
+    void BufferBase::MapReadAsync(uint32_t start,
+                                  uint32_t size,
+                                  dawnBufferMapReadCallback callback,
+                                  dawnCallbackUserdata userdata) {
+        if (mDevice->ConsumedError(ValidateMap(start, size, dawn::BufferUsageBit::MapRead))) {
+            callback(DAWN_BUFFER_MAP_ASYNC_STATUS_ERROR, nullptr, userdata);
+            return;
+        }
+
+        ASSERT(mMapWriteCallback == nullptr);
+
+        // TODO(cwallez@chromium.org): what to do on wraparound? Could cause crashes.
+        mMapSerial++;
+        mMapReadCallback = callback;
+        mMapUserdata = userdata;
+        mIsMapped = true;
+
+        MapReadAsyncImpl(mMapSerial, start, size);
+    }
+
+    void BufferBase::MapWriteAsync(uint32_t start,
+                                   uint32_t size,
+                                   dawnBufferMapWriteCallback callback,
+                                   dawnCallbackUserdata userdata) {
+        if (mDevice->ConsumedError(ValidateMap(start, size, dawn::BufferUsageBit::MapWrite))) {
+            callback(DAWN_BUFFER_MAP_ASYNC_STATUS_ERROR, nullptr, userdata);
+            return;
+        }
+
+        ASSERT(mMapReadCallback == nullptr);
+
+        // TODO(cwallez@chromium.org): what to do on wraparound? Could cause crashes.
+        mMapSerial++;
+        mMapWriteCallback = callback;
+        mMapUserdata = userdata;
+        mIsMapped = true;
+
+        MapWriteAsyncImpl(mMapSerial, start, size);
+    }
+
+    void BufferBase::Unmap() {
+        if (mDevice->ConsumedError(ValidateUnmap())) {
+            return;
+        }
+
+        // A map request can only be called once, so this will fire only if the request wasn't
+        // completed before the Unmap
+        CallMapReadCallback(mMapSerial, DAWN_BUFFER_MAP_ASYNC_STATUS_UNKNOWN, nullptr);
+        CallMapWriteCallback(mMapSerial, DAWN_BUFFER_MAP_ASYNC_STATUS_UNKNOWN, nullptr);
+        UnmapImpl();
+        mIsMapped = false;
+        mMapReadCallback = nullptr;
+        mMapWriteCallback = nullptr;
+        mMapUserdata = 0;
+    }
+
+    MaybeError BufferBase::ValidateSetSubData(uint32_t start, uint32_t count) const {
+        // TODO(cwallez@chromium.org): check for overflows.
+        if (start + count > GetSize()) {
+            DAWN_RETURN_ERROR("Buffer subdata out of range");
+        }
+
+        if (!(mAllowedUsage & dawn::BufferUsageBit::TransferDst)) {
+            DAWN_RETURN_ERROR("Buffer needs the transfer dst usage bit");
+        }
+
+        return {};
+    }
+
+    MaybeError BufferBase::ValidateMap(uint32_t start,
+                                       uint32_t size,
+                                       dawn::BufferUsageBit requiredUsage) const {
+        // TODO(cwallez@chromium.org): check for overflows.
+        if (start + size > GetSize()) {
+            DAWN_RETURN_ERROR("Buffer map read out of range");
+        }
+
+        if (mIsMapped) {
+            DAWN_RETURN_ERROR("Buffer already mapped");
+        }
+
+        if (!(mAllowedUsage & requiredUsage)) {
+            DAWN_RETURN_ERROR("Buffer needs the correct map usage bit");
+        }
+
+        return {};
+    }
+
+    MaybeError BufferBase::ValidateUnmap() const {
+        if (!mIsMapped) {
+            DAWN_RETURN_ERROR("Buffer wasn't mapped");
+        }
+
+        return {};
+    }
+
+    // BufferBuilder
+
+    enum BufferSetProperties {
+        BUFFER_PROPERTY_ALLOWED_USAGE = 0x1,
+        BUFFER_PROPERTY_SIZE = 0x2,
+    };
+
+    BufferBuilder::BufferBuilder(DeviceBase* device) : Builder(device) {
+    }
+
+    BufferBase* BufferBuilder::GetResultImpl() {
+        constexpr int allProperties = BUFFER_PROPERTY_ALLOWED_USAGE | BUFFER_PROPERTY_SIZE;
+        if ((mPropertiesSet & allProperties) != allProperties) {
+            HandleError("Buffer missing properties");
+            return nullptr;
+        }
+
+        const dawn::BufferUsageBit kMapWriteAllowedUsages =
+            dawn::BufferUsageBit::MapWrite | dawn::BufferUsageBit::TransferSrc;
+        if (mAllowedUsage & dawn::BufferUsageBit::MapWrite &&
+            (mAllowedUsage & kMapWriteAllowedUsages) != mAllowedUsage) {
+            HandleError("Only TransferSrc is allowed with MapWrite");
+            return nullptr;
+        }
+
+        const dawn::BufferUsageBit kMapReadAllowedUsages =
+            dawn::BufferUsageBit::MapRead | dawn::BufferUsageBit::TransferDst;
+        if (mAllowedUsage & dawn::BufferUsageBit::MapRead &&
+            (mAllowedUsage & kMapReadAllowedUsages) != mAllowedUsage) {
+            HandleError("Only TransferDst is allowed with MapRead");
+            return nullptr;
+        }
+
+        return mDevice->CreateBuffer(this);
+    }
+
+    void BufferBuilder::SetAllowedUsage(dawn::BufferUsageBit usage) {
+        if ((mPropertiesSet & BUFFER_PROPERTY_ALLOWED_USAGE) != 0) {
+            HandleError("Buffer allowedUsage property set multiple times");
+            return;
+        }
+
+        mAllowedUsage = usage;
+        mPropertiesSet |= BUFFER_PROPERTY_ALLOWED_USAGE;
+    }
+
+    void BufferBuilder::SetSize(uint32_t size) {
+        if ((mPropertiesSet & BUFFER_PROPERTY_SIZE) != 0) {
+            HandleError("Buffer size property set multiple times");
+            return;
+        }
+
+        mSize = size;
+        mPropertiesSet |= BUFFER_PROPERTY_SIZE;
+    }
+
+    // BufferViewBase
+
+    BufferViewBase::BufferViewBase(BufferViewBuilder* builder)
+        : mBuffer(std::move(builder->mBuffer)), mSize(builder->mSize), mOffset(builder->mOffset) {
+    }
+
+    BufferBase* BufferViewBase::GetBuffer() {
+        return mBuffer.Get();
+    }
+
+    uint32_t BufferViewBase::GetSize() const {
+        return mSize;
+    }
+
+    uint32_t BufferViewBase::GetOffset() const {
+        return mOffset;
+    }
+
+    // BufferViewBuilder
+
+    enum BufferViewSetProperties {
+        BUFFER_VIEW_PROPERTY_EXTENT = 0x1,
+    };
+
+    BufferViewBuilder::BufferViewBuilder(DeviceBase* device, BufferBase* buffer)
+        : Builder(device), mBuffer(buffer) {
+    }
+
+    BufferViewBase* BufferViewBuilder::GetResultImpl() {
+        constexpr int allProperties = BUFFER_VIEW_PROPERTY_EXTENT;
+        if ((mPropertiesSet & allProperties) != allProperties) {
+            HandleError("Buffer view missing properties");
+            return nullptr;
+        }
+
+        return mDevice->CreateBufferView(this);
+    }
+
+    void BufferViewBuilder::SetExtent(uint32_t offset, uint32_t size) {
+        if ((mPropertiesSet & BUFFER_VIEW_PROPERTY_EXTENT) != 0) {
+            HandleError("Buffer view extent property set multiple times");
+            return;
+        }
+
+        uint64_t viewEnd = static_cast<uint64_t>(offset) + static_cast<uint64_t>(size);
+        if (viewEnd > static_cast<uint64_t>(mBuffer->GetSize())) {
+            HandleError("Buffer view end is OOB");
+            return;
+        }
+
+        mOffset = offset;
+        mSize = size;
+        mPropertiesSet |= BUFFER_VIEW_PROPERTY_EXTENT;
+    }
+
+}  // namespace backend