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>
This commit is contained in:
Corentin Wallez 2020-09-28 14:14:44 +00:00 committed by Commit Bot service account
parent 145f115c54
commit 53cdbead78
5 changed files with 33 additions and 21 deletions

View File

@ -138,7 +138,7 @@ namespace dawn_native {
BufferBase::~BufferBase() { BufferBase::~BufferBase() {
if (mState == BufferState::Mapped) { if (mState == BufferState::Mapped) {
ASSERT(!IsError()); ASSERT(!IsError());
CallMapCallback(mMapSerial, WGPUBufferMapAsyncStatus_DestroyedBeforeCallback); CallMapCallback(mLastMapID, WGPUBufferMapAsyncStatus_DestroyedBeforeCallback);
} }
} }
@ -212,9 +212,9 @@ namespace dawn_native {
} }
} }
void BufferBase::CallMapCallback(uint32_t serial, WGPUBufferMapAsyncStatus status) { void BufferBase::CallMapCallback(MapRequestID mapID, WGPUBufferMapAsyncStatus status) {
ASSERT(!IsError()); 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 // 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. // for example buffer.Unmap() is called inside the application-provided callback.
WGPUBufferMapCallback callback = mMapCallback; WGPUBufferMapCallback callback = mMapCallback;
@ -249,8 +249,7 @@ namespace dawn_native {
} }
ASSERT(!IsError()); ASSERT(!IsError());
// TODO(cwallez@chromium.org): what to do on wraparound? Could cause crashes. mLastMapID++;
mMapSerial++;
mMapMode = mode; mMapMode = mode;
mMapOffset = offset; mMapOffset = offset;
mMapSize = size; mMapSize = size;
@ -259,12 +258,12 @@ namespace dawn_native {
mState = BufferState::Mapped; mState = BufferState::Mapped;
if (GetDevice()->ConsumedError(MapAsyncImpl(mode, offset, size))) { if (GetDevice()->ConsumedError(MapAsyncImpl(mode, offset, size))) {
CallMapCallback(mMapSerial, WGPUBufferMapAsyncStatus_DeviceLost); CallMapCallback(mLastMapID, WGPUBufferMapAsyncStatus_DeviceLost);
return; return;
} }
MapRequestTracker* tracker = GetDevice()->GetMapRequestTracker(); MapRequestTracker* tracker = GetDevice()->GetMapRequestTracker();
tracker->Track(this, mMapSerial); tracker->Track(this, mLastMapID);
} }
void* BufferBase::GetMappedRange(size_t offset, size_t size) { void* BufferBase::GetMappedRange(size_t offset, size_t size) {
@ -350,7 +349,7 @@ namespace dawn_native {
// completed before the Unmap. // completed before the Unmap.
// Callbacks are not fired if there is no callback registered, so this is correct for // Callbacks are not fired if there is no callback registered, so this is correct for
// mappedAtCreation = true. // mappedAtCreation = true.
CallMapCallback(mMapSerial, callbackStatus); CallMapCallback(mLastMapID, callbackStatus);
UnmapImpl(); UnmapImpl();
mMapCallback = nullptr; mMapCallback = nullptr;
@ -514,8 +513,8 @@ namespace dawn_native {
mState = BufferState::Destroyed; mState = BufferState::Destroyed;
} }
void BufferBase::OnMapCommandSerialFinished(uint32_t mapSerial) { void BufferBase::OnMapRequestCompleted(MapRequestID mapID) {
CallMapCallback(mapSerial, WGPUBufferMapAsyncStatus_Success); CallMapCallback(mapID, WGPUBufferMapAsyncStatus_Success);
} }
bool BufferBase::IsDataInitialized() const { bool BufferBase::IsDataInitialized() const {

View File

@ -17,6 +17,7 @@
#include "dawn_native/Error.h" #include "dawn_native/Error.h"
#include "dawn_native/Forward.h" #include "dawn_native/Forward.h"
#include "dawn_native/IntegerTypes.h"
#include "dawn_native/ObjectBase.h" #include "dawn_native/ObjectBase.h"
#include "dawn_native/dawn_platform.h" #include "dawn_native/dawn_platform.h"
@ -52,7 +53,7 @@ namespace dawn_native {
wgpu::BufferUsage GetUsage() const; wgpu::BufferUsage GetUsage() const;
MaybeError MapAtCreation(); MaybeError MapAtCreation();
void OnMapCommandSerialFinished(uint32_t mapSerial); void OnMapRequestCompleted(MapRequestID mapID);
MaybeError ValidateCanUseOnQueueNow() const; MaybeError ValidateCanUseOnQueueNow() const;
@ -91,7 +92,7 @@ namespace dawn_native {
virtual bool IsCPUWritableAtCreation() const = 0; virtual bool IsCPUWritableAtCreation() const = 0;
MaybeError CopyFromStagingBuffer(); MaybeError CopyFromStagingBuffer();
void* GetMappedRangeInternal(bool writable, size_t offset, size_t size); 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, MaybeError ValidateMap(wgpu::BufferUsage requiredUsage,
WGPUBufferMapAsyncStatus* status) const; WGPUBufferMapAsyncStatus* status) const;
@ -113,7 +114,7 @@ namespace dawn_native {
WGPUBufferMapCallback mMapCallback = nullptr; WGPUBufferMapCallback mMapCallback = nullptr;
void* mMapUserdata = 0; void* mMapUserdata = 0;
uint32_t mMapSerial = 0; MapRequestID mLastMapID = MapRequestID(0);
wgpu::MapMode mMapMode = wgpu::MapMode::None; wgpu::MapMode mMapMode = wgpu::MapMode::None;
size_t mMapOffset = 0; size_t mMapOffset = 0;
size_t mMapSize = 0; size_t mMapSize = 0;

View File

@ -43,6 +43,17 @@ namespace dawn_native {
constexpr VertexAttributeLocation kMaxVertexAttributesTyped = constexpr VertexAttributeLocation kMaxVertexAttributesTyped =
VertexAttributeLocation(kMaxVertexAttributes); 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 } // namespace dawn_native
#endif // DAWNNATIVE_INTEGERTYPES_H_ #endif // DAWNNATIVE_INTEGERTYPES_H_

View File

@ -13,12 +13,11 @@
// limitations under the License. // limitations under the License.
#include "dawn_native/MapRequestTracker.h" #include "dawn_native/MapRequestTracker.h"
#include "dawn_native/Buffer.h" #include "dawn_native/Buffer.h"
#include "dawn_native/Device.h" #include "dawn_native/Device.h"
namespace dawn_native { namespace dawn_native {
struct Request;
class DeviceBase;
MapRequestTracker::MapRequestTracker(DeviceBase* device) : mDevice(device) { MapRequestTracker::MapRequestTracker(DeviceBase* device) : mDevice(device) {
} }
@ -27,10 +26,10 @@ namespace dawn_native {
ASSERT(mInflightRequests.Empty()); ASSERT(mInflightRequests.Empty());
} }
void MapRequestTracker::Track(BufferBase* buffer, uint32_t mapSerial) { void MapRequestTracker::Track(BufferBase* buffer, MapRequestID mapID) {
Request request; Request request;
request.buffer = buffer; request.buffer = buffer;
request.mapSerial = mapSerial; request.id = mapID;
mInflightRequests.Enqueue(std::move(request), mDevice->GetPendingCommandSerial()); mInflightRequests.Enqueue(std::move(request), mDevice->GetPendingCommandSerial());
mDevice->AddFutureCallbackSerial(mDevice->GetPendingCommandSerial()); mDevice->AddFutureCallbackSerial(mDevice->GetPendingCommandSerial());
@ -38,7 +37,7 @@ namespace dawn_native {
void MapRequestTracker::Tick(Serial finishedSerial) { void MapRequestTracker::Tick(Serial finishedSerial) {
for (auto& request : mInflightRequests.IterateUpTo(finishedSerial)) { for (auto& request : mInflightRequests.IterateUpTo(finishedSerial)) {
request.buffer->OnMapCommandSerialFinished(request.mapSerial); request.buffer->OnMapRequestCompleted(request.id);
} }
mInflightRequests.ClearUpTo(finishedSerial); mInflightRequests.ClearUpTo(finishedSerial);
} }

View File

@ -16,7 +16,9 @@
#define DAWNNATIVE_MAPREQUESTTRACKER_H_ #define DAWNNATIVE_MAPREQUESTTRACKER_H_
#include "common/SerialQueue.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 { namespace dawn_native {
@ -25,7 +27,7 @@ namespace dawn_native {
MapRequestTracker(DeviceBase* device); MapRequestTracker(DeviceBase* device);
~MapRequestTracker(); ~MapRequestTracker();
void Track(BufferBase* buffer, uint32_t mapSerial); void Track(BufferBase* buffer, MapRequestID mapID);
void Tick(Serial finishedSerial); void Tick(Serial finishedSerial);
private: private:
@ -33,7 +35,7 @@ namespace dawn_native {
struct Request { struct Request {
Ref<BufferBase> buffer; Ref<BufferBase> buffer;
uint32_t mapSerial; MapRequestID id;
}; };
SerialQueue<Serial, Request> mInflightRequests; SerialQueue<Serial, Request> mInflightRequests;
}; };