Use typed integers for the Buffer MapRequestID
This will prevent mixing it up with other serial types in the future.
Bug: dawn:442
Change-Id: Ie655d57722fcd79c82acc5aac429aed2c2741c3e
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/28920
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
diff --git a/src/dawn_native/Buffer.cpp b/src/dawn_native/Buffer.cpp
index aa9af0a..9ec821e 100644
--- a/src/dawn_native/Buffer.cpp
+++ b/src/dawn_native/Buffer.cpp
@@ -138,7 +138,7 @@
BufferBase::~BufferBase() {
if (mState == BufferState::Mapped) {
ASSERT(!IsError());
- CallMapCallback(mMapSerial, WGPUBufferMapAsyncStatus_DestroyedBeforeCallback);
+ CallMapCallback(mLastMapID, WGPUBufferMapAsyncStatus_DestroyedBeforeCallback);
}
}
@@ -212,9 +212,9 @@
}
}
- void BufferBase::CallMapCallback(uint32_t serial, WGPUBufferMapAsyncStatus status) {
+ void BufferBase::CallMapCallback(MapRequestID mapID, WGPUBufferMapAsyncStatus status) {
ASSERT(!IsError());
- if (mMapCallback != nullptr && serial == mMapSerial) {
+ if (mMapCallback != nullptr && mapID == mLastMapID) {
// 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.
WGPUBufferMapCallback callback = mMapCallback;
@@ -249,8 +249,7 @@
}
ASSERT(!IsError());
- // TODO(cwallez@chromium.org): what to do on wraparound? Could cause crashes.
- mMapSerial++;
+ mLastMapID++;
mMapMode = mode;
mMapOffset = offset;
mMapSize = size;
@@ -259,12 +258,12 @@
mState = BufferState::Mapped;
if (GetDevice()->ConsumedError(MapAsyncImpl(mode, offset, size))) {
- CallMapCallback(mMapSerial, WGPUBufferMapAsyncStatus_DeviceLost);
+ CallMapCallback(mLastMapID, WGPUBufferMapAsyncStatus_DeviceLost);
return;
}
MapRequestTracker* tracker = GetDevice()->GetMapRequestTracker();
- tracker->Track(this, mMapSerial);
+ tracker->Track(this, mLastMapID);
}
void* BufferBase::GetMappedRange(size_t offset, size_t size) {
@@ -350,7 +349,7 @@
// completed before the Unmap.
// Callbacks are not fired if there is no callback registered, so this is correct for
// mappedAtCreation = true.
- CallMapCallback(mMapSerial, callbackStatus);
+ CallMapCallback(mLastMapID, callbackStatus);
UnmapImpl();
mMapCallback = nullptr;
@@ -514,8 +513,8 @@
mState = BufferState::Destroyed;
}
- void BufferBase::OnMapCommandSerialFinished(uint32_t mapSerial) {
- CallMapCallback(mapSerial, WGPUBufferMapAsyncStatus_Success);
+ void BufferBase::OnMapRequestCompleted(MapRequestID mapID) {
+ CallMapCallback(mapID, WGPUBufferMapAsyncStatus_Success);
}
bool BufferBase::IsDataInitialized() const {
diff --git a/src/dawn_native/Buffer.h b/src/dawn_native/Buffer.h
index fc6353c..675b071 100644
--- a/src/dawn_native/Buffer.h
+++ b/src/dawn_native/Buffer.h
@@ -17,6 +17,7 @@
#include "dawn_native/Error.h"
#include "dawn_native/Forward.h"
+#include "dawn_native/IntegerTypes.h"
#include "dawn_native/ObjectBase.h"
#include "dawn_native/dawn_platform.h"
@@ -52,7 +53,7 @@
wgpu::BufferUsage GetUsage() const;
MaybeError MapAtCreation();
- void OnMapCommandSerialFinished(uint32_t mapSerial);
+ void OnMapRequestCompleted(MapRequestID mapID);
MaybeError ValidateCanUseOnQueueNow() const;
@@ -91,7 +92,7 @@
virtual bool IsCPUWritableAtCreation() const = 0;
MaybeError CopyFromStagingBuffer();
void* GetMappedRangeInternal(bool writable, size_t offset, size_t size);
- void CallMapCallback(uint32_t serial, WGPUBufferMapAsyncStatus status);
+ void CallMapCallback(MapRequestID mapID, WGPUBufferMapAsyncStatus status);
MaybeError ValidateMap(wgpu::BufferUsage requiredUsage,
WGPUBufferMapAsyncStatus* status) const;
@@ -113,7 +114,7 @@
WGPUBufferMapCallback mMapCallback = nullptr;
void* mMapUserdata = 0;
- uint32_t mMapSerial = 0;
+ MapRequestID mLastMapID = MapRequestID(0);
wgpu::MapMode mMapMode = wgpu::MapMode::None;
size_t mMapOffset = 0;
size_t mMapSize = 0;
diff --git a/src/dawn_native/IntegerTypes.h b/src/dawn_native/IntegerTypes.h
index bd31c79..3b72722 100644
--- a/src/dawn_native/IntegerTypes.h
+++ b/src/dawn_native/IntegerTypes.h
@@ -43,6 +43,17 @@
constexpr VertexAttributeLocation kMaxVertexAttributesTyped =
VertexAttributeLocation(kMaxVertexAttributes);
+ // Serials are 64bit integers that are incremented by one each time to produce unique values.
+ // Some serials (like queue serials) are compared numerically to know which one is before
+ // another, while some serials are only checked for equality. We call serials only checked
+ // for equality IDs.
+
+ // Buffer mapping requests are stored outside of the buffer while they are being processed and
+ // cannot be invalidated. Instead they are associated with an ID, and when a map request is
+ // finished, the mapping callback is fired only if its ID matches the ID if the last request
+ // that was sent.
+ using MapRequestID = TypedInteger<struct MapRequestIDT, uint64_t>;
+
} // namespace dawn_native
#endif // DAWNNATIVE_INTEGERTYPES_H_
diff --git a/src/dawn_native/MapRequestTracker.cpp b/src/dawn_native/MapRequestTracker.cpp
index faf7034..ef7c49c 100644
--- a/src/dawn_native/MapRequestTracker.cpp
+++ b/src/dawn_native/MapRequestTracker.cpp
@@ -13,12 +13,11 @@
// limitations under the License.
#include "dawn_native/MapRequestTracker.h"
+
#include "dawn_native/Buffer.h"
#include "dawn_native/Device.h"
namespace dawn_native {
- struct Request;
- class DeviceBase;
MapRequestTracker::MapRequestTracker(DeviceBase* device) : mDevice(device) {
}
@@ -27,10 +26,10 @@
ASSERT(mInflightRequests.Empty());
}
- void MapRequestTracker::Track(BufferBase* buffer, uint32_t mapSerial) {
+ void MapRequestTracker::Track(BufferBase* buffer, MapRequestID mapID) {
Request request;
request.buffer = buffer;
- request.mapSerial = mapSerial;
+ request.id = mapID;
mInflightRequests.Enqueue(std::move(request), mDevice->GetPendingCommandSerial());
mDevice->AddFutureCallbackSerial(mDevice->GetPendingCommandSerial());
@@ -38,7 +37,7 @@
void MapRequestTracker::Tick(Serial finishedSerial) {
for (auto& request : mInflightRequests.IterateUpTo(finishedSerial)) {
- request.buffer->OnMapCommandSerialFinished(request.mapSerial);
+ request.buffer->OnMapRequestCompleted(request.id);
}
mInflightRequests.ClearUpTo(finishedSerial);
}
diff --git a/src/dawn_native/MapRequestTracker.h b/src/dawn_native/MapRequestTracker.h
index 06eae3d..2afad01 100644
--- a/src/dawn_native/MapRequestTracker.h
+++ b/src/dawn_native/MapRequestTracker.h
@@ -16,7 +16,9 @@
#define DAWNNATIVE_MAPREQUESTTRACKER_H_
#include "common/SerialQueue.h"
-#include "dawn_native/Device.h"
+#include "dawn_native/Buffer.h"
+#include "dawn_native/Forward.h"
+#include "dawn_native/IntegerTypes.h"
namespace dawn_native {
@@ -25,7 +27,7 @@
MapRequestTracker(DeviceBase* device);
~MapRequestTracker();
- void Track(BufferBase* buffer, uint32_t mapSerial);
+ void Track(BufferBase* buffer, MapRequestID mapID);
void Tick(Serial finishedSerial);
private:
@@ -33,7 +35,7 @@
struct Request {
Ref<BufferBase> buffer;
- uint32_t mapSerial;
+ MapRequestID id;
};
SerialQueue<Serial, Request> mInflightRequests;
};