dawn_wire/client: Encapsulate all queue/fence-related logic
This CL only moves code, renames client::Fence members, and introduces
client::Queue. Additional fence methods are added for the interaction
with the queue. There are no functional changes.
With this ApiProcs.cpp is almost passthrough and will be removed in a
follow-up CL.
Bug: dawn:445
Change-Id: I65544ef76b54614452cf7c74a948a96cb35a4cfe
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/24061
Reviewed-by: Austin Eng <enga@chromium.org>
Reviewed-by: Stephen White <senorblanco@chromium.org>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
diff --git a/dawn_wire.json b/dawn_wire.json
index f3c1c8c..54d8c94 100644
--- a/dawn_wire.json
+++ b/dawn_wire.json
@@ -119,7 +119,8 @@
"client_special_objects": [
"Buffer",
"Device",
- "Fence"
+ "Fence",
+ "Queue"
],
"server_custom_pre_handler_commands": [
"BufferDestroy",
diff --git a/src/dawn_wire/BUILD.gn b/src/dawn_wire/BUILD.gn
index 5d1b2d7..aa8b0c0 100644
--- a/src/dawn_wire/BUILD.gn
+++ b/src/dawn_wire/BUILD.gn
@@ -20,9 +20,7 @@
# Public dawn_wire headers so they can be publically visible for
# dependencies of dawn_wire
source_set("dawn_wire_headers") {
- public_deps = [
- "${dawn_root}/src/dawn:dawn_headers",
- ]
+ public_deps = [ "${dawn_root}/src/dawn:dawn_headers" ]
all_dependent_configs = [ "${dawn_root}/src/common:dawn_public_include_dirs" ]
sources = [
"${dawn_root}/src/include/dawn_wire/Wire.h",
@@ -78,6 +76,8 @@
"client/Fence.cpp",
"client/Fence.h",
"client/ObjectAllocator.h",
+ "client/Queue.cpp",
+ "client/Queue.h",
"server/ObjectStorage.h",
"server/Server.cpp",
"server/Server.h",
@@ -89,7 +89,5 @@
]
# Make headers publicly visible
- public_deps = [
- ":dawn_wire_headers",
- ]
+ public_deps = [ ":dawn_wire_headers" ]
}
diff --git a/src/dawn_wire/CMakeLists.txt b/src/dawn_wire/CMakeLists.txt
index 8ec7bff..579d46a 100644
--- a/src/dawn_wire/CMakeLists.txt
+++ b/src/dawn_wire/CMakeLists.txt
@@ -42,6 +42,8 @@
"client/Fence.cpp"
"client/Fence.h"
"client/ObjectAllocator.h"
+ "client/Queue.cpp"
+ "client/Queue.h"
"server/ObjectStorage.h"
"server/Server.cpp"
"server/Server.h"
diff --git a/src/dawn_wire/client/ApiObjects.h b/src/dawn_wire/client/ApiObjects.h
index b74eefe..f842d53 100644
--- a/src/dawn_wire/client/ApiObjects.h
+++ b/src/dawn_wire/client/ApiObjects.h
@@ -20,6 +20,7 @@
#include "dawn_wire/client/Buffer.h"
#include "dawn_wire/client/Device.h"
#include "dawn_wire/client/Fence.h"
+#include "dawn_wire/client/Queue.h"
#include "dawn_wire/client/ApiObjects_autogen.h"
diff --git a/src/dawn_wire/client/ApiProcs.cpp b/src/dawn_wire/client/ApiProcs.cpp
index 0475284..db4365b 100644
--- a/src/dawn_wire/client/ApiProcs.cpp
+++ b/src/dawn_wire/client/ApiProcs.cpp
@@ -86,8 +86,8 @@
}
uint64_t ClientHandwrittenFenceGetCompletedValue(WGPUFence cSelf) {
- auto fence = reinterpret_cast<Fence*>(cSelf);
- return fence->completedValue;
+ Fence* fence = reinterpret_cast<Fence*>(cSelf);
+ return fence->GetCompletedValue();
}
void ClientHandwrittenFenceOnCompletion(WGPUFence cFence,
@@ -95,72 +95,18 @@
WGPUFenceOnCompletionCallback callback,
void* userdata) {
Fence* fence = reinterpret_cast<Fence*>(cFence);
- if (value > fence->signaledValue) {
- ClientDeviceInjectError(reinterpret_cast<WGPUDevice>(fence->device),
- WGPUErrorType_Validation,
- "Value greater than fence signaled value");
- callback(WGPUFenceCompletionStatus_Error, userdata);
- return;
- }
-
- if (value <= fence->completedValue) {
- callback(WGPUFenceCompletionStatus_Success, userdata);
- return;
- }
-
- Fence::OnCompletionData request;
- request.completionCallback = callback;
- request.userdata = userdata;
- fence->requests.Enqueue(std::move(request), value);
+ fence->OnCompletion(value, callback, userdata);
}
WGPUFence ClientHandwrittenQueueCreateFence(WGPUQueue cSelf,
WGPUFenceDescriptor const* descriptor) {
Queue* queue = reinterpret_cast<Queue*>(cSelf);
- Device* device = queue->device;
-
- QueueCreateFenceCmd cmd;
- cmd.self = cSelf;
- auto* allocation = device->GetClient()->FenceAllocator().New(device);
- cmd.result = ObjectHandle{allocation->object->id, allocation->generation};
- cmd.descriptor = descriptor;
-
- device->GetClient()->SerializeCommand(cmd);
-
- WGPUFence cFence = reinterpret_cast<WGPUFence>(allocation->object.get());
-
- Fence* fence = reinterpret_cast<Fence*>(cFence);
- fence->queue = queue;
-
- uint64_t initialValue = descriptor != nullptr ? descriptor->initialValue : 0u;
- fence->signaledValue = initialValue;
- fence->completedValue = initialValue;
- return cFence;
+ return queue->CreateFence(descriptor);
}
void ClientHandwrittenQueueSignal(WGPUQueue cQueue, WGPUFence cFence, uint64_t signalValue) {
- Fence* fence = reinterpret_cast<Fence*>(cFence);
Queue* queue = reinterpret_cast<Queue*>(cQueue);
- if (fence->queue != queue) {
- ClientDeviceInjectError(reinterpret_cast<WGPUDevice>(fence->device),
- WGPUErrorType_Validation,
- "Fence must be signaled on the queue on which it was created.");
- return;
- }
- if (signalValue <= fence->signaledValue) {
- ClientDeviceInjectError(reinterpret_cast<WGPUDevice>(fence->device),
- WGPUErrorType_Validation,
- "Fence value less than or equal to signaled value");
- return;
- }
- fence->signaledValue = signalValue;
-
- QueueSignalCmd cmd;
- cmd.self = cQueue;
- cmd.fence = cFence;
- cmd.signalValue = signalValue;
-
- queue->device->GetClient()->SerializeCommand(cmd);
+ queue->Signal(cFence, signalValue);
}
void ClientHandwrittenQueueWriteBuffer(WGPUQueue cQueue,
@@ -169,16 +115,7 @@
const void* data,
size_t size) {
Queue* queue = reinterpret_cast<Queue*>(cQueue);
- Buffer* buffer = reinterpret_cast<Buffer*>(cBuffer);
-
- QueueWriteBufferInternalCmd cmd;
- cmd.queueId = queue->id;
- cmd.bufferId = buffer->id;
- cmd.bufferOffset = bufferOffset;
- cmd.data = static_cast<const uint8_t*>(data);
- cmd.size = size;
-
- queue->device->GetClient()->SerializeCommand(cmd);
+ queue->WriteBuffer(cBuffer, bufferOffset, data, size);
}
void ClientDeviceReference(WGPUDevice) {
diff --git a/src/dawn_wire/client/ClientDoers.cpp b/src/dawn_wire/client/ClientDoers.cpp
index ffc5198..55818ba 100644
--- a/src/dawn_wire/client/ClientDoers.cpp
+++ b/src/dawn_wire/client/ClientDoers.cpp
@@ -77,8 +77,7 @@
return true;
}
- fence->completedValue = value;
- fence->CheckPassedFences();
+ fence->OnUpdateCompletedValueCallback(value);
return true;
}
diff --git a/src/dawn_wire/client/Device.h b/src/dawn_wire/client/Device.h
index f32259a..42dff18 100644
--- a/src/dawn_wire/client/Device.h
+++ b/src/dawn_wire/client/Device.h
@@ -24,7 +24,7 @@
namespace dawn_wire { namespace client {
class Client;
- struct Queue;
+ class Queue;
class Device : public ObjectBase {
public:
diff --git a/src/dawn_wire/client/Fence.cpp b/src/dawn_wire/client/Fence.cpp
index 607483e..aa0407c 100644
--- a/src/dawn_wire/client/Fence.cpp
+++ b/src/dawn_wire/client/Fence.cpp
@@ -14,22 +14,74 @@
#include "dawn_wire/client/Fence.h"
+#include "dawn_wire/client/ApiProcs_autogen.h"
+
namespace dawn_wire { namespace client {
Fence::~Fence() {
// Callbacks need to be fired in all cases, as they can handle freeing resources
// so we call them with "Unknown" status.
- for (auto& request : requests.IterateAll()) {
+ for (auto& request : mRequests.IterateAll()) {
request.completionCallback(WGPUFenceCompletionStatus_Unknown, request.userdata);
}
- requests.Clear();
+ mRequests.Clear();
+ }
+
+ void Fence::Initialize(Queue* queue, const WGPUFenceDescriptor* descriptor) {
+ mQueue = queue;
+
+ uint64_t initialValue = descriptor != nullptr ? descriptor->initialValue : 0u;
+ mSignaledValue = initialValue;
+ mCompletedValue = initialValue;
}
void Fence::CheckPassedFences() {
- for (auto& request : requests.IterateUpTo(completedValue)) {
+ for (auto& request : mRequests.IterateUpTo(mCompletedValue)) {
request.completionCallback(WGPUFenceCompletionStatus_Success, request.userdata);
}
- requests.ClearUpTo(completedValue);
+ mRequests.ClearUpTo(mCompletedValue);
+ }
+
+ void Fence::OnCompletion(uint64_t value,
+ WGPUFenceOnCompletionCallback callback,
+ void* userdata) {
+ if (value > mSignaledValue) {
+ ClientDeviceInjectError(reinterpret_cast<WGPUDevice>(device), WGPUErrorType_Validation,
+ "Value greater than fence signaled value");
+ callback(WGPUFenceCompletionStatus_Error, userdata);
+ return;
+ }
+
+ if (value <= mCompletedValue) {
+ callback(WGPUFenceCompletionStatus_Success, userdata);
+ return;
+ }
+
+ Fence::OnCompletionData request;
+ request.completionCallback = callback;
+ request.userdata = userdata;
+ mRequests.Enqueue(std::move(request), value);
+ }
+
+ void Fence::OnUpdateCompletedValueCallback(uint64_t value) {
+ mCompletedValue = value;
+ CheckPassedFences();
+ }
+
+ uint64_t Fence::GetCompletedValue() const {
+ return mCompletedValue;
+ }
+
+ uint64_t Fence::GetSignaledValue() const {
+ return mSignaledValue;
+ }
+
+ Queue* Fence::GetQueue() const {
+ return mQueue;
+ }
+
+ void Fence::SetSignaledValue(uint64_t value) {
+ mSignaledValue = value;
}
}} // namespace dawn_wire::client
diff --git a/src/dawn_wire/client/Fence.h b/src/dawn_wire/client/Fence.h
index 4acde6d..107b4e7 100644
--- a/src/dawn_wire/client/Fence.h
+++ b/src/dawn_wire/client/Fence.h
@@ -22,21 +22,33 @@
namespace dawn_wire { namespace client {
- struct Queue;
- struct Fence : ObjectBase {
+ class Queue;
+ class Fence : public ObjectBase {
+ public:
using ObjectBase::ObjectBase;
~Fence();
- void CheckPassedFences();
+ void Initialize(Queue* queue, const WGPUFenceDescriptor* descriptor);
+ void CheckPassedFences();
+ void OnCompletion(uint64_t value, WGPUFenceOnCompletionCallback callback, void* userdata);
+ void OnUpdateCompletedValueCallback(uint64_t value);
+
+ uint64_t GetCompletedValue() const;
+ uint64_t GetSignaledValue() const;
+ Queue* GetQueue() const;
+
+ void SetSignaledValue(uint64_t value);
+
+ private:
struct OnCompletionData {
WGPUFenceOnCompletionCallback completionCallback = nullptr;
void* userdata = nullptr;
};
- Queue* queue = nullptr;
- uint64_t signaledValue = 0;
- uint64_t completedValue = 0;
- SerialMap<OnCompletionData> requests;
+ Queue* mQueue = nullptr;
+ uint64_t mSignaledValue = 0;
+ uint64_t mCompletedValue = 0;
+ SerialMap<OnCompletionData> mRequests;
};
}} // namespace dawn_wire::client
diff --git a/src/dawn_wire/client/Queue.cpp b/src/dawn_wire/client/Queue.cpp
new file mode 100644
index 0000000..fa338f3
--- /dev/null
+++ b/src/dawn_wire/client/Queue.cpp
@@ -0,0 +1,78 @@
+// Copyright 2020 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/Queue.h"
+
+#include "dawn_wire/client/ApiProcs_autogen.h"
+#include "dawn_wire/client/Client.h"
+#include "dawn_wire/client/Device.h"
+
+namespace dawn_wire { namespace client {
+
+ WGPUFence Queue::CreateFence(WGPUFenceDescriptor const* descriptor) {
+ auto* allocation = device->GetClient()->FenceAllocator().New(device);
+
+ QueueCreateFenceCmd cmd;
+ cmd.self = reinterpret_cast<WGPUQueue>(this);
+ cmd.result = ObjectHandle{allocation->object->id, allocation->generation};
+ cmd.descriptor = descriptor;
+ device->GetClient()->SerializeCommand(cmd);
+
+ Fence* fence = allocation->object.get();
+ fence->Initialize(this, descriptor);
+ return reinterpret_cast<WGPUFence>(fence);
+ }
+
+ void Queue::Signal(WGPUFence cFence, uint64_t signalValue) {
+ Fence* fence = reinterpret_cast<Fence*>(cFence);
+ if (fence->GetQueue() != this) {
+ ClientDeviceInjectError(reinterpret_cast<WGPUDevice>(fence->device),
+ WGPUErrorType_Validation,
+ "Fence must be signaled on the queue on which it was created.");
+ return;
+ }
+ if (signalValue <= fence->GetSignaledValue()) {
+ ClientDeviceInjectError(reinterpret_cast<WGPUDevice>(fence->device),
+ WGPUErrorType_Validation,
+ "Fence value less than or equal to signaled value");
+ return;
+ }
+
+ fence->SetSignaledValue(signalValue);
+
+ QueueSignalCmd cmd;
+ cmd.self = reinterpret_cast<WGPUQueue>(this);
+ cmd.fence = cFence;
+ cmd.signalValue = signalValue;
+
+ device->GetClient()->SerializeCommand(cmd);
+ }
+
+ void Queue::WriteBuffer(WGPUBuffer cBuffer,
+ uint64_t bufferOffset,
+ const void* data,
+ size_t size) {
+ Buffer* buffer = reinterpret_cast<Buffer*>(cBuffer);
+
+ QueueWriteBufferInternalCmd cmd;
+ cmd.queueId = id;
+ cmd.bufferId = buffer->id;
+ cmd.bufferOffset = bufferOffset;
+ cmd.data = static_cast<const uint8_t*>(data);
+ cmd.size = size;
+
+ device->GetClient()->SerializeCommand(cmd);
+ }
+
+}} // namespace dawn_wire::client
diff --git a/src/dawn_wire/client/Queue.h b/src/dawn_wire/client/Queue.h
new file mode 100644
index 0000000..9e51618
--- /dev/null
+++ b/src/dawn_wire/client/Queue.h
@@ -0,0 +1,38 @@
+// Copyright 2020 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.
+
+#ifndef DAWNWIRE_CLIENT_QUEUE_H_
+#define DAWNWIRE_CLIENT_QUEUE_H_
+
+#include <dawn/webgpu.h>
+
+#include "dawn_wire/WireClient.h"
+#include "dawn_wire/client/ObjectBase.h"
+
+#include <map>
+
+namespace dawn_wire { namespace client {
+
+ class Queue : public ObjectBase {
+ public:
+ using ObjectBase::ObjectBase;
+
+ WGPUFence CreateFence(const WGPUFenceDescriptor* descriptor);
+ void Signal(WGPUFence fence, uint64_t signalValue);
+ void WriteBuffer(WGPUBuffer cBuffer, uint64_t bufferOffset, const void* data, size_t size);
+ };
+
+}} // namespace dawn_wire::client
+
+#endif // DAWNWIRE_CLIENT_QUEUE_H_