blob: b19cc504b5797001d1c32702221fced8d0578701 [file] [log] [blame]
// Copyright 2019 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_wire/client/ApiObjects.h"
#include "dawn_wire/client/ApiProcs_autogen.h"
#include "dawn_wire/client/Client.h"
namespace dawn_wire { namespace client {
void ClientBufferMapReadAsync(dawnBuffer cBuffer,
dawnBufferMapReadCallback callback,
dawnCallbackUserdata userdata) {
Buffer* buffer = reinterpret_cast<Buffer*>(cBuffer);
uint32_t serial = buffer->requestSerial++;
ASSERT(buffer->requests.find(serial) == buffer->requests.end());
Buffer::MapRequestData request;
request.readCallback = callback;
request.userdata = userdata;
request.isWrite = false;
buffer->requests[serial] = request;
BufferMapAsyncCmd cmd;
cmd.bufferId = buffer->id;
cmd.requestSerial = serial;
cmd.isWrite = false;
size_t requiredSize = cmd.GetRequiredSize();
char* allocatedBuffer =
static_cast<char*>(buffer->device->GetClient()->GetCmdSpace(requiredSize));
cmd.Serialize(allocatedBuffer);
}
void ClientBufferMapWriteAsync(dawnBuffer cBuffer,
dawnBufferMapWriteCallback callback,
dawnCallbackUserdata userdata) {
Buffer* buffer = reinterpret_cast<Buffer*>(cBuffer);
uint32_t serial = buffer->requestSerial++;
ASSERT(buffer->requests.find(serial) == buffer->requests.end());
Buffer::MapRequestData request;
request.writeCallback = callback;
request.userdata = userdata;
request.isWrite = true;
buffer->requests[serial] = request;
BufferMapAsyncCmd cmd;
cmd.bufferId = buffer->id;
cmd.requestSerial = serial;
cmd.isWrite = true;
size_t requiredSize = cmd.GetRequiredSize();
char* allocatedBuffer =
static_cast<char*>(buffer->device->GetClient()->GetCmdSpace(requiredSize));
cmd.Serialize(allocatedBuffer);
}
uint64_t ClientFenceGetCompletedValue(dawnFence cSelf) {
auto fence = reinterpret_cast<Fence*>(cSelf);
return fence->completedValue;
}
void ClientFenceOnCompletion(dawnFence cFence,
uint64_t value,
dawnFenceOnCompletionCallback callback,
dawnCallbackUserdata userdata) {
Fence* fence = reinterpret_cast<Fence*>(cFence);
if (value > fence->signaledValue) {
fence->device->HandleError("Value greater than fence signaled value");
callback(DAWN_FENCE_COMPLETION_STATUS_ERROR, userdata);
return;
}
if (value <= fence->completedValue) {
callback(DAWN_FENCE_COMPLETION_STATUS_SUCCESS, userdata);
return;
}
Fence::OnCompletionData request;
request.completionCallback = callback;
request.userdata = userdata;
fence->requests.Enqueue(std::move(request), value);
}
void ClientBufferUnmap(dawnBuffer cBuffer) {
Buffer* buffer = reinterpret_cast<Buffer*>(cBuffer);
// Invalidate the local pointer, and cancel all other in-flight requests that would
// turn into errors anyway (you can't double map). This prevents race when the following
// happens, where the application code would have unmapped a buffer but still receive a
// callback:
// - Client -> Server: MapRequest1, Unmap, MapRequest2
// - Server -> Client: Result of MapRequest1
// - Unmap locally on the client
// - Server -> Client: Result of MapRequest2
if (buffer->mappedData) {
// If the buffer was mapped for writing, send the update to the data to the server
if (buffer->isWriteMapped) {
BufferUpdateMappedDataCmd cmd;
cmd.bufferId = buffer->id;
cmd.dataLength = static_cast<uint32_t>(buffer->mappedDataSize);
cmd.data = static_cast<const uint8_t*>(buffer->mappedData);
size_t requiredSize = cmd.GetRequiredSize();
char* allocatedBuffer =
static_cast<char*>(buffer->device->GetClient()->GetCmdSpace(requiredSize));
cmd.Serialize(allocatedBuffer);
}
free(buffer->mappedData);
buffer->mappedData = nullptr;
}
buffer->ClearMapRequests(DAWN_BUFFER_MAP_ASYNC_STATUS_UNKNOWN);
BufferUnmapCmd cmd;
cmd.self = cBuffer;
size_t requiredSize = cmd.GetRequiredSize();
char* allocatedBuffer =
static_cast<char*>(buffer->device->GetClient()->GetCmdSpace(requiredSize));
cmd.Serialize(allocatedBuffer, *buffer->device->GetClient());
}
dawnFence ClientDeviceCreateFence(dawnDevice cSelf, dawnFenceDescriptor const* descriptor) {
Device* device = reinterpret_cast<Device*>(cSelf);
DeviceCreateFenceCmd cmd;
cmd.self = cSelf;
auto* allocation = device->GetClient()->FenceAllocator().New(device);
cmd.result = ObjectHandle{allocation->object->id, allocation->serial};
cmd.descriptor = descriptor;
size_t requiredSize = cmd.GetRequiredSize();
char* allocatedBuffer = static_cast<char*>(device->GetClient()->GetCmdSpace(requiredSize));
cmd.Serialize(allocatedBuffer, *device->GetClient());
dawnFence cFence = reinterpret_cast<dawnFence>(allocation->object.get());
Fence* fence = reinterpret_cast<Fence*>(cFence);
fence->signaledValue = descriptor->initialValue;
fence->completedValue = descriptor->initialValue;
return cFence;
}
void ClientQueueSignal(dawnQueue cQueue, dawnFence cFence, uint64_t signalValue) {
Fence* fence = reinterpret_cast<Fence*>(cFence);
if (signalValue <= fence->signaledValue) {
fence->device->HandleError("Fence value less than or equal to signaled value");
return;
}
fence->signaledValue = signalValue;
QueueSignalCmd cmd;
cmd.self = cQueue;
cmd.fence = cFence;
cmd.signalValue = signalValue;
size_t requiredSize = cmd.GetRequiredSize();
char* allocatedBuffer =
static_cast<char*>(fence->device->GetClient()->GetCmdSpace(requiredSize));
cmd.Serialize(allocatedBuffer, *fence->device->GetClient());
}
void ClientDeviceReference(dawnDevice) {
}
void ClientDeviceRelease(dawnDevice) {
}
void ClientDeviceSetErrorCallback(dawnDevice cSelf,
dawnDeviceErrorCallback callback,
dawnCallbackUserdata userdata) {
Device* device = reinterpret_cast<Device*>(cSelf);
device->SetErrorCallback(callback, userdata);
}
}} // namespace dawn_wire::client