Remove CreateBufferMappedAsync
The upstream WebGPU spec decided to not pursue CreateBufferMappedAsync, and it adds some complexity to Dawn, so we remove it. Bug: dawn:22 Change-Id: I4182a90c4a1aa0bfbaecd7d8f67d7049cf5df5d6 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/17321 Commit-Queue: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Austin Eng <enga@chromium.org>
This commit is contained in:
parent
e3f44e3cd6
commit
0ff7ed41ec
16
dawn.json
16
dawn.json
|
@ -203,14 +203,6 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"buffer create mapped callback": {
|
|
||||||
"category": "callback",
|
|
||||||
"args": [
|
|
||||||
{"name": "status", "type": "buffer map async status"},
|
|
||||||
{"name": "result", "type": "create buffer mapped result"},
|
|
||||||
{"name": "userdata", "type": "void", "annotation": "*"}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"buffer copy view": {
|
"buffer copy view": {
|
||||||
"category": "structure",
|
"category": "structure",
|
||||||
"extensible": true,
|
"extensible": true,
|
||||||
|
@ -533,14 +525,6 @@
|
||||||
{"name": "descriptor", "type": "buffer descriptor", "annotation": "const*"}
|
{"name": "descriptor", "type": "buffer descriptor", "annotation": "const*"}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "create buffer mapped async",
|
|
||||||
"args": [
|
|
||||||
{"name": "descriptor", "type": "buffer descriptor", "annotation": "const*"},
|
|
||||||
{"name": "callback", "type": "buffer create mapped callback"},
|
|
||||||
{"name": "userdata", "type": "void", "annotation": "*"}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "create command encoder",
|
"name": "create command encoder",
|
||||||
"returns": "command encoder",
|
"returns": "command encoder",
|
||||||
|
|
|
@ -40,14 +40,6 @@
|
||||||
{ "name": "handle create info length", "type": "uint64_t" },
|
{ "name": "handle create info length", "type": "uint64_t" },
|
||||||
{ "name": "handle create info", "type": "uint8_t", "annotation": "const*", "length": "handle create info length", "skip_serialize": true}
|
{ "name": "handle create info", "type": "uint8_t", "annotation": "const*", "length": "handle create info length", "skip_serialize": true}
|
||||||
],
|
],
|
||||||
"device create buffer mapped async": [
|
|
||||||
{ "name": "device", "type": "device" },
|
|
||||||
{ "name": "descriptor", "type": "buffer descriptor", "annotation": "const*" },
|
|
||||||
{ "name": "request serial", "type": "uint32_t" },
|
|
||||||
{ "name": "result", "type": "ObjectHandle", "handle_type": "buffer" },
|
|
||||||
{ "name": "handle create info length", "type": "uint64_t" },
|
|
||||||
{ "name": "handle create info", "type": "uint8_t", "annotation": "const*", "length": "handle create info length", "skip_serialize": true}
|
|
||||||
],
|
|
||||||
"device pop error scope": [
|
"device pop error scope": [
|
||||||
{ "name": "device", "type": "device" },
|
{ "name": "device", "type": "device" },
|
||||||
{ "name": "request serial", "type": "uint64_t" }
|
{ "name": "request serial", "type": "uint64_t" }
|
||||||
|
@ -98,7 +90,6 @@
|
||||||
"BufferMapReadAsync",
|
"BufferMapReadAsync",
|
||||||
"BufferMapWriteAsync",
|
"BufferMapWriteAsync",
|
||||||
"BufferSetSubData",
|
"BufferSetSubData",
|
||||||
"DeviceCreateBufferMappedAsync",
|
|
||||||
"DevicePopErrorScope",
|
"DevicePopErrorScope",
|
||||||
"DeviceSetDeviceLostCallback",
|
"DeviceSetDeviceLostCallback",
|
||||||
"DeviceSetUncapturedErrorCallback",
|
"DeviceSetUncapturedErrorCallback",
|
||||||
|
|
|
@ -76,17 +76,6 @@ bool ProcTableAsClass::DevicePopErrorScope(WGPUDevice self,
|
||||||
return OnDevicePopErrorScopeCallback(self, callback, userdata);
|
return OnDevicePopErrorScopeCallback(self, callback, userdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProcTableAsClass::DeviceCreateBufferMappedAsync(WGPUDevice self,
|
|
||||||
const WGPUBufferDescriptor* descriptor,
|
|
||||||
WGPUBufferCreateMappedCallback callback,
|
|
||||||
void* userdata) {
|
|
||||||
auto object = reinterpret_cast<ProcTableAsClass::Object*>(self);
|
|
||||||
object->createBufferMappedCallback = callback;
|
|
||||||
object->userdata = userdata;
|
|
||||||
|
|
||||||
OnDeviceCreateBufferMappedAsyncCallback(self, descriptor, callback, userdata);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ProcTableAsClass::BufferMapReadAsync(WGPUBuffer self,
|
void ProcTableAsClass::BufferMapReadAsync(WGPUBuffer self,
|
||||||
WGPUBufferMapReadCallback callback,
|
WGPUBufferMapReadCallback callback,
|
||||||
void* userdata) {
|
void* userdata) {
|
||||||
|
@ -130,12 +119,6 @@ void ProcTableAsClass::CallDeviceLostCallback(WGPUDevice device, const char* mes
|
||||||
object->deviceLostCallback(message, object->userdata);
|
object->deviceLostCallback(message, object->userdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProcTableAsClass::CallCreateBufferMappedCallback(WGPUDevice device,
|
|
||||||
WGPUBufferMapAsyncStatus status,
|
|
||||||
WGPUCreateBufferMappedResult result) {
|
|
||||||
auto object = reinterpret_cast<ProcTableAsClass::Object*>(device);
|
|
||||||
object->createBufferMappedCallback(status, result, object->userdata);
|
|
||||||
}
|
|
||||||
void ProcTableAsClass::CallMapReadCallback(WGPUBuffer buffer,
|
void ProcTableAsClass::CallMapReadCallback(WGPUBuffer buffer,
|
||||||
WGPUBufferMapAsyncStatus status,
|
WGPUBufferMapAsyncStatus status,
|
||||||
const void* data,
|
const void* data,
|
||||||
|
|
|
@ -59,10 +59,6 @@ class ProcTableAsClass {
|
||||||
WGPUDeviceLostCallback callback,
|
WGPUDeviceLostCallback callback,
|
||||||
void* userdata);
|
void* userdata);
|
||||||
bool DevicePopErrorScope(WGPUDevice self, WGPUErrorCallback callback, void* userdata);
|
bool DevicePopErrorScope(WGPUDevice self, WGPUErrorCallback callback, void* userdata);
|
||||||
void DeviceCreateBufferMappedAsync(WGPUDevice self,
|
|
||||||
const WGPUBufferDescriptor* descriptor,
|
|
||||||
WGPUBufferCreateMappedCallback callback,
|
|
||||||
void* userdata);
|
|
||||||
void BufferMapReadAsync(WGPUBuffer self,
|
void BufferMapReadAsync(WGPUBuffer self,
|
||||||
WGPUBufferMapReadCallback callback,
|
WGPUBufferMapReadCallback callback,
|
||||||
void* userdata);
|
void* userdata);
|
||||||
|
@ -84,10 +80,6 @@ class ProcTableAsClass {
|
||||||
virtual bool OnDevicePopErrorScopeCallback(WGPUDevice device,
|
virtual bool OnDevicePopErrorScopeCallback(WGPUDevice device,
|
||||||
WGPUErrorCallback callback,
|
WGPUErrorCallback callback,
|
||||||
void* userdata) = 0;
|
void* userdata) = 0;
|
||||||
virtual void OnDeviceCreateBufferMappedAsyncCallback(WGPUDevice self,
|
|
||||||
const WGPUBufferDescriptor* descriptor,
|
|
||||||
WGPUBufferCreateMappedCallback callback,
|
|
||||||
void* userdata) = 0;
|
|
||||||
virtual void OnBufferMapReadAsyncCallback(WGPUBuffer buffer,
|
virtual void OnBufferMapReadAsyncCallback(WGPUBuffer buffer,
|
||||||
WGPUBufferMapReadCallback callback,
|
WGPUBufferMapReadCallback callback,
|
||||||
void* userdata) = 0;
|
void* userdata) = 0;
|
||||||
|
@ -102,7 +94,6 @@ class ProcTableAsClass {
|
||||||
// Calls the stored callbacks
|
// Calls the stored callbacks
|
||||||
void CallDeviceErrorCallback(WGPUDevice device, WGPUErrorType type, const char* message);
|
void CallDeviceErrorCallback(WGPUDevice device, WGPUErrorType type, const char* message);
|
||||||
void CallDeviceLostCallback(WGPUDevice device, const char* message);
|
void CallDeviceLostCallback(WGPUDevice device, const char* message);
|
||||||
void CallCreateBufferMappedCallback(WGPUDevice device, WGPUBufferMapAsyncStatus status, WGPUCreateBufferMappedResult result);
|
|
||||||
void CallMapReadCallback(WGPUBuffer buffer, WGPUBufferMapAsyncStatus status, const void* data, uint64_t dataLength);
|
void CallMapReadCallback(WGPUBuffer buffer, WGPUBufferMapAsyncStatus status, const void* data, uint64_t dataLength);
|
||||||
void CallMapWriteCallback(WGPUBuffer buffer, WGPUBufferMapAsyncStatus status, void* data, uint64_t dataLength);
|
void CallMapWriteCallback(WGPUBuffer buffer, WGPUBufferMapAsyncStatus status, void* data, uint64_t dataLength);
|
||||||
void CallFenceOnCompletionCallback(WGPUFence fence, WGPUFenceCompletionStatus status);
|
void CallFenceOnCompletionCallback(WGPUFence fence, WGPUFenceCompletionStatus status);
|
||||||
|
@ -111,7 +102,6 @@ class ProcTableAsClass {
|
||||||
ProcTableAsClass* procs = nullptr;
|
ProcTableAsClass* procs = nullptr;
|
||||||
WGPUErrorCallback deviceErrorCallback = nullptr;
|
WGPUErrorCallback deviceErrorCallback = nullptr;
|
||||||
WGPUDeviceLostCallback deviceLostCallback = nullptr;
|
WGPUDeviceLostCallback deviceLostCallback = nullptr;
|
||||||
WGPUBufferCreateMappedCallback createBufferMappedCallback = nullptr;
|
|
||||||
WGPUBufferMapReadCallback mapReadCallback = nullptr;
|
WGPUBufferMapReadCallback mapReadCallback = nullptr;
|
||||||
WGPUBufferMapWriteCallback mapWriteCallback = nullptr;
|
WGPUBufferMapWriteCallback mapWriteCallback = nullptr;
|
||||||
WGPUFenceOnCompletionCallback fenceOnCompletionCallback = nullptr;
|
WGPUFenceOnCompletionCallback fenceOnCompletionCallback = nullptr;
|
||||||
|
@ -149,7 +139,6 @@ class MockProcTable : public ProcTableAsClass {
|
||||||
MOCK_METHOD3(OnDeviceSetDeviceLostCallback,
|
MOCK_METHOD3(OnDeviceSetDeviceLostCallback,
|
||||||
void(WGPUDevice device, WGPUDeviceLostCallback callback, void* userdata));
|
void(WGPUDevice device, WGPUDeviceLostCallback callback, void* userdata));
|
||||||
MOCK_METHOD3(OnDevicePopErrorScopeCallback, bool(WGPUDevice device, WGPUErrorCallback callback, void* userdata));
|
MOCK_METHOD3(OnDevicePopErrorScopeCallback, bool(WGPUDevice device, WGPUErrorCallback callback, void* userdata));
|
||||||
MOCK_METHOD4(OnDeviceCreateBufferMappedAsyncCallback, void(WGPUDevice device, const WGPUBufferDescriptor* descriptor, WGPUBufferCreateMappedCallback callback, void* userdata));
|
|
||||||
MOCK_METHOD3(OnBufferMapReadAsyncCallback, void(WGPUBuffer buffer, WGPUBufferMapReadCallback callback, void* userdata));
|
MOCK_METHOD3(OnBufferMapReadAsyncCallback, void(WGPUBuffer buffer, WGPUBufferMapReadCallback callback, void* userdata));
|
||||||
MOCK_METHOD3(OnBufferMapWriteAsyncCallback, void(WGPUBuffer buffer, WGPUBufferMapWriteCallback callback, void* userdata));
|
MOCK_METHOD3(OnBufferMapWriteAsyncCallback, void(WGPUBuffer buffer, WGPUBufferMapWriteCallback callback, void* userdata));
|
||||||
MOCK_METHOD4(OnFenceOnCompletionCallback,
|
MOCK_METHOD4(OnFenceOnCompletionCallback,
|
||||||
|
|
|
@ -87,7 +87,6 @@ namespace dawn_native {
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceBase::~DeviceBase() {
|
DeviceBase::~DeviceBase() {
|
||||||
ASSERT(mDeferredCreateBufferMappedAsyncResults.empty());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MaybeError DeviceBase::Initialize() {
|
MaybeError DeviceBase::Initialize() {
|
||||||
|
@ -544,27 +543,6 @@ namespace dawn_native {
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
void DeviceBase::CreateBufferMappedAsync(const BufferDescriptor* descriptor,
|
|
||||||
wgpu::BufferCreateMappedCallback callback,
|
|
||||||
void* userdata) {
|
|
||||||
WGPUCreateBufferMappedResult result = CreateBufferMapped(descriptor);
|
|
||||||
|
|
||||||
WGPUBufferMapAsyncStatus status = WGPUBufferMapAsyncStatus_Success;
|
|
||||||
if (IsLost()) {
|
|
||||||
status = WGPUBufferMapAsyncStatus_DeviceLost;
|
|
||||||
} else if (result.data == nullptr || result.dataLength != descriptor->size) {
|
|
||||||
status = WGPUBufferMapAsyncStatus_Error;
|
|
||||||
}
|
|
||||||
|
|
||||||
DeferredCreateBufferMappedAsync deferred_info;
|
|
||||||
deferred_info.callback = callback;
|
|
||||||
deferred_info.status = status;
|
|
||||||
deferred_info.result = result;
|
|
||||||
deferred_info.userdata = userdata;
|
|
||||||
|
|
||||||
// The callback is deferred so it matches the async behavior of WebGPU.
|
|
||||||
mDeferredCreateBufferMappedAsyncResults.push_back(deferred_info);
|
|
||||||
}
|
|
||||||
CommandEncoder* DeviceBase::CreateCommandEncoder(const CommandEncoderDescriptor* descriptor) {
|
CommandEncoder* DeviceBase::CreateCommandEncoder(const CommandEncoderDescriptor* descriptor) {
|
||||||
return new CommandEncoder(this, descriptor);
|
return new CommandEncoder(this, descriptor);
|
||||||
}
|
}
|
||||||
|
@ -668,14 +646,6 @@ namespace dawn_native {
|
||||||
// Other Device API methods
|
// Other Device API methods
|
||||||
|
|
||||||
void DeviceBase::Tick() {
|
void DeviceBase::Tick() {
|
||||||
// We need to do the deferred callback even if Device is lost since Buffer Map Async will
|
|
||||||
// send callback with device lost status when device is lost.
|
|
||||||
{
|
|
||||||
auto deferredResults = std::move(mDeferredCreateBufferMappedAsyncResults);
|
|
||||||
for (const auto& deferred : deferredResults) {
|
|
||||||
deferred.callback(deferred.status, deferred.result, deferred.userdata);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ConsumedError(ValidateIsAlive())) {
|
if (ConsumedError(ValidateIsAlive())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,9 +140,6 @@ namespace dawn_native {
|
||||||
BindGroupLayoutBase* CreateBindGroupLayout(const BindGroupLayoutDescriptor* descriptor);
|
BindGroupLayoutBase* CreateBindGroupLayout(const BindGroupLayoutDescriptor* descriptor);
|
||||||
BufferBase* CreateBuffer(const BufferDescriptor* descriptor);
|
BufferBase* CreateBuffer(const BufferDescriptor* descriptor);
|
||||||
WGPUCreateBufferMappedResult CreateBufferMapped(const BufferDescriptor* descriptor);
|
WGPUCreateBufferMappedResult CreateBufferMapped(const BufferDescriptor* descriptor);
|
||||||
void CreateBufferMappedAsync(const BufferDescriptor* descriptor,
|
|
||||||
wgpu::BufferCreateMappedCallback callback,
|
|
||||||
void* userdata);
|
|
||||||
CommandEncoder* CreateCommandEncoder(const CommandEncoderDescriptor* descriptor);
|
CommandEncoder* CreateCommandEncoder(const CommandEncoderDescriptor* descriptor);
|
||||||
ComputePipelineBase* CreateComputePipeline(const ComputePipelineDescriptor* descriptor);
|
ComputePipelineBase* CreateComputePipeline(const ComputePipelineDescriptor* descriptor);
|
||||||
PipelineLayoutBase* CreatePipelineLayout(const PipelineLayoutDescriptor* descriptor);
|
PipelineLayoutBase* CreatePipelineLayout(const PipelineLayoutDescriptor* descriptor);
|
||||||
|
@ -305,17 +302,9 @@ namespace dawn_native {
|
||||||
struct Caches;
|
struct Caches;
|
||||||
std::unique_ptr<Caches> mCaches;
|
std::unique_ptr<Caches> mCaches;
|
||||||
|
|
||||||
struct DeferredCreateBufferMappedAsync {
|
|
||||||
wgpu::BufferCreateMappedCallback callback;
|
|
||||||
WGPUBufferMapAsyncStatus status;
|
|
||||||
WGPUCreateBufferMappedResult result;
|
|
||||||
void* userdata;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::unique_ptr<DynamicUploader> mDynamicUploader;
|
std::unique_ptr<DynamicUploader> mDynamicUploader;
|
||||||
std::unique_ptr<ErrorScopeTracker> mErrorScopeTracker;
|
std::unique_ptr<ErrorScopeTracker> mErrorScopeTracker;
|
||||||
std::unique_ptr<FenceSignalTracker> mFenceSignalTracker;
|
std::unique_ptr<FenceSignalTracker> mFenceSignalTracker;
|
||||||
std::vector<DeferredCreateBufferMappedAsync> mDeferredCreateBufferMappedAsyncResults;
|
|
||||||
|
|
||||||
uint32_t mRefCount = 1;
|
uint32_t mRefCount = 1;
|
||||||
State mState = State::BeingCreated;
|
State mState = State::BeingCreated;
|
||||||
|
|
|
@ -190,80 +190,6 @@ namespace dawn_wire { namespace client {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientDeviceCreateBufferMappedAsync(WGPUDevice cDevice,
|
|
||||||
const WGPUBufferDescriptor* descriptor,
|
|
||||||
WGPUBufferCreateMappedCallback callback,
|
|
||||||
void* userdata) {
|
|
||||||
Device* device = reinterpret_cast<Device*>(cDevice);
|
|
||||||
Client* wireClient = device->GetClient();
|
|
||||||
|
|
||||||
auto* bufferObjectAndSerial = wireClient->BufferAllocator().New(device);
|
|
||||||
Buffer* buffer = bufferObjectAndSerial->object.get();
|
|
||||||
buffer->size = descriptor->size;
|
|
||||||
|
|
||||||
uint32_t serial = buffer->requestSerial++;
|
|
||||||
|
|
||||||
struct CreateBufferMappedInfo {
|
|
||||||
WGPUBuffer buffer;
|
|
||||||
WGPUBufferCreateMappedCallback callback;
|
|
||||||
void* userdata;
|
|
||||||
};
|
|
||||||
|
|
||||||
CreateBufferMappedInfo* info = new CreateBufferMappedInfo;
|
|
||||||
info->buffer = reinterpret_cast<WGPUBuffer>(buffer);
|
|
||||||
info->callback = callback;
|
|
||||||
info->userdata = userdata;
|
|
||||||
|
|
||||||
// Create a WriteHandle for the map request. This is the client's intent to write GPU
|
|
||||||
// memory.
|
|
||||||
MemoryTransferService::WriteHandle* writeHandle =
|
|
||||||
wireClient->GetMemoryTransferService()->CreateWriteHandle(descriptor->size);
|
|
||||||
if (writeHandle == nullptr) {
|
|
||||||
WGPUCreateBufferMappedResult result;
|
|
||||||
result.buffer = reinterpret_cast<WGPUBuffer>(buffer);
|
|
||||||
result.data = nullptr;
|
|
||||||
result.dataLength = 0;
|
|
||||||
callback(WGPUBufferMapAsyncStatus_DeviceLost, result, userdata);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Buffer::MapRequestData request;
|
|
||||||
request.writeCallback = [](WGPUBufferMapAsyncStatus status, void* data, uint64_t dataLength,
|
|
||||||
void* userdata) {
|
|
||||||
auto info = std::unique_ptr<CreateBufferMappedInfo>(
|
|
||||||
static_cast<CreateBufferMappedInfo*>(userdata));
|
|
||||||
|
|
||||||
WGPUCreateBufferMappedResult result;
|
|
||||||
result.buffer = info->buffer;
|
|
||||||
result.data = data;
|
|
||||||
result.dataLength = dataLength;
|
|
||||||
|
|
||||||
info->callback(status, result, info->userdata);
|
|
||||||
};
|
|
||||||
request.userdata = info;
|
|
||||||
// The handle is owned by the MapRequest until the callback returns.
|
|
||||||
request.writeHandle = std::unique_ptr<MemoryTransferService::WriteHandle>(writeHandle);
|
|
||||||
buffer->requests[serial] = std::move(request);
|
|
||||||
|
|
||||||
// Get the serialization size of the WriteHandle.
|
|
||||||
size_t handleCreateInfoLength = writeHandle->SerializeCreateSize();
|
|
||||||
|
|
||||||
DeviceCreateBufferMappedAsyncCmd cmd;
|
|
||||||
cmd.device = cDevice;
|
|
||||||
cmd.descriptor = descriptor;
|
|
||||||
cmd.requestSerial = serial;
|
|
||||||
cmd.result = ObjectHandle{buffer->id, bufferObjectAndSerial->generation};
|
|
||||||
cmd.handleCreateInfoLength = handleCreateInfoLength;
|
|
||||||
cmd.handleCreateInfo = nullptr;
|
|
||||||
|
|
||||||
size_t commandSize = cmd.GetRequiredSize();
|
|
||||||
size_t requiredSize = commandSize + handleCreateInfoLength;
|
|
||||||
char* allocatedBuffer = static_cast<char*>(wireClient->GetCmdSpace(requiredSize));
|
|
||||||
cmd.Serialize(allocatedBuffer, *wireClient);
|
|
||||||
// Serialize the WriteHandle into the space after the command.
|
|
||||||
writeHandle->SerializeCreate(allocatedBuffer + commandSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClientDevicePushErrorScope(WGPUDevice cDevice, WGPUErrorFilter filter) {
|
void ClientDevicePushErrorScope(WGPUDevice cDevice, WGPUErrorFilter filter) {
|
||||||
Device* device = reinterpret_cast<Device*>(cDevice);
|
Device* device = reinterpret_cast<Device*>(cDevice);
|
||||||
device->PushErrorScope(filter);
|
device->PushErrorScope(filter);
|
||||||
|
|
|
@ -153,34 +153,6 @@ namespace dawn_wire { namespace server {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Server::DoDeviceCreateBufferMappedAsync(WGPUDevice device,
|
|
||||||
const WGPUBufferDescriptor* descriptor,
|
|
||||||
uint32_t requestSerial,
|
|
||||||
ObjectHandle bufferResult,
|
|
||||||
uint64_t handleCreateInfoLength,
|
|
||||||
const uint8_t* handleCreateInfo) {
|
|
||||||
if (!DoDeviceCreateBufferMapped(device, descriptor, bufferResult, handleCreateInfoLength,
|
|
||||||
handleCreateInfo)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto* bufferData = BufferObjects().Get(bufferResult.id);
|
|
||||||
ASSERT(bufferData != nullptr);
|
|
||||||
|
|
||||||
ReturnBufferMapWriteAsyncCallbackCmd cmd;
|
|
||||||
cmd.buffer = ObjectHandle{bufferResult.id, bufferResult.generation};
|
|
||||||
cmd.requestSerial = requestSerial;
|
|
||||||
cmd.status = bufferData->mapWriteState == BufferMapWriteState::Mapped
|
|
||||||
? WGPUBufferMapAsyncStatus_Success
|
|
||||||
: WGPUBufferMapAsyncStatus_Error;
|
|
||||||
|
|
||||||
size_t requiredSize = cmd.GetRequiredSize();
|
|
||||||
char* allocatedBuffer = static_cast<char*>(GetCmdSpace(requiredSize));
|
|
||||||
cmd.Serialize(allocatedBuffer);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Server::DoBufferSetSubDataInternal(ObjectId bufferId,
|
bool Server::DoBufferSetSubDataInternal(ObjectId bufferId,
|
||||||
uint64_t start,
|
uint64_t start,
|
||||||
uint64_t offset,
|
uint64_t offset,
|
||||||
|
|
|
@ -410,50 +410,6 @@ class CreateBufferMappedTests : public DawnTest {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <WGPUBufferMapAsyncStatus expectedStatus = WGPUBufferMapAsyncStatus_Success>
|
|
||||||
wgpu::CreateBufferMappedResult CreateBufferMappedAsyncAndWait(wgpu::BufferUsage usage,
|
|
||||||
uint64_t size) {
|
|
||||||
wgpu::BufferDescriptor descriptor = {};
|
|
||||||
descriptor.size = size;
|
|
||||||
descriptor.usage = usage;
|
|
||||||
|
|
||||||
struct ResultInfo {
|
|
||||||
wgpu::CreateBufferMappedResult result;
|
|
||||||
bool done = false;
|
|
||||||
} resultInfo;
|
|
||||||
|
|
||||||
device.CreateBufferMappedAsync(
|
|
||||||
&descriptor,
|
|
||||||
[](WGPUBufferMapAsyncStatus status, WGPUCreateBufferMappedResult result,
|
|
||||||
void* userdata) {
|
|
||||||
ASSERT_EQ(status, expectedStatus);
|
|
||||||
auto* resultInfo = reinterpret_cast<ResultInfo*>(userdata);
|
|
||||||
resultInfo->result.buffer = wgpu::Buffer::Acquire(result.buffer);
|
|
||||||
resultInfo->result.data = result.data;
|
|
||||||
resultInfo->result.dataLength = result.dataLength;
|
|
||||||
resultInfo->done = true;
|
|
||||||
},
|
|
||||||
&resultInfo);
|
|
||||||
|
|
||||||
while (!resultInfo.done) {
|
|
||||||
WaitABit();
|
|
||||||
}
|
|
||||||
|
|
||||||
CheckResultStartsZeroed(resultInfo.result, size);
|
|
||||||
|
|
||||||
return resultInfo.result;
|
|
||||||
}
|
|
||||||
|
|
||||||
wgpu::CreateBufferMappedResult CreateBufferMappedAsyncWithDataAndWait(
|
|
||||||
wgpu::BufferUsage usage,
|
|
||||||
const std::vector<uint32_t>& data) {
|
|
||||||
size_t byteLength = data.size() * sizeof(uint32_t);
|
|
||||||
wgpu::CreateBufferMappedResult result = CreateBufferMappedAsyncAndWait(usage, byteLength);
|
|
||||||
memcpy(result.data, data.data(), byteLength);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const void* mappedData = nullptr;
|
const void* mappedData = nullptr;
|
||||||
};
|
};
|
||||||
|
@ -592,140 +548,6 @@ TEST_P(CreateBufferMappedTests, CreateThenMapBeforeUnmapFailure) {
|
||||||
EXPECT_BUFFER_U32_EQ(myData, result.buffer, 0);
|
EXPECT_BUFFER_U32_EQ(myData, result.buffer, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that the simplest CreateBufferMappedAsync works for MapWrite buffers.
|
|
||||||
TEST_P(CreateBufferMappedTests, MapWriteUsageSmallAsync) {
|
|
||||||
uint32_t myData = 230502;
|
|
||||||
wgpu::CreateBufferMappedResult result = CreateBufferMappedAsyncWithDataAndWait(
|
|
||||||
wgpu::BufferUsage::MapWrite | wgpu::BufferUsage::CopySrc, {myData});
|
|
||||||
UnmapBuffer(result.buffer);
|
|
||||||
EXPECT_BUFFER_U32_EQ(myData, result.buffer, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test that the simplest CreateBufferMappedAsync works for MapRead buffers.
|
|
||||||
TEST_P(CreateBufferMappedTests, MapReadUsageSmallAsync) {
|
|
||||||
uint32_t myData = 230502;
|
|
||||||
wgpu::CreateBufferMappedResult result =
|
|
||||||
CreateBufferMappedAsyncWithDataAndWait(wgpu::BufferUsage::MapRead, {myData});
|
|
||||||
UnmapBuffer(result.buffer);
|
|
||||||
|
|
||||||
const void* mappedData = MapReadAsyncAndWait(result.buffer);
|
|
||||||
ASSERT_EQ(myData, *reinterpret_cast<const uint32_t*>(mappedData));
|
|
||||||
UnmapBuffer(result.buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test that the simplest CreateBufferMappedAsync works for non-mappable buffers.
|
|
||||||
TEST_P(CreateBufferMappedTests, NonMappableUsageSmallAsync) {
|
|
||||||
uint32_t myData = 4239;
|
|
||||||
wgpu::CreateBufferMappedResult result =
|
|
||||||
CreateBufferMappedAsyncWithDataAndWait(wgpu::BufferUsage::CopySrc, {myData});
|
|
||||||
UnmapBuffer(result.buffer);
|
|
||||||
|
|
||||||
EXPECT_BUFFER_U32_EQ(myData, result.buffer, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test CreateBufferMappedAsync for a large MapWrite buffer
|
|
||||||
TEST_P(CreateBufferMappedTests, MapWriteUsageLargeAsync) {
|
|
||||||
constexpr uint64_t kDataSize = 1000 * 1000;
|
|
||||||
std::vector<uint32_t> myData;
|
|
||||||
for (uint32_t i = 0; i < kDataSize; ++i) {
|
|
||||||
myData.push_back(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
wgpu::CreateBufferMappedResult result = CreateBufferMappedAsyncWithDataAndWait(
|
|
||||||
wgpu::BufferUsage::MapWrite | wgpu::BufferUsage::CopySrc, {myData});
|
|
||||||
UnmapBuffer(result.buffer);
|
|
||||||
|
|
||||||
EXPECT_BUFFER_U32_RANGE_EQ(myData.data(), result.buffer, 0, kDataSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test CreateBufferMappedAsync for a large MapRead buffer
|
|
||||||
TEST_P(CreateBufferMappedTests, MapReadUsageLargeAsync) {
|
|
||||||
constexpr uint64_t kDataSize = 1000 * 1000;
|
|
||||||
std::vector<uint32_t> myData;
|
|
||||||
for (uint32_t i = 0; i < kDataSize; ++i) {
|
|
||||||
myData.push_back(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
wgpu::CreateBufferMappedResult result =
|
|
||||||
CreateBufferMappedAsyncWithDataAndWait(wgpu::BufferUsage::MapRead, {myData});
|
|
||||||
UnmapBuffer(result.buffer);
|
|
||||||
|
|
||||||
const void* mappedData = MapReadAsyncAndWait(result.buffer);
|
|
||||||
ASSERT_EQ(0, memcmp(mappedData, myData.data(), kDataSize * sizeof(uint32_t)));
|
|
||||||
UnmapBuffer(result.buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test CreateBufferMappedAsync for a large non-mappable buffer
|
|
||||||
TEST_P(CreateBufferMappedTests, NonMappableUsageLargeAsync) {
|
|
||||||
constexpr uint64_t kDataSize = 1000 * 1000;
|
|
||||||
std::vector<uint32_t> myData;
|
|
||||||
for (uint32_t i = 0; i < kDataSize; ++i) {
|
|
||||||
myData.push_back(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
wgpu::CreateBufferMappedResult result =
|
|
||||||
CreateBufferMappedAsyncWithDataAndWait(wgpu::BufferUsage::CopySrc, {myData});
|
|
||||||
UnmapBuffer(result.buffer);
|
|
||||||
|
|
||||||
EXPECT_BUFFER_U32_RANGE_EQ(myData.data(), result.buffer, 0, kDataSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test that mapping a buffer is valid after CreateBufferMappedAsync and Unmap
|
|
||||||
TEST_P(CreateBufferMappedTests, CreateThenMapSuccessAsync) {
|
|
||||||
static uint32_t myData = 230502;
|
|
||||||
static uint32_t myData2 = 1337;
|
|
||||||
wgpu::CreateBufferMappedResult result = CreateBufferMappedAsyncWithDataAndWait(
|
|
||||||
wgpu::BufferUsage::MapWrite | wgpu::BufferUsage::CopySrc, {myData});
|
|
||||||
UnmapBuffer(result.buffer);
|
|
||||||
|
|
||||||
EXPECT_BUFFER_U32_EQ(myData, result.buffer, 0);
|
|
||||||
|
|
||||||
bool done = false;
|
|
||||||
result.buffer.MapWriteAsync(
|
|
||||||
[](WGPUBufferMapAsyncStatus status, void* data, uint64_t, void* userdata) {
|
|
||||||
ASSERT_EQ(WGPUBufferMapAsyncStatus_Success, status);
|
|
||||||
ASSERT_NE(nullptr, data);
|
|
||||||
|
|
||||||
*static_cast<uint32_t*>(data) = myData2;
|
|
||||||
*static_cast<bool*>(userdata) = true;
|
|
||||||
},
|
|
||||||
&done);
|
|
||||||
|
|
||||||
while (!done) {
|
|
||||||
WaitABit();
|
|
||||||
}
|
|
||||||
|
|
||||||
UnmapBuffer(result.buffer);
|
|
||||||
EXPECT_BUFFER_U32_EQ(myData2, result.buffer, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test that is is invalid to map a buffer twice when using CreateBufferMappedAsync
|
|
||||||
TEST_P(CreateBufferMappedTests, CreateThenMapBeforeUnmapFailureAsync) {
|
|
||||||
uint32_t myData = 230502;
|
|
||||||
wgpu::CreateBufferMappedResult result = CreateBufferMappedAsyncWithDataAndWait(
|
|
||||||
wgpu::BufferUsage::MapWrite | wgpu::BufferUsage::CopySrc, {myData});
|
|
||||||
|
|
||||||
ASSERT_DEVICE_ERROR([&]() {
|
|
||||||
bool done = false;
|
|
||||||
result.buffer.MapWriteAsync(
|
|
||||||
[](WGPUBufferMapAsyncStatus status, void* data, uint64_t, void* userdata) {
|
|
||||||
ASSERT_EQ(WGPUBufferMapAsyncStatus_Error, status);
|
|
||||||
ASSERT_EQ(nullptr, data);
|
|
||||||
|
|
||||||
*static_cast<bool*>(userdata) = true;
|
|
||||||
},
|
|
||||||
&done);
|
|
||||||
|
|
||||||
while (!done) {
|
|
||||||
WaitABit();
|
|
||||||
}
|
|
||||||
}());
|
|
||||||
|
|
||||||
// CreateBufferMappedAsync is unaffected by the MapWrite error.
|
|
||||||
UnmapBuffer(result.buffer);
|
|
||||||
EXPECT_BUFFER_U32_EQ(myData, result.buffer, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test that creating a very large buffers fails gracefully.
|
// Test that creating a very large buffers fails gracefully.
|
||||||
TEST_P(CreateBufferMappedTests, LargeBufferFails) {
|
TEST_P(CreateBufferMappedTests, LargeBufferFails) {
|
||||||
// TODO(http://crbug.com/dawn/27): Missing support.
|
// TODO(http://crbug.com/dawn/27): Missing support.
|
||||||
|
|
|
@ -296,38 +296,6 @@ TEST_P(DeviceLostTest, CreateBufferMappedFails) {
|
||||||
ASSERT_DEVICE_ERROR(device.CreateBufferMapped(&bufferDescriptor));
|
ASSERT_DEVICE_ERROR(device.CreateBufferMapped(&bufferDescriptor));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that CreateBufferMappedAsync fails after device is lost
|
|
||||||
TEST_P(DeviceLostTest, CreateBufferMappedAsyncFails) {
|
|
||||||
wgpu::BufferDescriptor bufferDescriptor;
|
|
||||||
bufferDescriptor.size = sizeof(float);
|
|
||||||
bufferDescriptor.usage = wgpu::BufferUsage::MapWrite;
|
|
||||||
|
|
||||||
SetCallbackAndLoseForTesting();
|
|
||||||
struct ResultInfo {
|
|
||||||
wgpu::CreateBufferMappedResult result;
|
|
||||||
bool done = false;
|
|
||||||
} resultInfo;
|
|
||||||
|
|
||||||
ASSERT_DEVICE_ERROR(device.CreateBufferMappedAsync(
|
|
||||||
&bufferDescriptor,
|
|
||||||
[](WGPUBufferMapAsyncStatus status, WGPUCreateBufferMappedResult result, void* userdata) {
|
|
||||||
auto* resultInfo = static_cast<ResultInfo*>(userdata);
|
|
||||||
EXPECT_EQ(WGPUBufferMapAsyncStatus_DeviceLost, status);
|
|
||||||
EXPECT_NE(nullptr, result.data);
|
|
||||||
resultInfo->result.buffer = wgpu::Buffer::Acquire(result.buffer);
|
|
||||||
resultInfo->result.data = result.data;
|
|
||||||
resultInfo->result.dataLength = result.dataLength;
|
|
||||||
resultInfo->done = true;
|
|
||||||
},
|
|
||||||
&resultInfo));
|
|
||||||
|
|
||||||
while (!resultInfo.done) {
|
|
||||||
ASSERT_DEVICE_ERROR(WaitABit());
|
|
||||||
}
|
|
||||||
|
|
||||||
ASSERT_DEVICE_ERROR(resultInfo.result.buffer.Unmap());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test that BufferMapReadAsync fails after device is lost
|
// Test that BufferMapReadAsync fails after device is lost
|
||||||
TEST_P(DeviceLostTest, BufferMapReadAsyncFails) {
|
TEST_P(DeviceLostTest, BufferMapReadAsyncFails) {
|
||||||
wgpu::BufferDescriptor bufferDescriptor;
|
wgpu::BufferDescriptor bufferDescriptor;
|
||||||
|
|
|
@ -69,18 +69,6 @@ namespace {
|
||||||
void* userdata));
|
void* userdata));
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<StrictMock<MockBufferCreateMappedCallback>> mockCreateBufferMappedCallback;
|
|
||||||
uint32_t* lastCreateMappedPointer = nullptr;
|
|
||||||
void ToMockCreateBufferMappedCallback(WGPUBufferMapAsyncStatus status,
|
|
||||||
WGPUCreateBufferMappedResult result,
|
|
||||||
void* userdata) {
|
|
||||||
// Assume the data is uint32_t to make writing matchers easier
|
|
||||||
lastCreateMappedPointer = static_cast<uint32_t*>(result.data);
|
|
||||||
// Unpack WGPUCreateBufferMappedResult to make writing matchers easier
|
|
||||||
mockCreateBufferMappedCallback->Call(status, result.buffer, lastCreateMappedPointer,
|
|
||||||
result.dataLength, userdata);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
class WireBufferMappingTests : public WireTest {
|
class WireBufferMappingTests : public WireTest {
|
||||||
|
@ -94,8 +82,6 @@ class WireBufferMappingTests : public WireTest {
|
||||||
|
|
||||||
mockBufferMapReadCallback = std::make_unique<StrictMock<MockBufferMapReadCallback>>();
|
mockBufferMapReadCallback = std::make_unique<StrictMock<MockBufferMapReadCallback>>();
|
||||||
mockBufferMapWriteCallback = std::make_unique<StrictMock<MockBufferMapWriteCallback>>();
|
mockBufferMapWriteCallback = std::make_unique<StrictMock<MockBufferMapWriteCallback>>();
|
||||||
mockCreateBufferMappedCallback =
|
|
||||||
std::make_unique<StrictMock<MockBufferCreateMappedCallback>>();
|
|
||||||
|
|
||||||
WGPUBufferDescriptor descriptor = {};
|
WGPUBufferDescriptor descriptor = {};
|
||||||
descriptor.size = kBufferSize;
|
descriptor.size = kBufferSize;
|
||||||
|
@ -115,7 +101,6 @@ class WireBufferMappingTests : public WireTest {
|
||||||
// Delete mocks so that expectations are checked
|
// Delete mocks so that expectations are checked
|
||||||
mockBufferMapReadCallback = nullptr;
|
mockBufferMapReadCallback = nullptr;
|
||||||
mockBufferMapWriteCallback = nullptr;
|
mockBufferMapWriteCallback = nullptr;
|
||||||
mockCreateBufferMappedCallback = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlushServer() {
|
void FlushServer() {
|
||||||
|
@ -123,7 +108,6 @@ class WireBufferMappingTests : public WireTest {
|
||||||
|
|
||||||
Mock::VerifyAndClearExpectations(&mockBufferMapReadCallback);
|
Mock::VerifyAndClearExpectations(&mockBufferMapReadCallback);
|
||||||
Mock::VerifyAndClearExpectations(&mockBufferMapWriteCallback);
|
Mock::VerifyAndClearExpectations(&mockBufferMapWriteCallback);
|
||||||
Mock::VerifyAndClearExpectations(&mockCreateBufferMappedCallback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -629,187 +613,3 @@ TEST_F(WireBufferMappingTests, CreateBufferMappedThenMapFailure) {
|
||||||
FlushClient();
|
FlushClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test successful CreateBufferMappedAsync
|
|
||||||
TEST_F(WireBufferMappingTests, CreateBufferMappedAsyncSuccess) {
|
|
||||||
WGPUBufferDescriptor descriptor = {};
|
|
||||||
descriptor.size = kBufferSize;
|
|
||||||
|
|
||||||
WGPUCreateBufferMappedResult apiResult;
|
|
||||||
uint32_t serverBufferContent = 31337;
|
|
||||||
apiResult.buffer = apiBuffer;
|
|
||||||
apiResult.data = reinterpret_cast<uint8_t*>(&serverBufferContent);
|
|
||||||
apiResult.dataLength = kBufferSize;
|
|
||||||
|
|
||||||
uint32_t updatedContent = 4242;
|
|
||||||
uint32_t zero = 0;
|
|
||||||
|
|
||||||
wgpuDeviceCreateBufferMappedAsync(device, &descriptor, ToMockCreateBufferMappedCallback,
|
|
||||||
nullptr);
|
|
||||||
|
|
||||||
EXPECT_CALL(api, DeviceCreateBufferMapped(apiDevice, _))
|
|
||||||
.WillOnce(Return(apiResult))
|
|
||||||
.RetiresOnSaturation();
|
|
||||||
|
|
||||||
FlushClient();
|
|
||||||
|
|
||||||
WGPUBuffer buffer;
|
|
||||||
// The callback always gets a buffer full of zeroes.
|
|
||||||
EXPECT_CALL(*mockCreateBufferMappedCallback,
|
|
||||||
Call(WGPUBufferMapAsyncStatus_Success, _, Pointee(Eq(zero)), kBufferSize, _))
|
|
||||||
.WillOnce(::testing::SaveArg<1>(&buffer));
|
|
||||||
|
|
||||||
FlushServer();
|
|
||||||
|
|
||||||
// Write something to the mapped pointer
|
|
||||||
*lastCreateMappedPointer = updatedContent;
|
|
||||||
|
|
||||||
wgpuBufferUnmap(buffer);
|
|
||||||
EXPECT_CALL(api, BufferUnmap(apiBuffer)).Times(1);
|
|
||||||
|
|
||||||
FlushClient();
|
|
||||||
|
|
||||||
// After the buffer is unmapped, the content of the buffer is updated on the server
|
|
||||||
ASSERT_EQ(serverBufferContent, updatedContent);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test CreateBufferMappedAsync with map error
|
|
||||||
TEST_F(WireBufferMappingTests, CreateBufferMappedAsyncMapError) {
|
|
||||||
WGPUBufferDescriptor descriptor = {};
|
|
||||||
|
|
||||||
WGPUCreateBufferMappedResult apiResult;
|
|
||||||
apiResult.buffer = apiBuffer;
|
|
||||||
apiResult.data = nullptr; // error mapping
|
|
||||||
apiResult.dataLength = kBufferSize;
|
|
||||||
|
|
||||||
wgpuDeviceCreateBufferMappedAsync(device, &descriptor, ToMockCreateBufferMappedCallback,
|
|
||||||
nullptr);
|
|
||||||
|
|
||||||
EXPECT_CALL(api, DeviceCreateBufferMapped(apiDevice, _))
|
|
||||||
.WillOnce(Return(apiResult))
|
|
||||||
.RetiresOnSaturation();
|
|
||||||
|
|
||||||
FlushClient();
|
|
||||||
|
|
||||||
WGPUBuffer buffer;
|
|
||||||
EXPECT_CALL(*mockCreateBufferMappedCallback,
|
|
||||||
Call(WGPUBufferMapAsyncStatus_Error, _, nullptr, 0, _))
|
|
||||||
.WillOnce(::testing::SaveArg<1>(&buffer));
|
|
||||||
|
|
||||||
FlushServer();
|
|
||||||
|
|
||||||
wgpuBufferUnmap(buffer);
|
|
||||||
EXPECT_CALL(api, BufferUnmap(apiBuffer)).Times(1);
|
|
||||||
|
|
||||||
FlushClient();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test that the CreateBufferMappedCallback isn't fired twice when unmap() is called inside the
|
|
||||||
// callback
|
|
||||||
TEST_F(WireBufferMappingTests, UnmapInsideCreateBufferMappedAsyncCallback) {
|
|
||||||
WGPUBufferDescriptor descriptor = {};
|
|
||||||
descriptor.size = kBufferSize;
|
|
||||||
|
|
||||||
WGPUCreateBufferMappedResult apiResult;
|
|
||||||
uint32_t serverBufferContent = 31337;
|
|
||||||
apiResult.buffer = apiBuffer;
|
|
||||||
apiResult.data = reinterpret_cast<uint8_t*>(&serverBufferContent);
|
|
||||||
apiResult.dataLength = kBufferSize;
|
|
||||||
|
|
||||||
uint32_t zero = 0;
|
|
||||||
|
|
||||||
wgpuDeviceCreateBufferMappedAsync(device, &descriptor, ToMockCreateBufferMappedCallback,
|
|
||||||
nullptr);
|
|
||||||
|
|
||||||
EXPECT_CALL(api, DeviceCreateBufferMapped(apiDevice, _))
|
|
||||||
.WillOnce(Return(apiResult))
|
|
||||||
.RetiresOnSaturation();
|
|
||||||
|
|
||||||
FlushClient();
|
|
||||||
|
|
||||||
WGPUBuffer buffer;
|
|
||||||
// The callback always gets a buffer full of zeroes.
|
|
||||||
EXPECT_CALL(*mockCreateBufferMappedCallback,
|
|
||||||
Call(WGPUBufferMapAsyncStatus_Success, _, Pointee(Eq(zero)), kBufferSize, _))
|
|
||||||
.WillOnce(DoAll(::testing::SaveArg<1>(&buffer),
|
|
||||||
InvokeWithoutArgs([&]() { wgpuBufferUnmap(buffer); })));
|
|
||||||
|
|
||||||
FlushServer();
|
|
||||||
|
|
||||||
EXPECT_CALL(api, BufferUnmap(apiBuffer)).Times(1);
|
|
||||||
|
|
||||||
FlushClient();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test that the CreateBufferMappedCallback isn't fired twice when the buffer is deleted inside
|
|
||||||
// the callback
|
|
||||||
TEST_F(WireBufferMappingTests, ReleaseInsideCreateBufferMappedAsyncCallback) {
|
|
||||||
WGPUBufferDescriptor descriptor = {};
|
|
||||||
descriptor.size = kBufferSize;
|
|
||||||
|
|
||||||
WGPUCreateBufferMappedResult apiResult;
|
|
||||||
uint32_t serverBufferContent = 31337;
|
|
||||||
apiResult.buffer = apiBuffer;
|
|
||||||
apiResult.data = reinterpret_cast<uint8_t*>(&serverBufferContent);
|
|
||||||
apiResult.dataLength = kBufferSize;
|
|
||||||
|
|
||||||
uint32_t zero = 0;
|
|
||||||
|
|
||||||
wgpuDeviceCreateBufferMappedAsync(device, &descriptor, ToMockCreateBufferMappedCallback,
|
|
||||||
nullptr);
|
|
||||||
|
|
||||||
EXPECT_CALL(api, DeviceCreateBufferMapped(apiDevice, _))
|
|
||||||
.WillOnce(Return(apiResult))
|
|
||||||
.RetiresOnSaturation();
|
|
||||||
|
|
||||||
FlushClient();
|
|
||||||
|
|
||||||
WGPUBuffer buffer;
|
|
||||||
// The callback always gets a buffer full of zeroes.
|
|
||||||
EXPECT_CALL(*mockCreateBufferMappedCallback,
|
|
||||||
Call(WGPUBufferMapAsyncStatus_Success, _, Pointee(Eq(zero)), kBufferSize, _))
|
|
||||||
.WillOnce(DoAll(::testing::SaveArg<1>(&buffer),
|
|
||||||
InvokeWithoutArgs([&]() { wgpuBufferRelease(buffer); })));
|
|
||||||
|
|
||||||
FlushServer();
|
|
||||||
|
|
||||||
EXPECT_CALL(api, BufferRelease(apiBuffer));
|
|
||||||
|
|
||||||
FlushClient();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test that the CreateBufferMappedCallback isn't fired twice when the buffer is destroyed inside
|
|
||||||
// the callback
|
|
||||||
TEST_F(WireBufferMappingTests, DestroyInsideCreateBufferMappedAsyncCallback) {
|
|
||||||
WGPUBufferDescriptor descriptor = {};
|
|
||||||
descriptor.size = kBufferSize;
|
|
||||||
|
|
||||||
WGPUCreateBufferMappedResult apiResult;
|
|
||||||
uint32_t serverBufferContent = 31337;
|
|
||||||
apiResult.buffer = apiBuffer;
|
|
||||||
apiResult.data = reinterpret_cast<uint8_t*>(&serverBufferContent);
|
|
||||||
apiResult.dataLength = kBufferSize;
|
|
||||||
|
|
||||||
uint32_t zero = 0;
|
|
||||||
|
|
||||||
wgpuDeviceCreateBufferMappedAsync(device, &descriptor, ToMockCreateBufferMappedCallback,
|
|
||||||
nullptr);
|
|
||||||
|
|
||||||
EXPECT_CALL(api, DeviceCreateBufferMapped(apiDevice, _))
|
|
||||||
.WillOnce(Return(apiResult))
|
|
||||||
.RetiresOnSaturation();
|
|
||||||
|
|
||||||
FlushClient();
|
|
||||||
|
|
||||||
WGPUBuffer buffer;
|
|
||||||
// The callback always gets a buffer full of zeroes.
|
|
||||||
EXPECT_CALL(*mockCreateBufferMappedCallback,
|
|
||||||
Call(WGPUBufferMapAsyncStatus_Success, _, Pointee(Eq(zero)), kBufferSize, _))
|
|
||||||
.WillOnce(DoAll(::testing::SaveArg<1>(&buffer),
|
|
||||||
InvokeWithoutArgs([&]() { wgpuBufferDestroy(buffer); })));
|
|
||||||
|
|
||||||
FlushServer();
|
|
||||||
|
|
||||||
EXPECT_CALL(api, BufferDestroy(apiBuffer));
|
|
||||||
|
|
||||||
FlushClient();
|
|
||||||
}
|
|
||||||
|
|
|
@ -70,16 +70,6 @@ namespace {
|
||||||
void* userdata));
|
void* userdata));
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<StrictMock<MockBufferCreateMappedCallback>> mockCreateBufferMappedCallback;
|
|
||||||
void ToMockCreateBufferMappedCallback(WGPUBufferMapAsyncStatus status,
|
|
||||||
WGPUCreateBufferMappedResult result,
|
|
||||||
void* userdata) {
|
|
||||||
// Assume the data is uint32_t to make writing matchers easier
|
|
||||||
mockCreateBufferMappedCallback->Call(status, result.buffer,
|
|
||||||
static_cast<uint32_t*>(result.data), result.dataLength,
|
|
||||||
userdata);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
// WireMemoryTransferServiceTests test the MemoryTransferService with buffer mapping.
|
// WireMemoryTransferServiceTests test the MemoryTransferService with buffer mapping.
|
||||||
|
@ -113,8 +103,6 @@ class WireMemoryTransferServiceTests : public WireTest {
|
||||||
|
|
||||||
mockBufferMapReadCallback = std::make_unique<StrictMock<MockBufferMapReadCallback>>();
|
mockBufferMapReadCallback = std::make_unique<StrictMock<MockBufferMapReadCallback>>();
|
||||||
mockBufferMapWriteCallback = std::make_unique<StrictMock<MockBufferMapWriteCallback>>();
|
mockBufferMapWriteCallback = std::make_unique<StrictMock<MockBufferMapWriteCallback>>();
|
||||||
mockCreateBufferMappedCallback =
|
|
||||||
std::make_unique<StrictMock<MockBufferCreateMappedCallback>>();
|
|
||||||
|
|
||||||
// TODO(enga): Make this thread-safe.
|
// TODO(enga): Make this thread-safe.
|
||||||
mBufferContent++;
|
mBufferContent++;
|
||||||
|
@ -131,7 +119,6 @@ class WireMemoryTransferServiceTests : public WireTest {
|
||||||
// Delete mocks so that expectations are checked
|
// Delete mocks so that expectations are checked
|
||||||
mockBufferMapReadCallback = nullptr;
|
mockBufferMapReadCallback = nullptr;
|
||||||
mockBufferMapWriteCallback = nullptr;
|
mockBufferMapWriteCallback = nullptr;
|
||||||
mockCreateBufferMappedCallback = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlushClient(bool success = true) {
|
void FlushClient(bool success = true) {
|
||||||
|
@ -144,7 +131,6 @@ class WireMemoryTransferServiceTests : public WireTest {
|
||||||
|
|
||||||
Mock::VerifyAndClearExpectations(&mockBufferMapReadCallback);
|
Mock::VerifyAndClearExpectations(&mockBufferMapReadCallback);
|
||||||
Mock::VerifyAndClearExpectations(&mockBufferMapWriteCallback);
|
Mock::VerifyAndClearExpectations(&mockBufferMapWriteCallback);
|
||||||
Mock::VerifyAndClearExpectations(&mockCreateBufferMappedCallback);
|
|
||||||
Mock::VerifyAndClearExpectations(&clientMemoryTransferService);
|
Mock::VerifyAndClearExpectations(&clientMemoryTransferService);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,27 +174,6 @@ class WireMemoryTransferServiceTests : public WireTest {
|
||||||
return std::make_pair(apiResult, result);
|
return std::make_pair(apiResult, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
WGPUCreateBufferMappedResult CreateBufferMappedAsync() {
|
|
||||||
WGPUBufferDescriptor descriptor = {};
|
|
||||||
descriptor.size = sizeof(mBufferContent);
|
|
||||||
|
|
||||||
wgpuDeviceCreateBufferMappedAsync(device, &descriptor, ToMockCreateBufferMappedCallback,
|
|
||||||
nullptr);
|
|
||||||
|
|
||||||
WGPUBuffer apiBuffer = api.GetNewBuffer();
|
|
||||||
|
|
||||||
WGPUCreateBufferMappedResult apiResult;
|
|
||||||
apiResult.buffer = apiBuffer;
|
|
||||||
apiResult.data = reinterpret_cast<uint8_t*>(&mMappedBufferContent);
|
|
||||||
apiResult.dataLength = sizeof(mMappedBufferContent);
|
|
||||||
|
|
||||||
EXPECT_CALL(api, DeviceCreateBufferMapped(apiDevice, _))
|
|
||||||
.WillOnce(Return(apiResult))
|
|
||||||
.RetiresOnSaturation();
|
|
||||||
|
|
||||||
return apiResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
ClientReadHandle* ExpectReadHandleCreation() {
|
ClientReadHandle* ExpectReadHandleCreation() {
|
||||||
// Create the handle first so we can use it in later expectations.
|
// Create the handle first so we can use it in later expectations.
|
||||||
ClientReadHandle* handle = clientMemoryTransferService.NewReadHandle();
|
ClientReadHandle* handle = clientMemoryTransferService.NewReadHandle();
|
||||||
|
@ -934,168 +899,6 @@ TEST_F(WireMemoryTransferServiceTests, BufferMapWriteDestroyBeforeUnmap) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test successful CreateBufferMappedAsync.
|
|
||||||
TEST_F(WireMemoryTransferServiceTests, CreateBufferMappedAsyncSuccess) {
|
|
||||||
// The client should create and serialize a WriteHandle on createBufferMappedAsync
|
|
||||||
ClientWriteHandle* clientHandle = ExpectWriteHandleCreation();
|
|
||||||
ExpectWriteHandleSerialization(clientHandle);
|
|
||||||
|
|
||||||
WGPUCreateBufferMappedResult apiResult = CreateBufferMappedAsync();
|
|
||||||
|
|
||||||
// The server should then deserialize the WriteHandle from the client.
|
|
||||||
ServerWriteHandle* serverHandle = ExpectServerWriteHandleDeserialization();
|
|
||||||
|
|
||||||
FlushClient();
|
|
||||||
|
|
||||||
// The client receives a success callback. Save the buffer argument so we can call Unmap.
|
|
||||||
WGPUBuffer buffer;
|
|
||||||
EXPECT_CALL(*mockCreateBufferMappedCallback,
|
|
||||||
Call(WGPUBufferMapAsyncStatus_Success, _, &mMappedBufferContent,
|
|
||||||
sizeof(mMappedBufferContent), _))
|
|
||||||
|
|
||||||
.WillOnce(SaveArg<1>(&buffer));
|
|
||||||
|
|
||||||
// Since the mapping succeeds, the client opens the WriteHandle.
|
|
||||||
ExpectClientWriteHandleOpen(clientHandle, &mMappedBufferContent);
|
|
||||||
|
|
||||||
FlushServer();
|
|
||||||
|
|
||||||
// The client writes to the handle contents.
|
|
||||||
mMappedBufferContent = mUpdatedBufferContent;
|
|
||||||
|
|
||||||
// The client will then flush and destroy the handle on Unmap()
|
|
||||||
ExpectClientWriteHandleSerializeFlush(clientHandle);
|
|
||||||
EXPECT_CALL(clientMemoryTransferService, OnWriteHandleDestroy(clientHandle)).Times(1);
|
|
||||||
|
|
||||||
wgpuBufferUnmap(buffer);
|
|
||||||
|
|
||||||
// The server deserializes the Flush message.
|
|
||||||
ExpectServerWriteHandleDeserializeFlush(serverHandle, mUpdatedBufferContent);
|
|
||||||
|
|
||||||
// After the handle is updated it can be destroyed.
|
|
||||||
EXPECT_CALL(serverMemoryTransferService, OnWriteHandleDestroy(serverHandle)).Times(1);
|
|
||||||
EXPECT_CALL(api, BufferUnmap(apiResult.buffer)).Times(1);
|
|
||||||
|
|
||||||
FlushClient();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test CreateBufferMappedAsync WriteHandle creation failure.
|
|
||||||
TEST_F(WireMemoryTransferServiceTests, CreateBufferMappedAsyncWriteHandleCreationFailure) {
|
|
||||||
// Mock a WriteHandle creation failure
|
|
||||||
MockWriteHandleCreationFailure();
|
|
||||||
|
|
||||||
WGPUBufferDescriptor descriptor = {};
|
|
||||||
descriptor.size = sizeof(mBufferContent);
|
|
||||||
|
|
||||||
// Failed creation of a WriteHandle is a fatal failure. The client synchronously receives
|
|
||||||
// a DEVICE_LOST callback.
|
|
||||||
EXPECT_CALL(*mockCreateBufferMappedCallback,
|
|
||||||
Call(WGPUBufferMapAsyncStatus_DeviceLost, _, nullptr, 0, _))
|
|
||||||
.Times(1);
|
|
||||||
|
|
||||||
wgpuDeviceCreateBufferMappedAsync(device, &descriptor, ToMockCreateBufferMappedCallback,
|
|
||||||
nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test CreateBufferMappedAsync DeserializeWriteHandle failure.
|
|
||||||
TEST_F(WireMemoryTransferServiceTests, CreateBufferMappedAsyncDeserializeWriteHandleFailure) {
|
|
||||||
// The client should create and serialize a WriteHandle on createBufferMappedAsync
|
|
||||||
ClientWriteHandle* clientHandle = ExpectWriteHandleCreation();
|
|
||||||
ExpectWriteHandleSerialization(clientHandle);
|
|
||||||
|
|
||||||
WGPUCreateBufferMappedResult apiResult = CreateBufferMappedAsync();
|
|
||||||
DAWN_UNUSED(apiResult);
|
|
||||||
|
|
||||||
// The server should then deserialize the WriteHandle from the client.
|
|
||||||
// Mock a deserialization failure.
|
|
||||||
MockServerWriteHandleDeserializeFailure();
|
|
||||||
|
|
||||||
FlushClient(false);
|
|
||||||
|
|
||||||
// The server hit a fatal failure and never returned the callback. It is called when the
|
|
||||||
// wire is destructed.
|
|
||||||
EXPECT_CALL(*mockCreateBufferMappedCallback,
|
|
||||||
Call(WGPUBufferMapAsyncStatus_Unknown, _, nullptr, 0, _))
|
|
||||||
.Times(1);
|
|
||||||
|
|
||||||
EXPECT_CALL(clientMemoryTransferService, OnWriteHandleDestroy(clientHandle)).Times(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test CreateBufferMappedAsync handle Open failure.
|
|
||||||
TEST_F(WireMemoryTransferServiceTests, CreateBufferMappedAsyncHandleOpenFailure) {
|
|
||||||
// The client should create and serialize a WriteHandle on createBufferMappedAsync
|
|
||||||
ClientWriteHandle* clientHandle = ExpectWriteHandleCreation();
|
|
||||||
ExpectWriteHandleSerialization(clientHandle);
|
|
||||||
|
|
||||||
WGPUCreateBufferMappedResult apiResult = CreateBufferMappedAsync();
|
|
||||||
DAWN_UNUSED(apiResult);
|
|
||||||
|
|
||||||
// The server should then deserialize the WriteHandle from the client.
|
|
||||||
ServerWriteHandle* serverHandle = ExpectServerWriteHandleDeserialization();
|
|
||||||
|
|
||||||
FlushClient();
|
|
||||||
|
|
||||||
// Since the mapping succeeds, the client opens the WriteHandle.
|
|
||||||
MockClientWriteHandleOpenFailure(clientHandle);
|
|
||||||
|
|
||||||
// Failing to open a handle is a fatal failure. The client receives a DEVICE_LOST callback.
|
|
||||||
EXPECT_CALL(*mockCreateBufferMappedCallback,
|
|
||||||
Call(WGPUBufferMapAsyncStatus_DeviceLost, _, nullptr, 0, _))
|
|
||||||
.Times(1);
|
|
||||||
|
|
||||||
// Since opening the handle fails, it is destroyed immediately.
|
|
||||||
EXPECT_CALL(clientMemoryTransferService, OnWriteHandleDestroy(clientHandle)).Times(1);
|
|
||||||
|
|
||||||
FlushServer(false);
|
|
||||||
|
|
||||||
EXPECT_CALL(serverMemoryTransferService, OnWriteHandleDestroy(serverHandle)).Times(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test CreateBufferMappedAsync DeserializeFlush failure.
|
|
||||||
TEST_F(WireMemoryTransferServiceTests, CreateBufferMappedAsyncDeserializeFlushFailure) {
|
|
||||||
// The client should create and serialize a WriteHandle on createBufferMappedAsync
|
|
||||||
ClientWriteHandle* clientHandle = ExpectWriteHandleCreation();
|
|
||||||
ExpectWriteHandleSerialization(clientHandle);
|
|
||||||
|
|
||||||
WGPUCreateBufferMappedResult apiResult = CreateBufferMappedAsync();
|
|
||||||
DAWN_UNUSED(apiResult);
|
|
||||||
|
|
||||||
// The server should then deserialize the WriteHandle from the client.
|
|
||||||
ServerWriteHandle* serverHandle = ExpectServerWriteHandleDeserialization();
|
|
||||||
|
|
||||||
FlushClient();
|
|
||||||
|
|
||||||
// The client receives a success callback. Save the buffer argument so we can call Unmap.
|
|
||||||
WGPUBuffer buffer;
|
|
||||||
EXPECT_CALL(*mockCreateBufferMappedCallback,
|
|
||||||
Call(WGPUBufferMapAsyncStatus_Success, _, &mMappedBufferContent,
|
|
||||||
sizeof(mMappedBufferContent), _))
|
|
||||||
|
|
||||||
.WillOnce(SaveArg<1>(&buffer));
|
|
||||||
|
|
||||||
// Since the mapping succeeds, the client opens the WriteHandle.
|
|
||||||
ExpectClientWriteHandleOpen(clientHandle, &mMappedBufferContent);
|
|
||||||
|
|
||||||
FlushServer();
|
|
||||||
|
|
||||||
// The client writes to the handle contents.
|
|
||||||
mMappedBufferContent = mUpdatedBufferContent;
|
|
||||||
|
|
||||||
// The client will then flush and destroy the handle on Unmap()
|
|
||||||
ExpectClientWriteHandleSerializeFlush(clientHandle);
|
|
||||||
EXPECT_CALL(clientMemoryTransferService, OnWriteHandleDestroy(clientHandle)).Times(1);
|
|
||||||
|
|
||||||
wgpuBufferUnmap(buffer);
|
|
||||||
|
|
||||||
// The server deserializes the Flush message.
|
|
||||||
// Mock a deserialization failure.
|
|
||||||
MockServerWriteHandleDeserializeFlushFailure(serverHandle);
|
|
||||||
|
|
||||||
FlushClient(false);
|
|
||||||
|
|
||||||
EXPECT_CALL(serverMemoryTransferService, OnWriteHandleDestroy(serverHandle)).Times(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test successful CreateBufferMapped.
|
// Test successful CreateBufferMapped.
|
||||||
TEST_F(WireMemoryTransferServiceTests, CreateBufferMappedSuccess) {
|
TEST_F(WireMemoryTransferServiceTests, CreateBufferMappedSuccess) {
|
||||||
// The client should create and serialize a WriteHandle on createBufferMapped.
|
// The client should create and serialize a WriteHandle on createBufferMapped.
|
||||||
|
|
Loading…
Reference in New Issue