diff --git a/dawn.json b/dawn.json index fb88a2144d..f04d366894 100644 --- a/dawn.json +++ b/dawn.json @@ -951,47 +951,6 @@ {"name": "format", "type": "texture format"} ] }, - "fence": { - "category": "object", - "methods": [ - { - "name": "get completed value", - "returns": "uint64_t" - }, - { - "name": "on completion", - "args": [ - {"name": "value", "type": "uint64_t"}, - {"name": "callback", "type": "fence on completion callback"}, - {"name": "userdata", "type": "void", "annotation": "*"} - ] - } - ] - }, - "fence on completion callback": { - "category": "callback", - "args": [ - {"name": "status", "type": "fence completion status"}, - {"name": "userdata", "type": "void", "annotation": "*"} - ] - }, - "fence completion status": { - "category": "enum", - "values": [ - {"value": 0, "name": "success"}, - {"value": 1, "name": "error"}, - {"value": 2, "name": "unknown"}, - {"value": 3, "name": "device lost"} - ] - }, - "fence descriptor": { - "category": "structure", - "extensible": true, - "members": [ - {"name": "label", "type": "char", "annotation": "const*", "length": "strlen", "optional": true}, - {"name": "initial value", "type": "uint64_t", "default": "0"} - ] - }, "filter mode": { "category": "enum", "values": [ @@ -1210,20 +1169,6 @@ {"name": "commands", "type": "command buffer", "annotation": "const*", "length": "command count"} ] }, - { - "name": "signal", - "args": [ - {"name": "fence", "type": "fence"}, - {"name": "signal value", "type": "uint64_t"} - ] - }, - { - "name": "create fence", - "returns": "fence", - "args": [ - {"name": "descriptor", "type": "fence descriptor", "annotation": "const*", "optional": true} - ] - }, { "name": "on submitted work done", "args": [ diff --git a/dawn_wire.json b/dawn_wire.json index dcaac56b11..85a9394a55 100644 --- a/dawn_wire.json +++ b/dawn_wire.json @@ -59,11 +59,6 @@ { "name": "object type", "type": "ObjectType" }, { "name": "object id", "type": "ObjectId" } ], - "fence on completion": [ - { "name": "fence id", "type": "ObjectId" }, - { "name": "value", "type": "uint64_t" }, - { "name": "request serial", "type": "uint64_t" } - ], "queue on submitted work done": [ { "name": "queue id", "type": "ObjectId" }, { "name": "signal value", "type": "uint64_t" }, @@ -124,15 +119,6 @@ { "name": "type", "type": "error type" }, { "name": "message", "type": "char", "annotation": "const*", "length": "strlen" } ], - "fence on completion callback": [ - { "name": "fence", "type": "ObjectHandle", "handle_type": "fence" }, - { "name": "request serial", "type": "uint64_t" }, - { "name": "status", "type": "fence completion status" } - ], - "fence update completed value": [ - { "name": "fence", "type": "ObjectHandle", "handle_type": "fence" }, - { "name": "value", "type": "uint64_t" } - ], "queue work done callback": [ { "name": "queue", "type": "ObjectHandle", "handle_type": "queue" }, { "name": "request serial", "type": "uint64_t" }, @@ -162,8 +148,6 @@ "DevicePopErrorScope", "DeviceSetDeviceLostCallback", "DeviceSetUncapturedErrorCallback", - "FenceGetCompletedValue", - "FenceOnCompletion", "ShaderModuleGetCompilationInfo", "QueueOnSubmittedWorkDone", "QueueWriteBuffer", @@ -176,13 +160,11 @@ "DeviceGetDefaultQueue", "DeviceGetQueue", "DeviceInjectError", - "DevicePushErrorScope", - "QueueCreateFence" + "DevicePushErrorScope" ], "client_special_objects": [ "Buffer", "Device", - "Fence", "Queue", "ShaderModule" ], @@ -194,7 +176,6 @@ "QueueSignal" ], "server_reverse_lookup_objects": [ - "Fence" ] } } diff --git a/src/dawn_native/BUILD.gn b/src/dawn_native/BUILD.gn index 8e4f0c4ddf..7ea9b167c7 100644 --- a/src/dawn_native/BUILD.gn +++ b/src/dawn_native/BUILD.gn @@ -228,8 +228,6 @@ source_set("dawn_native_sources") { "Extensions.h", "ExternalTexture.cpp", "ExternalTexture.h", - "Fence.cpp", - "Fence.h", "Format.cpp", "Format.h", "Forward.h", diff --git a/src/dawn_native/CMakeLists.txt b/src/dawn_native/CMakeLists.txt index b0d470b6ed..f03d6fd678 100644 --- a/src/dawn_native/CMakeLists.txt +++ b/src/dawn_native/CMakeLists.txt @@ -96,8 +96,6 @@ target_sources(dawn_native PRIVATE "ExternalTexture.h" "ObjectContentHasher.cpp" "ObjectContentHasher.h" - "Fence.cpp" - "Fence.h" "Format.cpp" "Format.h" "Forward.h" diff --git a/src/dawn_native/Device.cpp b/src/dawn_native/Device.cpp index 713688eb25..9363a15839 100644 --- a/src/dawn_native/Device.cpp +++ b/src/dawn_native/Device.cpp @@ -30,7 +30,6 @@ #include "dawn_native/ErrorData.h" #include "dawn_native/ErrorScope.h" #include "dawn_native/ExternalTexture.h" -#include "dawn_native/Fence.h" #include "dawn_native/Instance.h" #include "dawn_native/InternalPipelineStore.h" #include "dawn_native/PersistentCache.h" diff --git a/src/dawn_native/Fence.cpp b/src/dawn_native/Fence.cpp deleted file mode 100644 index c9f322470b..0000000000 --- a/src/dawn_native/Fence.cpp +++ /dev/null @@ -1,159 +0,0 @@ -// Copyright 2018 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_native/Fence.h" - -#include "common/Assert.h" -#include "dawn_native/Device.h" -#include "dawn_native/Queue.h" -#include "dawn_native/ValidationUtils_autogen.h" - -#include - -namespace dawn_native { - - struct FenceInFlight : QueueBase::TaskInFlight { - FenceInFlight(Ref fence, FenceAPISerial value) - : fence(std::move(fence)), value(value) { - } - void Finish() override { - fence->SetCompletedValue(value, WGPUFenceCompletionStatus_Success); - } - void HandleDeviceLoss() override { - fence->SetCompletedValue(value, WGPUFenceCompletionStatus_DeviceLost); - } - ~FenceInFlight() override = default; - - private: - Ref fence; - FenceAPISerial value; - }; - - MaybeError ValidateFenceDescriptor(const FenceDescriptor* descriptor) { - if (descriptor->nextInChain != nullptr) { - return DAWN_VALIDATION_ERROR("nextInChain must be nullptr"); - } - - return {}; - } - - // Fence - - Fence::Fence(QueueBase* queue, const FenceDescriptor* descriptor) - : ObjectBase(queue->GetDevice()), - mSignalValue(descriptor->initialValue), - mCompletedValue(descriptor->initialValue), - mQueue(queue) { - } - - Fence::Fence(DeviceBase* device, ObjectBase::ErrorTag tag) : ObjectBase(device, tag) { - } - - Fence::~Fence() { - for (auto& request : mRequests.IterateAll()) { - ASSERT(!IsError()); - request.completionCallback(WGPUFenceCompletionStatus_Unknown, request.userdata); - } - mRequests.Clear(); - } - - // static - Fence* Fence::MakeError(DeviceBase* device) { - return new Fence(device, ObjectBase::kError); - } - - uint64_t Fence::APIGetCompletedValue() const { - if (IsError()) { - return 0; - } - return uint64_t(mCompletedValue); - } - - void Fence::APIOnCompletion(uint64_t apiValue, - wgpu::FenceOnCompletionCallback callback, - void* userdata) { - FenceAPISerial value(apiValue); - - WGPUFenceCompletionStatus status; - if (GetDevice()->ConsumedError(ValidateOnCompletion(value, &status))) { - callback(status, userdata); - return; - } - ASSERT(!IsError()); - - if (value <= mCompletedValue) { - callback(WGPUFenceCompletionStatus_Success, userdata); - return; - } - - OnCompletionData request; - request.completionCallback = callback; - request.userdata = userdata; - mRequests.Enqueue(std::move(request), value); - } - - FenceAPISerial Fence::GetSignaledValue() const { - ASSERT(!IsError()); - return mSignalValue; - } - - const QueueBase* Fence::GetQueue() const { - ASSERT(!IsError()); - return mQueue.Get(); - } - - void Fence::SetSignaledValue(FenceAPISerial signalValue) { - ASSERT(!IsError()); - ASSERT(signalValue > mSignalValue); - mSignalValue = signalValue; - } - - void Fence::SetCompletedValue(FenceAPISerial completedValue, WGPUFenceCompletionStatus status) { - ASSERT(!IsError()); - ASSERT(completedValue <= mSignalValue); - ASSERT(completedValue > mCompletedValue); - mCompletedValue = completedValue; - - for (auto& request : mRequests.IterateUpTo(mCompletedValue)) { - request.completionCallback(status, request.userdata); - } - mRequests.ClearUpTo(mCompletedValue); - } - - void Fence::UpdateFenceOnComplete(Fence* fence, FenceAPISerial value) { - std::unique_ptr fenceInFlight = - std::make_unique(fence, value); - - // TODO: use GetLastSubmittedCommandSerial in the future for perforamnce - GetDevice()->GetQueue()->TrackTask(std::move(fenceInFlight), - GetDevice()->GetPendingCommandSerial()); - } - - MaybeError Fence::ValidateOnCompletion(FenceAPISerial value, - WGPUFenceCompletionStatus* status) const { - *status = WGPUFenceCompletionStatus_DeviceLost; - DAWN_TRY(GetDevice()->ValidateIsAlive()); - - *status = WGPUFenceCompletionStatus_Error; - DAWN_TRY(GetDevice()->ValidateObject(this)); - - if (value > mSignalValue) { - return DAWN_VALIDATION_ERROR("Value greater than fence signaled value"); - } - - *status = WGPUFenceCompletionStatus_Success; - return {}; - } - -} // namespace dawn_native diff --git a/src/dawn_native/Fence.h b/src/dawn_native/Fence.h deleted file mode 100644 index 2f834349ed..0000000000 --- a/src/dawn_native/Fence.h +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright 2018 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 DAWNNATIVE_FENCE_H_ -#define DAWNNATIVE_FENCE_H_ - -#include "common/SerialMap.h" -#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" - -#include - -namespace dawn_native { - - MaybeError ValidateFenceDescriptor(const FenceDescriptor* descriptor); - - class Fence final : public ObjectBase { - public: - Fence(QueueBase* queue, const FenceDescriptor* descriptor); - - static Fence* MakeError(DeviceBase* device); - - FenceAPISerial GetSignaledValue() const; - const QueueBase* GetQueue() const; - - // Dawn API - uint64_t APIGetCompletedValue() const; - void APIOnCompletion(uint64_t value, - wgpu::FenceOnCompletionCallback callback, - void* userdata); - - protected: - friend class QueueBase; - friend struct FenceInFlight; - void SetSignaledValue(FenceAPISerial signalValue); - void SetCompletedValue(FenceAPISerial completedValue, WGPUFenceCompletionStatus status); - void UpdateFenceOnComplete(Fence* fence, FenceAPISerial value); - - private: - Fence(DeviceBase* device, ObjectBase::ErrorTag tag); - ~Fence() override; - - MaybeError ValidateOnCompletion(FenceAPISerial value, - WGPUFenceCompletionStatus* status) const; - - struct OnCompletionData { - wgpu::FenceOnCompletionCallback completionCallback = nullptr; - void* userdata = nullptr; - }; - - FenceAPISerial mSignalValue; - FenceAPISerial mCompletedValue; - Ref mQueue; - SerialMap mRequests; - }; - -} // namespace dawn_native - -#endif // DAWNNATIVE_FENCE_H_ diff --git a/src/dawn_native/Queue.cpp b/src/dawn_native/Queue.cpp index eddee0ad7a..fc3d9b3ab7 100644 --- a/src/dawn_native/Queue.cpp +++ b/src/dawn_native/Queue.cpp @@ -23,7 +23,6 @@ #include "dawn_native/CopyTextureForBrowserHelper.h" #include "dawn_native/Device.h" #include "dawn_native/DynamicUploader.h" -#include "dawn_native/Fence.h" #include "dawn_native/QuerySet.h" #include "dawn_native/RenderPassEncoder.h" #include "dawn_native/RenderPipeline.h" @@ -184,19 +183,6 @@ namespace dawn_native { } } - void QueueBase::APISignal(Fence* fence, uint64_t apiSignalValue) { - FenceAPISerial signalValue(apiSignalValue); - - DeviceBase* device = GetDevice(); - if (device->ConsumedError(ValidateSignal(fence, signalValue))) { - return; - } - ASSERT(!IsError()); - - fence->SetSignaledValue(signalValue); - fence->UpdateFenceOnComplete(fence, signalValue); - } - void QueueBase::APIOnSubmittedWorkDone(uint64_t signalValue, WGPUQueueWorkDoneCallback callback, void* userdata) { @@ -246,22 +232,6 @@ namespace dawn_native { mTasksInFlight.Clear(); } - Fence* QueueBase::APICreateFence(const FenceDescriptor* descriptor) { - // TODO(chromium:1177476): Remove once the deprecation period is finished. - GetDevice()->EmitDeprecationWarning( - "Fences are deprecated, use Queue::OnSubmittedWorkDone instead."); - - if (GetDevice()->ConsumedError(ValidateCreateFence(descriptor))) { - return Fence::MakeError(GetDevice()); - } - - if (descriptor == nullptr) { - FenceDescriptor defaultDescriptor = {}; - return new Fence(this, &defaultDescriptor); - } - return new Fence(this, descriptor); - } - void QueueBase::APIWriteBuffer(BufferBase* buffer, uint64_t bufferOffset, const void* data, @@ -437,21 +407,6 @@ namespace dawn_native { return {}; } - MaybeError QueueBase::ValidateSignal(const Fence* fence, FenceAPISerial signalValue) const { - DAWN_TRY(GetDevice()->ValidateIsAlive()); - DAWN_TRY(GetDevice()->ValidateObject(this)); - DAWN_TRY(GetDevice()->ValidateObject(fence)); - - if (fence->GetQueue() != this) { - return DAWN_VALIDATION_ERROR( - "Fence must be signaled on the queue on which it was created."); - } - if (signalValue <= fence->GetSignaledValue()) { - return DAWN_VALIDATION_ERROR("Signal value less than or equal to fence signaled value"); - } - return {}; - } - MaybeError QueueBase::ValidateOnSubmittedWorkDone(uint64_t signalValue, WGPUQueueWorkDoneStatus* status) const { *status = WGPUQueueWorkDoneStatus_DeviceLost; @@ -467,16 +422,6 @@ namespace dawn_native { return {}; } - MaybeError QueueBase::ValidateCreateFence(const FenceDescriptor* descriptor) const { - DAWN_TRY(GetDevice()->ValidateIsAlive()); - DAWN_TRY(GetDevice()->ValidateObject(this)); - if (descriptor != nullptr) { - DAWN_TRY(ValidateFenceDescriptor(descriptor)); - } - - return {}; - } - MaybeError QueueBase::ValidateWriteBuffer(const BufferBase* buffer, uint64_t bufferOffset, size_t size) const { diff --git a/src/dawn_native/Queue.h b/src/dawn_native/Queue.h index e0f59c4fee..b1795c1f65 100644 --- a/src/dawn_native/Queue.h +++ b/src/dawn_native/Queue.h @@ -38,8 +38,6 @@ namespace dawn_native { // Dawn API void APISubmit(uint32_t commandCount, CommandBufferBase* const* commands); - void APISignal(Fence* fence, uint64_t signalValue); - Fence* APICreateFence(const FenceDescriptor* descriptor); void APIOnSubmittedWorkDone(uint64_t signalValue, WGPUQueueWorkDoneCallback callback, void* userdata); @@ -92,10 +90,8 @@ namespace dawn_native { const Extent3D& writeSize); MaybeError ValidateSubmit(uint32_t commandCount, CommandBufferBase* const* commands) const; - MaybeError ValidateSignal(const Fence* fence, FenceAPISerial signalValue) const; MaybeError ValidateOnSubmittedWorkDone(uint64_t signalValue, WGPUQueueWorkDoneStatus* status) const; - MaybeError ValidateCreateFence(const FenceDescriptor* descriptor) const; MaybeError ValidateWriteBuffer(const BufferBase* buffer, uint64_t bufferOffset, size_t size) const; diff --git a/src/dawn_wire/BUILD.gn b/src/dawn_wire/BUILD.gn index 4a3f127583..b0b0c5e021 100644 --- a/src/dawn_wire/BUILD.gn +++ b/src/dawn_wire/BUILD.gn @@ -80,8 +80,6 @@ dawn_component("dawn_wire") { "client/ClientInlineMemoryTransferService.cpp", "client/Device.cpp", "client/Device.h", - "client/Fence.cpp", - "client/Fence.h", "client/ObjectAllocator.h", "client/Queue.cpp", "client/Queue.h", @@ -92,7 +90,6 @@ dawn_component("dawn_wire") { "server/Server.h", "server/ServerBuffer.cpp", "server/ServerDevice.cpp", - "server/ServerFence.cpp", "server/ServerInlineMemoryTransferService.cpp", "server/ServerQueue.cpp", "server/ServerShaderModule.cpp", diff --git a/src/dawn_wire/CMakeLists.txt b/src/dawn_wire/CMakeLists.txt index b1f9ba4bc2..bbcb04494c 100644 --- a/src/dawn_wire/CMakeLists.txt +++ b/src/dawn_wire/CMakeLists.txt @@ -52,8 +52,6 @@ target_sources(dawn_wire PRIVATE "client/ClientInlineMemoryTransferService.cpp" "client/Device.cpp" "client/Device.h" - "client/Fence.cpp" - "client/Fence.h" "client/ObjectAllocator.h" "client/Queue.cpp" "client/Queue.h" @@ -64,7 +62,6 @@ target_sources(dawn_wire PRIVATE "server/Server.h" "server/ServerBuffer.cpp" "server/ServerDevice.cpp" - "server/ServerFence.cpp" "server/ServerInlineMemoryTransferService.cpp" "server/ServerQueue.cpp" "server/ServerShaderModule.cpp" diff --git a/src/dawn_wire/client/ApiObjects.h b/src/dawn_wire/client/ApiObjects.h index 8ec482a971..71dbc82dfe 100644 --- a/src/dawn_wire/client/ApiObjects.h +++ b/src/dawn_wire/client/ApiObjects.h @@ -19,7 +19,6 @@ #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/ShaderModule.h" diff --git a/src/dawn_wire/client/ClientDoers.cpp b/src/dawn_wire/client/ClientDoers.cpp index 4073baa2ff..64db68840e 100644 --- a/src/dawn_wire/client/ClientDoers.cpp +++ b/src/dawn_wire/client/ClientDoers.cpp @@ -70,26 +70,6 @@ namespace dawn_wire { namespace client { readInitialDataInfo); } - bool Client::DoFenceUpdateCompletedValue(Fence* fence, uint64_t value) { - // The fence might have been deleted or recreated so this isn't an error. - if (fence == nullptr) { - return true; - } - - fence->OnUpdateCompletedValueCallback(value); - return true; - } - - bool Client::DoFenceOnCompletionCallback(Fence* fence, - uint64_t requestSerial, - WGPUFenceCompletionStatus status) { - // The fence might have been deleted or recreated so this isn't an error. - if (fence == nullptr) { - return true; - } - return fence->OnCompletionCallback(requestSerial, status); - } - bool Client::DoQueueWorkDoneCallback(Queue* queue, uint64_t requestSerial, WGPUQueueWorkDoneStatus status) { diff --git a/src/dawn_wire/client/Fence.cpp b/src/dawn_wire/client/Fence.cpp deleted file mode 100644 index 563f13f1fe..0000000000 --- a/src/dawn_wire/client/Fence.cpp +++ /dev/null @@ -1,89 +0,0 @@ -// 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/Fence.h" - -#include "dawn_wire/client/Client.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& it : mOnCompletionRequests) { - if (it.second.callback) { - it.second.callback(WGPUFenceCompletionStatus_Unknown, it.second.userdata); - } - } - mOnCompletionRequests.clear(); - } - - void Fence::CancelCallbacksForDisconnect() { - for (auto& it : mOnCompletionRequests) { - if (it.second.callback) { - it.second.callback(WGPUFenceCompletionStatus_DeviceLost, it.second.userdata); - } - } - mOnCompletionRequests.clear(); - } - - void Fence::Initialize(const WGPUFenceDescriptor* descriptor) { - mCompletedValue = descriptor != nullptr ? descriptor->initialValue : 0u; - } - - void Fence::OnCompletion(uint64_t value, - WGPUFenceOnCompletionCallback callback, - void* userdata) { - if (client->IsDisconnected()) { - callback(WGPUFenceCompletionStatus_DeviceLost, userdata); - return; - } - - uint32_t serial = mOnCompletionRequestSerial++; - ASSERT(mOnCompletionRequests.find(serial) == mOnCompletionRequests.end()); - - FenceOnCompletionCmd cmd; - cmd.fenceId = this->id; - cmd.value = value; - cmd.requestSerial = serial; - - mOnCompletionRequests[serial] = {callback, userdata}; - - client->SerializeCommand(cmd); - } - - void Fence::OnUpdateCompletedValueCallback(uint64_t value) { - mCompletedValue = value; - } - - bool Fence::OnCompletionCallback(uint64_t requestSerial, WGPUFenceCompletionStatus status) { - auto requestIt = mOnCompletionRequests.find(requestSerial); - if (requestIt == mOnCompletionRequests.end()) { - return false; - } - - // Remove the request data so that the callback cannot be called again. - // ex.) inside the callback: if the fence is deleted, all callbacks reject. - OnCompletionData request = std::move(requestIt->second); - mOnCompletionRequests.erase(requestIt); - - request.callback(status, request.userdata); - return true; - } - - uint64_t Fence::GetCompletedValue() const { - return mCompletedValue; - } - -}} // namespace dawn_wire::client diff --git a/src/dawn_wire/client/Fence.h b/src/dawn_wire/client/Fence.h deleted file mode 100644 index 7c09948e56..0000000000 --- a/src/dawn_wire/client/Fence.h +++ /dev/null @@ -1,53 +0,0 @@ -// 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. - -#ifndef DAWNWIRE_CLIENT_FENCE_H_ -#define DAWNWIRE_CLIENT_FENCE_H_ - -#include - -#include "common/SerialMap.h" -#include "dawn_wire/client/ObjectBase.h" - -namespace dawn_wire { namespace client { - - class Queue; - class Fence final : public ObjectBase { - public: - using ObjectBase::ObjectBase; - ~Fence(); - void Initialize(const WGPUFenceDescriptor* descriptor); - - void CheckPassedFences(); - void OnCompletion(uint64_t value, WGPUFenceOnCompletionCallback callback, void* userdata); - void OnUpdateCompletedValueCallback(uint64_t value); - bool OnCompletionCallback(uint64_t requestSerial, WGPUFenceCompletionStatus status); - - uint64_t GetCompletedValue() const; - - private: - void CancelCallbacksForDisconnect() override; - - struct OnCompletionData { - WGPUFenceOnCompletionCallback callback = nullptr; - void* userdata = nullptr; - }; - uint64_t mCompletedValue = 0; - uint64_t mOnCompletionRequestSerial = 0; - std::map mOnCompletionRequests; - }; - -}} // namespace dawn_wire::client - -#endif // DAWNWIRE_CLIENT_FENCE_H_ diff --git a/src/dawn_wire/client/Queue.cpp b/src/dawn_wire/client/Queue.cpp index 6d4da45070..1ac8c77819 100644 --- a/src/dawn_wire/client/Queue.cpp +++ b/src/dawn_wire/client/Queue.cpp @@ -60,20 +60,6 @@ namespace dawn_wire { namespace client { client->SerializeCommand(cmd); } - WGPUFence Queue::CreateFence(WGPUFenceDescriptor const* descriptor) { - auto* allocation = client->FenceAllocator().New(client); - - QueueCreateFenceCmd cmd; - cmd.self = ToAPI(this); - cmd.result = ObjectHandle{allocation->object->id, allocation->generation}; - cmd.descriptor = descriptor; - client->SerializeCommand(cmd); - - Fence* fence = allocation->object.get(); - fence->Initialize(descriptor); - return ToAPI(fence); - } - void Queue::WriteBuffer(WGPUBuffer cBuffer, uint64_t bufferOffset, const void* data, diff --git a/src/dawn_wire/client/Queue.h b/src/dawn_wire/client/Queue.h index 46a2fb58b0..d8e93a3106 100644 --- a/src/dawn_wire/client/Queue.h +++ b/src/dawn_wire/client/Queue.h @@ -35,7 +35,6 @@ namespace dawn_wire { namespace client { void OnSubmittedWorkDone(uint64_t signalValue, WGPUQueueWorkDoneCallback callback, void* userdata); - WGPUFence CreateFence(const WGPUFenceDescriptor* descriptor); void WriteBuffer(WGPUBuffer cBuffer, uint64_t bufferOffset, const void* data, size_t size); void WriteTexture(const WGPUImageCopyTexture* destination, const void* data, diff --git a/src/dawn_wire/server/Server.h b/src/dawn_wire/server/Server.h index 1979d87d23..0ca756dedd 100644 --- a/src/dawn_wire/server/Server.h +++ b/src/dawn_wire/server/Server.h @@ -127,20 +127,6 @@ namespace dawn_wire { namespace server { uint64_t requestSerial; }; - struct FenceCompletionUserdata : CallbackUserdata { - using CallbackUserdata::CallbackUserdata; - - ObjectHandle fence; - uint64_t value; - }; - - struct FenceOnCompletionUserdata : CallbackUserdata { - using CallbackUserdata::CallbackUserdata; - - ObjectHandle fence; - uint64_t requestSerial; - }; - struct ShaderModuleGetCompilationInfoUserdata : CallbackUserdata { using CallbackUserdata::CallbackUserdata; @@ -218,10 +204,6 @@ namespace dawn_wire { namespace server { const char* message, ErrorScopeUserdata* userdata); void OnBufferMapAsyncCallback(WGPUBufferMapAsyncStatus status, MapUserdata* userdata); - void OnFenceCompletedValueUpdated(WGPUFenceCompletionStatus status, - FenceCompletionUserdata* userdata); - void OnFenceOnCompletion(WGPUFenceCompletionStatus status, - FenceOnCompletionUserdata* userdata); void OnQueueWorkDone(WGPUQueueWorkDoneStatus status, QueueWorkDoneUserdata* userdata); void OnCreateComputePipelineAsyncCallback(WGPUCreatePipelineAsyncStatus status, WGPUComputePipeline pipeline, diff --git a/src/dawn_wire/server/ServerFence.cpp b/src/dawn_wire/server/ServerFence.cpp deleted file mode 100644 index 7d7884007f..0000000000 --- a/src/dawn_wire/server/ServerFence.cpp +++ /dev/null @@ -1,67 +0,0 @@ -// 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/server/Server.h" - -#include - -namespace dawn_wire { namespace server { - - void Server::OnFenceCompletedValueUpdated(WGPUFenceCompletionStatus status, - FenceCompletionUserdata* data) { - if (status != WGPUFenceCompletionStatus_Success) { - return; - } - - ReturnFenceUpdateCompletedValueCmd cmd; - cmd.fence = data->fence; - cmd.value = data->value; - - SerializeCommand(cmd); - } - - bool Server::DoFenceOnCompletion(ObjectId fenceId, uint64_t value, uint64_t requestSerial) { - // The null object isn't valid as `self` - if (fenceId == 0) { - return false; - } - - auto* fence = FenceObjects().Get(fenceId); - if (fence == nullptr) { - return false; - } - - auto userdata = MakeUserdata(); - userdata->fence = ObjectHandle{fenceId, fence->generation}; - userdata->requestSerial = requestSerial; - - mProcs.fenceOnCompletion( - fence->handle, value, - ForwardToServer::Func<&Server::OnFenceOnCompletion>(), - userdata.release()); - return true; - } - - void Server::OnFenceOnCompletion(WGPUFenceCompletionStatus status, - FenceOnCompletionUserdata* data) { - ReturnFenceOnCompletionCallbackCmd cmd; - cmd.fence = data->fence; - cmd.requestSerial = data->requestSerial; - cmd.status = status; - - SerializeCommand(cmd); - } - -}} // namespace dawn_wire::server diff --git a/src/dawn_wire/server/ServerQueue.cpp b/src/dawn_wire/server/ServerQueue.cpp index f194b32b2a..0ab99f5b32 100644 --- a/src/dawn_wire/server/ServerQueue.cpp +++ b/src/dawn_wire/server/ServerQueue.cpp @@ -17,29 +17,6 @@ namespace dawn_wire { namespace server { - bool Server::DoQueueSignal(WGPUQueue cSelf, WGPUFence cFence, uint64_t signalValue) { - if (cFence == nullptr) { - return false; - } - mProcs.queueSignal(cSelf, cFence, signalValue); - - ObjectId fenceId = FenceObjectIdTable().Get(cFence); - ASSERT(fenceId != 0); - auto* fence = FenceObjects().Get(fenceId); - ASSERT(fence != nullptr); - - auto userdata = MakeUserdata(); - userdata->fence = ObjectHandle{fenceId, fence->generation}; - userdata->value = signalValue; - - mProcs.fenceOnCompletion( - cFence, signalValue, - ForwardToServer::Func< - &Server::OnFenceCompletedValueUpdated>(), - userdata.release()); - return true; - } - void Server::OnQueueWorkDone(WGPUQueueWorkDoneStatus status, QueueWorkDoneUserdata* data) { ReturnQueueWorkDoneCallbackCmd cmd; cmd.queue = data->queue; diff --git a/src/tests/BUILD.gn b/src/tests/BUILD.gn index f90325d28d..d4ba8069ca 100644 --- a/src/tests/BUILD.gn +++ b/src/tests/BUILD.gn @@ -197,7 +197,6 @@ test("dawn_unittests") { "unittests/validation/DynamicStateCommandValidationTests.cpp", "unittests/validation/ErrorScopeValidationTests.cpp", "unittests/validation/ExternalTextureTests.cpp", - "unittests/validation/FenceValidationTests.cpp", "unittests/validation/GetBindGroupLayoutValidationTests.cpp", "unittests/validation/IndexBufferValidationTests.cpp", "unittests/validation/MinimumBufferSizeValidationTests.cpp", @@ -232,7 +231,6 @@ test("dawn_unittests") { "unittests/wire/WireDisconnectTests.cpp", "unittests/wire/WireErrorCallbackTests.cpp", "unittests/wire/WireExtensionTests.cpp", - "unittests/wire/WireFenceTests.cpp", "unittests/wire/WireInjectDeviceTests.cpp", "unittests/wire/WireInjectSwapChainTests.cpp", "unittests/wire/WireInjectTextureTests.cpp", @@ -318,7 +316,6 @@ source_set("dawn_end2end_tests_sources") { "end2end/DynamicBufferOffsetTests.cpp", "end2end/EntryPointTests.cpp", "end2end/ExternalTextureTests.cpp", - "end2end/FenceTests.cpp", "end2end/FirstIndexOffsetTests.cpp", "end2end/GpuMemorySynchronizationTests.cpp", "end2end/IndexFormatTests.cpp", diff --git a/src/tests/end2end/DeprecatedAPITests.cpp b/src/tests/end2end/DeprecatedAPITests.cpp index 3eebcfcdc0..7def5567ba 100644 --- a/src/tests/end2end/DeprecatedAPITests.cpp +++ b/src/tests/end2end/DeprecatedAPITests.cpp @@ -188,11 +188,6 @@ TEST_P(DeprecationTests, BindGroupLayoutEntryViewDimensionDefaulting) { } } -// Test that fences are deprecated. -TEST_P(DeprecationTests, CreateFence) { - EXPECT_DEPRECATION_WARNING(queue.CreateFence()); -} - DAWN_INSTANTIATE_TEST(DeprecationTests, D3D12Backend(), MetalBackend(), diff --git a/src/tests/end2end/DeviceLostTests.cpp b/src/tests/end2end/DeviceLostTests.cpp index 6989caf2a5..2441de511c 100644 --- a/src/tests/end2end/DeviceLostTests.cpp +++ b/src/tests/end2end/DeviceLostTests.cpp @@ -35,23 +35,6 @@ static void ToMockDeviceLostCallback(const char* message, void* userdata) { self->StartExpectDeviceError(); } -class MockFenceOnCompletionCallback { - public: - MOCK_METHOD(void, Call, (WGPUFenceCompletionStatus status, void* userdata)); -}; - -static std::unique_ptr mockFenceOnCompletionCallback; -static void ToMockFenceOnCompletionFails(WGPUFenceCompletionStatus status, void* userdata) { - EXPECT_EQ(WGPUFenceCompletionStatus_DeviceLost, status); - mockFenceOnCompletionCallback->Call(status, userdata); - mockFenceOnCompletionCallback = nullptr; -} -static void ToMockFenceOnCompletionSucceeds(WGPUFenceCompletionStatus status, void* userdata) { - EXPECT_EQ(WGPUFenceCompletionStatus_Success, status); - mockFenceOnCompletionCallback->Call(status, userdata); - mockFenceOnCompletionCallback = nullptr; -} - class MockQueueWorkDoneCallback { public: MOCK_METHOD(void, Call, (WGPUQueueWorkDoneStatus status, void* userdata)); @@ -70,13 +53,11 @@ class DeviceLostTest : public DawnTest { DawnTest::SetUp(); DAWN_SKIP_TEST_IF(UsesWire()); mockDeviceLostCallback = std::make_unique(); - mockFenceOnCompletionCallback = std::make_unique(); mockQueueWorkDoneCallback = std::make_unique(); } void TearDown() override { mockDeviceLostCallback = nullptr; - mockFenceOnCompletionCallback = nullptr; mockQueueWorkDoneCallback = nullptr; DawnTest::TearDown(); } @@ -416,67 +397,6 @@ TEST_P(DeviceLostTest, CommandEncoderFinishFails) { ASSERT_DEVICE_ERROR(encoder.Finish()); } -// Test that CreateFenceFails when device is lost -TEST_P(DeviceLostTest, CreateFenceFails) { - SetCallbackAndLoseForTesting(); - - EXPECT_DEPRECATION_WARNING(ASSERT_DEVICE_ERROR(queue.CreateFence())); -} - -// Test that queue signal fails when device is lost -TEST_P(DeviceLostTest, QueueSignalFenceFails) { - wgpu::Fence fence; - EXPECT_DEPRECATION_WARNING(fence = queue.CreateFence()); - - SetCallbackAndLoseForTesting(); - - ASSERT_DEVICE_ERROR(queue.Signal(fence, 3)); - - // callback should have device lost status - EXPECT_CALL(*mockFenceOnCompletionCallback, Call(WGPUFenceCompletionStatus_DeviceLost, nullptr)) - .Times(1); - ASSERT_DEVICE_ERROR(fence.OnCompletion(2u, ToMockFenceOnCompletionFails, nullptr)); - - // completed value should not have changed from initial value - EXPECT_EQ(fence.GetCompletedValue(), 0u); -} - -// Test that Fence On Completion fails after device is lost -TEST_P(DeviceLostTest, FenceOnCompletionFails) { - wgpu::Fence fence; - EXPECT_DEPRECATION_WARNING(fence = queue.CreateFence()); - - queue.Signal(fence, 2); - - SetCallbackAndLoseForTesting(); - // callback should have device lost status - EXPECT_CALL(*mockFenceOnCompletionCallback, Call(WGPUFenceCompletionStatus_DeviceLost, nullptr)) - .Times(1); - ASSERT_DEVICE_ERROR(fence.OnCompletion(2u, ToMockFenceOnCompletionFails, nullptr)); - ASSERT_DEVICE_ERROR(device.Tick()); - - // completed value is the last value signaled (all previous GPU operations are as if completed) - EXPECT_EQ(fence.GetCompletedValue(), 2u); -} - -// Test that Fence::OnCompletion callbacks with device lost status when device is lost after calling -// OnCompletion -TEST_P(DeviceLostTest, FenceOnCompletionBeforeLossFails) { - wgpu::Fence fence; - EXPECT_DEPRECATION_WARNING(fence = queue.CreateFence()); - - queue.Signal(fence, 2); - - // callback should have device lost status - EXPECT_CALL(*mockFenceOnCompletionCallback, Call(WGPUFenceCompletionStatus_DeviceLost, nullptr)) - .Times(1); - fence.OnCompletion(2u, ToMockFenceOnCompletionFails, nullptr); - SetCallbackAndLoseForTesting(); - ASSERT_DEVICE_ERROR(device.Tick()); - - EXPECT_EQ(fence.GetCompletedValue(), 2u); -} - // Test that QueueOnSubmittedWorkDone fails after device is lost. TEST_P(DeviceLostTest, QueueOnSubmittedWorkDoneFails) { SetCallbackAndLoseForTesting(); @@ -499,36 +419,6 @@ TEST_P(DeviceLostTest, QueueOnSubmittedWorkDoneBeforeLossFails) { ASSERT_DEVICE_ERROR(device.Tick()); } -// Regression test for the Null backend not properly setting the completedSerial when -// WaitForIdleForDestruction is called, causing the fence signaling to not be retired and an -// ASSERT to fire. -TEST_P(DeviceLostTest, AfterSubmitAndSerial) { - queue.Submit(0, nullptr); - - wgpu::Fence fence; - EXPECT_DEPRECATION_WARNING(fence = queue.CreateFence()); - - queue.Signal(fence, 1); - SetCallbackAndLoseForTesting(); -} - -// Test that when you Signal, then Tick, then device lost, the fence completed value would be 2 -TEST_P(DeviceLostTest, FenceSignalTickOnCompletion) { - wgpu::Fence fence; - EXPECT_DEPRECATION_WARNING(fence = queue.CreateFence()); - - queue.Signal(fence, 2); - WaitForAllOperations(); - - // callback should have device lost status - EXPECT_CALL(*mockFenceOnCompletionCallback, Call(WGPUFenceCompletionStatus_Success, nullptr)) - .Times(1); - fence.OnCompletion(2u, ToMockFenceOnCompletionSucceeds, nullptr); - SetCallbackAndLoseForTesting(); - - EXPECT_EQ(fence.GetCompletedValue(), 2u); -} - // Test that LostForTesting can only be called on one time TEST_P(DeviceLostTest, LoseForTestingOnce) { // First LoseForTesting call should occur normally diff --git a/src/tests/end2end/FenceTests.cpp b/src/tests/end2end/FenceTests.cpp deleted file mode 100644 index 1eeb7ec313..0000000000 --- a/src/tests/end2end/FenceTests.cpp +++ /dev/null @@ -1,277 +0,0 @@ -// Copyright 2018 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 -#include "tests/DawnTest.h" - -#include -#include - -using namespace testing; - -class MockFenceOnCompletionCallback { - public: - MOCK_METHOD(void, Call, (WGPUFenceCompletionStatus status, void* userdata)); -}; - -static std::unique_ptr mockFenceOnCompletionCallback; -static void ToMockFenceOnCompletion(WGPUFenceCompletionStatus status, void* userdata) { - mockFenceOnCompletionCallback->Call(status, userdata); -} - -class MockPopErrorScopeCallback { - public: - MOCK_METHOD(void, Call, (WGPUErrorType type, const char* message, void* userdata)); -}; - -static std::unique_ptr mockPopErrorScopeCallback; -static void ToMockPopErrorScopeCallback(WGPUErrorType type, const char* message, void* userdata) { - mockPopErrorScopeCallback->Call(type, message, userdata); -} - -class FenceTests : public DawnTest { - private: - struct CallbackInfo { - FenceTests* test; - uint64_t value; - WGPUFenceCompletionStatus status; - int32_t callIndex = -1; // If this is -1, the callback was not called - - void Update(WGPUFenceCompletionStatus status) { - this->callIndex = test->mCallIndex++; - this->status = status; - } - }; - - int32_t mCallIndex; - - protected: - FenceTests() : mCallIndex(0) { - } - - void SetUp() override { - DawnTest::SetUp(); - mockFenceOnCompletionCallback = std::make_unique(); - mockPopErrorScopeCallback = std::make_unique(); - } - - void TearDown() override { - mockFenceOnCompletionCallback = nullptr; - mockPopErrorScopeCallback = nullptr; - DawnTest::TearDown(); - } - - void WaitForCompletedValue(wgpu::Fence fence, uint64_t completedValue) { - while (fence.GetCompletedValue() < completedValue) { - WaitABit(); - } - } -}; - -// Test that signaling a fence updates the completed value -TEST_P(FenceTests, SimpleSignal) { - wgpu::FenceDescriptor descriptor; - descriptor.initialValue = 1u; - wgpu::Fence fence; - EXPECT_DEPRECATION_WARNING(fence = queue.CreateFence(&descriptor)); - - // Completed value starts at initial value - EXPECT_EQ(fence.GetCompletedValue(), 1u); - - queue.Signal(fence, 2); - WaitForCompletedValue(fence, 2); - - // Completed value updates to signaled value - EXPECT_EQ(fence.GetCompletedValue(), 2u); -} - -// Test callbacks are called in increasing order of fence completion value -TEST_P(FenceTests, OnCompletionOrdering) { - wgpu::Fence fence; - EXPECT_DEPRECATION_WARNING(fence = queue.CreateFence()); - - queue.Signal(fence, 4); - - { - testing::InSequence s; - - EXPECT_CALL(*mockFenceOnCompletionCallback, - Call(WGPUFenceCompletionStatus_Success, this + 0)) - .Times(1); - - EXPECT_CALL(*mockFenceOnCompletionCallback, - Call(WGPUFenceCompletionStatus_Success, this + 1)) - .Times(1); - - EXPECT_CALL(*mockFenceOnCompletionCallback, - Call(WGPUFenceCompletionStatus_Success, this + 2)) - .Times(1); - - EXPECT_CALL(*mockFenceOnCompletionCallback, - Call(WGPUFenceCompletionStatus_Success, this + 3)) - .Times(1); - } - - fence.OnCompletion(2u, ToMockFenceOnCompletion, this + 2); - fence.OnCompletion(0u, ToMockFenceOnCompletion, this + 0); - fence.OnCompletion(3u, ToMockFenceOnCompletion, this + 3); - fence.OnCompletion(1u, ToMockFenceOnCompletion, this + 1); - - WaitForCompletedValue(fence, 4); -} - -// Test callbacks still occur if Queue::Signal happens multiple times -TEST_P(FenceTests, MultipleSignalOnCompletion) { - wgpu::Fence fence; - EXPECT_DEPRECATION_WARNING(fence = queue.CreateFence()); - - queue.Signal(fence, 2); - queue.Signal(fence, 4); - - EXPECT_CALL(*mockFenceOnCompletionCallback, Call(WGPUFenceCompletionStatus_Success, nullptr)) - .Times(1); - fence.OnCompletion(3u, ToMockFenceOnCompletion, nullptr); - - WaitForCompletedValue(fence, 4); -} - -// Test callbacks still occur if Queue::Signal and fence::OnCompletion happens multiple times -TEST_P(FenceTests, SignalOnCompletionWait) { - wgpu::Fence fence; - EXPECT_DEPRECATION_WARNING(fence = queue.CreateFence()); - - queue.Signal(fence, 2); - queue.Signal(fence, 6); - - EXPECT_CALL(*mockFenceOnCompletionCallback, Call(WGPUFenceCompletionStatus_Success, this + 2)) - .Times(1); - EXPECT_CALL(*mockFenceOnCompletionCallback, Call(WGPUFenceCompletionStatus_Success, this + 6)) - .Times(1); - - fence.OnCompletion(1u, ToMockFenceOnCompletion, this + 2); - fence.OnCompletion(5u, ToMockFenceOnCompletion, this + 6); - - WaitForCompletedValue(fence, 6); -} - -// Test callbacks still occur if Queue::Signal and fence::OnCompletion happens multiple times -TEST_P(FenceTests, SignalOnCompletionWaitStaggered) { - wgpu::Fence fence; - EXPECT_DEPRECATION_WARNING(fence = queue.CreateFence()); - - queue.Signal(fence, 2); - - EXPECT_CALL(*mockFenceOnCompletionCallback, Call(WGPUFenceCompletionStatus_Success, this + 2)) - .Times(1); - fence.OnCompletion(1u, ToMockFenceOnCompletion, this + 2); - - queue.Signal(fence, 4); - - EXPECT_CALL(*mockFenceOnCompletionCallback, Call(WGPUFenceCompletionStatus_Success, this + 4)) - .Times(1); - fence.OnCompletion(3u, ToMockFenceOnCompletion, this + 4); - - WaitForCompletedValue(fence, 4); -} - -// Test all callbacks are called if they are added for the same fence value -TEST_P(FenceTests, OnCompletionMultipleCallbacks) { - wgpu::Fence fence; - EXPECT_DEPRECATION_WARNING(fence = queue.CreateFence()); - - queue.Signal(fence, 4); - - EXPECT_CALL(*mockFenceOnCompletionCallback, Call(WGPUFenceCompletionStatus_Success, this + 0)) - .Times(1); - - EXPECT_CALL(*mockFenceOnCompletionCallback, Call(WGPUFenceCompletionStatus_Success, this + 1)) - .Times(1); - - EXPECT_CALL(*mockFenceOnCompletionCallback, Call(WGPUFenceCompletionStatus_Success, this + 2)) - .Times(1); - - EXPECT_CALL(*mockFenceOnCompletionCallback, Call(WGPUFenceCompletionStatus_Success, this + 3)) - .Times(1); - - fence.OnCompletion(4u, ToMockFenceOnCompletion, this + 0); - fence.OnCompletion(4u, ToMockFenceOnCompletion, this + 1); - fence.OnCompletion(4u, ToMockFenceOnCompletion, this + 2); - fence.OnCompletion(4u, ToMockFenceOnCompletion, this + 3); - - WaitForCompletedValue(fence, 4u); -} - -// TODO(enga): Enable when fence is removed from fence signal tracker -// Currently it holds a reference and is not destructed -TEST_P(FenceTests, DISABLED_DestroyBeforeOnCompletionEnd) { - wgpu::Fence fence; - EXPECT_DEPRECATION_WARNING(fence = queue.CreateFence()); - - // The fence in this block will be deleted when it goes out of scope - { - wgpu::Fence testFence; - EXPECT_DEPRECATION_WARNING(testFence = queue.CreateFence()); - - queue.Signal(testFence, 4); - - EXPECT_CALL(*mockFenceOnCompletionCallback, - Call(WGPUFenceCompletionStatus_Unknown, this + 0)) - .Times(1); - - EXPECT_CALL(*mockFenceOnCompletionCallback, - Call(WGPUFenceCompletionStatus_Unknown, this + 1)) - .Times(1); - - EXPECT_CALL(*mockFenceOnCompletionCallback, - Call(WGPUFenceCompletionStatus_Unknown, this + 2)) - .Times(1); - - EXPECT_CALL(*mockFenceOnCompletionCallback, - Call(WGPUFenceCompletionStatus_Unknown, this + 3)) - .Times(1); - - testFence.OnCompletion(1u, ToMockFenceOnCompletion, this + 0); - testFence.OnCompletion(2u, ToMockFenceOnCompletion, this + 1); - testFence.OnCompletion(2u, ToMockFenceOnCompletion, this + 2); - testFence.OnCompletion(3u, ToMockFenceOnCompletion, this + 3); - } - - // Wait for another fence to be sure all callbacks have cleared - queue.Signal(fence, 1); - WaitForCompletedValue(fence, 1); -} - -// Regression test that validation errors that are tracked client-side are captured -// in error scopes. -TEST_P(FenceTests, ClientValidationErrorInErrorScope) { - wgpu::Fence fence; - EXPECT_DEPRECATION_WARNING(fence = queue.CreateFence()); - - queue.Signal(fence, 4); - - device.PushErrorScope(wgpu::ErrorFilter::Validation); - queue.Signal(fence, 2); - - EXPECT_CALL(*mockPopErrorScopeCallback, Call(WGPUErrorType_Validation, _, this)).Times(1); - device.PopErrorScope(ToMockPopErrorScopeCallback, this); - - WaitForCompletedValue(fence, 4); -} - -DAWN_INSTANTIATE_TEST(FenceTests, - D3D12Backend(), - MetalBackend(), - OpenGLBackend(), - OpenGLESBackend(), - VulkanBackend()); diff --git a/src/tests/end2end/QueueTimelineTests.cpp b/src/tests/end2end/QueueTimelineTests.cpp index 2991fae6bb..f93c714626 100644 --- a/src/tests/end2end/QueueTimelineTests.cpp +++ b/src/tests/end2end/QueueTimelineTests.cpp @@ -28,17 +28,6 @@ static void ToMockMapCallback(WGPUBufferMapAsyncStatus status, void* userdata) { mockMapCallback->Call(status, userdata); } -class MockFenceOnCompletionCallback { - public: - MOCK_METHOD(void, Call, (WGPUFenceCompletionStatus status, void* userdata)); -}; - -static std::unique_ptr mockFenceOnCompletionCallback; -static void ToMockFenceOnCompletion(WGPUFenceCompletionStatus status, void* userdata) { - EXPECT_EQ(status, WGPUFenceCompletionStatus_Success); - mockFenceOnCompletionCallback->Call(status, userdata); -} - class MockQueueWorkDoneCallback { public: MOCK_METHOD(void, Call, (WGPUQueueWorkDoneStatus status, void* userdata)); @@ -55,7 +44,6 @@ class QueueTimelineTests : public DawnTest { DawnTest::SetUp(); mockMapCallback = std::make_unique(); - mockFenceOnCompletionCallback = std::make_unique(); mockQueueWorkDoneCallback = std::make_unique(); wgpu::BufferDescriptor descriptor; @@ -66,7 +54,6 @@ class QueueTimelineTests : public DawnTest { void TearDown() override { mockMapCallback = nullptr; - mockFenceOnCompletionCallback = nullptr; mockQueueWorkDoneCallback = nullptr; DawnTest::TearDown(); } @@ -74,27 +61,6 @@ class QueueTimelineTests : public DawnTest { wgpu::Buffer mMapReadBuffer; }; -// Test that mMapReadBuffer.MapAsync callback happens before fence.OnCompletion callback -// when queue.Signal is called after mMapReadBuffer.MapAsync. The callback order should -// happen in the order the functions are called. -TEST_P(QueueTimelineTests, MapReadSignalOnComplete) { - testing::InSequence sequence; - EXPECT_CALL(*mockMapCallback, Call(WGPUBufferMapAsyncStatus_Success, this)).Times(1); - EXPECT_CALL(*mockFenceOnCompletionCallback, Call(WGPUFenceCompletionStatus_Success, this)) - .Times(1); - - mMapReadBuffer.MapAsync(wgpu::MapMode::Read, 0, 0, ToMockMapCallback, this); - - wgpu::Fence fence; - EXPECT_DEPRECATION_WARNING(fence = queue.CreateFence()); - - queue.Signal(fence, 1); - fence.OnCompletion(1u, ToMockFenceOnCompletion, this); - - WaitForAllOperations(); - mMapReadBuffer.Unmap(); -} - // Test that mMapReadBuffer.MapAsync callback happens before queue.OnWorkDone callback // when queue.OnSubmittedWorkDone is called after mMapReadBuffer.MapAsync. The callback order should // happen in the order the functions are called. @@ -111,26 +77,6 @@ TEST_P(QueueTimelineTests, MapRead_OnWorkDone) { mMapReadBuffer.Unmap(); } -// Test that fence.OnCompletion callback happens before mMapReadBuffer.MapAsync callback when -// queue.OnSubmittedWorkDone is called before mMapReadBuffer.MapAsync. The callback order should -// happen in the order the functions are called. -TEST_P(QueueTimelineTests, SignalMapReadOnComplete) { - testing::InSequence sequence; - EXPECT_CALL(*mockFenceOnCompletionCallback, Call(WGPUFenceCompletionStatus_Success, this)) - .Times(1); - EXPECT_CALL(*mockMapCallback, Call(WGPUBufferMapAsyncStatus_Success, this)).Times(1); - - wgpu::Fence fence; - EXPECT_DEPRECATION_WARNING(fence = queue.CreateFence()); - queue.Signal(fence, 2); - - mMapReadBuffer.MapAsync(wgpu::MapMode::Read, 0, 0, ToMockMapCallback, this); - - fence.OnCompletion(2u, ToMockFenceOnCompletion, this); - WaitForAllOperations(); - mMapReadBuffer.Unmap(); -} - // Test that queue.OnWorkDone callback happens before mMapReadBuffer.MapAsync callback when // queue.Signal is called before mMapReadBuffer.MapAsync. The callback order should // happen in the order the functions are called. @@ -147,65 +93,6 @@ TEST_P(QueueTimelineTests, OnWorkDone_MapRead) { mMapReadBuffer.Unmap(); } -// Test that fence.OnCompletion callback happens before mMapReadBuffer.MapAsync callback when -// queue.Signal is called before mMapReadBuffer.MapAsync. The callback order should -// happen in the order the functions are called -TEST_P(QueueTimelineTests, SignalOnCompleteMapRead) { - testing::InSequence sequence; - EXPECT_CALL(*mockFenceOnCompletionCallback, Call(WGPUFenceCompletionStatus_Success, this)) - .Times(1); - EXPECT_CALL(*mockMapCallback, Call(WGPUBufferMapAsyncStatus_Success, this)).Times(1); - - wgpu::Fence fence; - EXPECT_DEPRECATION_WARNING(fence = queue.CreateFence()); - queue.Signal(fence, 2); - - fence.OnCompletion(2u, ToMockFenceOnCompletion, this); - - mMapReadBuffer.MapAsync(wgpu::MapMode::Read, 0, 0, ToMockMapCallback, this); - - WaitForAllOperations(); - mMapReadBuffer.Unmap(); -} - -// Test a complicated case with many signals surrounding a buffer mapping. -TEST_P(QueueTimelineTests, SurroundWithFenceSignals) { - testing::InSequence sequence; - EXPECT_CALL(*mockFenceOnCompletionCallback, Call(WGPUFenceCompletionStatus_Success, this + 0)) - .Times(1); - EXPECT_CALL(*mockFenceOnCompletionCallback, Call(WGPUFenceCompletionStatus_Success, this + 2)) - .Times(1); - EXPECT_CALL(*mockFenceOnCompletionCallback, Call(WGPUFenceCompletionStatus_Success, this + 3)) - .Times(1); - EXPECT_CALL(*mockMapCallback, Call(WGPUBufferMapAsyncStatus_Success, this)).Times(1); - EXPECT_CALL(*mockFenceOnCompletionCallback, Call(WGPUFenceCompletionStatus_Success, this + 5)) - .Times(1); - EXPECT_CALL(*mockFenceOnCompletionCallback, Call(WGPUFenceCompletionStatus_Success, this + 6)) - .Times(1); - EXPECT_CALL(*mockFenceOnCompletionCallback, Call(WGPUFenceCompletionStatus_Success, this + 8)) - .Times(1); - - wgpu::Fence fence; - EXPECT_DEPRECATION_WARNING(fence = queue.CreateFence()); - queue.Signal(fence, 2); - queue.Signal(fence, 4); - - fence.OnCompletion(1u, ToMockFenceOnCompletion, this + 0); - fence.OnCompletion(2u, ToMockFenceOnCompletion, this + 2); - - mMapReadBuffer.MapAsync(wgpu::MapMode::Read, 0, 0, ToMockMapCallback, this); - queue.Signal(fence, 6); - fence.OnCompletion(3u, ToMockFenceOnCompletion, this + 3); - fence.OnCompletion(5u, ToMockFenceOnCompletion, this + 5); - fence.OnCompletion(6u, ToMockFenceOnCompletion, this + 6); - - queue.Signal(fence, 8); - fence.OnCompletion(8u, ToMockFenceOnCompletion, this + 8); - - WaitForAllOperations(); - mMapReadBuffer.Unmap(); -} - DAWN_INSTANTIATE_TEST(QueueTimelineTests, D3D12Backend(), MetalBackend(), diff --git a/src/tests/unittests/validation/ErrorScopeValidationTests.cpp b/src/tests/unittests/validation/ErrorScopeValidationTests.cpp index 85ae37b30a..0feb805cf4 100644 --- a/src/tests/unittests/validation/ErrorScopeValidationTests.cpp +++ b/src/tests/unittests/validation/ErrorScopeValidationTests.cpp @@ -31,11 +31,22 @@ static void ToMockDevicePopErrorScopeCallback(WGPUErrorType type, mockDevicePopErrorScopeCallback->Call(type, message, userdata); } +class MockQueueWorkDoneCallback { + public: + MOCK_METHOD(void, Call, (WGPUQueueWorkDoneStatus status, void* userdata)); +}; + +static std::unique_ptr mockQueueWorkDoneCallback; +static void ToMockQueueWorkDone(WGPUQueueWorkDoneStatus status, void* userdata) { + mockQueueWorkDoneCallback->Call(status, userdata); +} + class ErrorScopeValidationTest : public ValidationTest { private: void SetUp() override { ValidationTest::SetUp(); mockDevicePopErrorScopeCallback = std::make_unique(); + mockQueueWorkDoneCallback = std::make_unique(); } void TearDown() override { @@ -43,6 +54,7 @@ class ErrorScopeValidationTest : public ValidationTest { // Delete mocks so that expectations are checked mockDevicePopErrorScopeCallback = nullptr; + mockQueueWorkDoneCallback = nullptr; } }; @@ -141,31 +153,6 @@ TEST_F(ErrorScopeValidationTest, PushPopBalanced) { } } -// Test that error scopes call their callbacks before an enclosed Queue::Submit -// completes -TEST_F(ErrorScopeValidationTest, EnclosedQueueSubmit) { - wgpu::Queue queue = device.GetQueue(); - - device.PushErrorScope(wgpu::ErrorFilter::OutOfMemory); - - queue.Submit(0, nullptr); - wgpu::Fence fence; - EXPECT_DEPRECATION_WARNING(fence = queue.CreateFence()); - queue.Signal(fence, 1); - - testing::Sequence seq; - - MockCallback fenceCallback; - fence.OnCompletion(1, fenceCallback.Callback(), fenceCallback.MakeUserdata(this)); - - MockCallback errorScopeCallback; - EXPECT_CALL(errorScopeCallback, Call(WGPUErrorType_NoError, _, this + 1)).InSequence(seq); - device.PopErrorScope(errorScopeCallback.Callback(), errorScopeCallback.MakeUserdata(this + 1)); - - EXPECT_CALL(fenceCallback, Call(WGPUFenceCompletionStatus_Success, this)).InSequence(seq); - WaitForAllOperations(device); -} - // Test that parent error scopes also call their callbacks before an enclosed Queue::Submit // completes TEST_F(ErrorScopeValidationTest, EnclosedQueueSubmitNested) { @@ -175,15 +162,10 @@ TEST_F(ErrorScopeValidationTest, EnclosedQueueSubmitNested) { device.PushErrorScope(wgpu::ErrorFilter::OutOfMemory); queue.Submit(0, nullptr); - wgpu::Fence fence; - EXPECT_DEPRECATION_WARNING(fence = queue.CreateFence()); - queue.Signal(fence, 1); + queue.OnSubmittedWorkDone(0u, ToMockQueueWorkDone, this); testing::Sequence seq; - MockCallback fenceCallback; - fence.OnCompletion(1, fenceCallback.Callback(), fenceCallback.MakeUserdata(this)); - MockCallback errorScopeCallback2; EXPECT_CALL(errorScopeCallback2, Call(WGPUErrorType_NoError, _, this + 1)).InSequence(seq); device.PopErrorScope(errorScopeCallback2.Callback(), @@ -194,7 +176,8 @@ TEST_F(ErrorScopeValidationTest, EnclosedQueueSubmitNested) { device.PopErrorScope(errorScopeCallback1.Callback(), errorScopeCallback1.MakeUserdata(this + 2)); - EXPECT_CALL(fenceCallback, Call(WGPUFenceCompletionStatus_Success, this)).InSequence(seq); + EXPECT_CALL(*mockQueueWorkDoneCallback, Call(WGPUQueueWorkDoneStatus_Success, this)) + .InSequence(seq); WaitForAllOperations(device); } diff --git a/src/tests/unittests/validation/FenceValidationTests.cpp b/src/tests/unittests/validation/FenceValidationTests.cpp deleted file mode 100644 index 639fd634e9..0000000000 --- a/src/tests/unittests/validation/FenceValidationTests.cpp +++ /dev/null @@ -1,235 +0,0 @@ -// Copyright 2018 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 "tests/unittests/validation/ValidationTest.h" - -#include - -using namespace testing; - -class MockFenceOnCompletionCallback { - public: - MOCK_METHOD(void, Call, (WGPUFenceCompletionStatus status, void* userdata)); -}; - -struct FenceOnCompletionExpectation { - wgpu::Fence fence; - uint64_t value; - WGPUFenceCompletionStatus status; -}; - -static std::unique_ptr mockFenceOnCompletionCallback; -static void ToMockFenceOnCompletion(WGPUFenceCompletionStatus status, void* userdata) { - mockFenceOnCompletionCallback->Call(status, userdata); -} - -class FenceValidationTest : public ValidationTest { - protected: - void TestOnCompletion(wgpu::Fence fence, uint64_t value, WGPUFenceCompletionStatus status) { - FenceOnCompletionExpectation* expectation = new FenceOnCompletionExpectation; - expectation->fence = fence; - expectation->value = value; - expectation->status = status; - - EXPECT_CALL(*mockFenceOnCompletionCallback, Call(status, expectation)).Times(1); - fence.OnCompletion(value, ToMockFenceOnCompletion, expectation); - } - - wgpu::Queue queue; - - private: - void SetUp() override { - ValidationTest::SetUp(); - - mockFenceOnCompletionCallback = std::make_unique(); - queue = device.GetQueue(); - } - - void TearDown() override { - // Delete mocks so that expectations are checked - mockFenceOnCompletionCallback = nullptr; - - ValidationTest::TearDown(); - } -}; - -// Test cases where creation should succeed -TEST_F(FenceValidationTest, CreationSuccess) { - // Success - { - wgpu::FenceDescriptor descriptor; - descriptor.initialValue = 0; - EXPECT_DEPRECATION_WARNING(queue.CreateFence(&descriptor)); - } -} - -// Creation succeeds if no descriptor is provided -TEST_F(FenceValidationTest, DefaultDescriptor) { - wgpu::Fence fence; - EXPECT_DEPRECATION_WARNING(fence = queue.CreateFence()); - EXPECT_EQ(fence.GetCompletedValue(), 0u); -} - -TEST_F(FenceValidationTest, GetCompletedValue) { - // Starts at initial value - { - wgpu::FenceDescriptor descriptor; - descriptor.initialValue = 1; - wgpu::Fence fence; - EXPECT_DEPRECATION_WARNING(fence = queue.CreateFence(&descriptor)); - EXPECT_EQ(fence.GetCompletedValue(), 1u); - } -} - -// Test that OnCompletion handlers are called immediately for -// already completed fence values -TEST_F(FenceValidationTest, OnCompletionImmediate) { - // TODO(crbug.com/dawn/653): This has wrong different behavior on the wire, but fences will be - // removed soon. - DAWN_SKIP_TEST_IF(UsesWire()); - - wgpu::FenceDescriptor descriptor; - descriptor.initialValue = 1; - wgpu::Fence fence; - EXPECT_DEPRECATION_WARNING(fence = queue.CreateFence(&descriptor)); - - EXPECT_CALL(*mockFenceOnCompletionCallback, Call(WGPUFenceCompletionStatus_Success, this + 0)) - .Times(1); - fence.OnCompletion(0u, ToMockFenceOnCompletion, this + 0); - - EXPECT_CALL(*mockFenceOnCompletionCallback, Call(WGPUFenceCompletionStatus_Success, this + 1)) - .Times(1); - fence.OnCompletion(1u, ToMockFenceOnCompletion, this + 1); -} - -// Test setting OnCompletion handlers for values > signaled value -TEST_F(FenceValidationTest, OnCompletionLargerThanSignaled) { - wgpu::FenceDescriptor descriptor; - descriptor.initialValue = 1; - wgpu::Fence fence; - EXPECT_DEPRECATION_WARNING(fence = queue.CreateFence(&descriptor)); - - // Cannot signal for values > signaled value - EXPECT_CALL(*mockFenceOnCompletionCallback, Call(WGPUFenceCompletionStatus_Error, nullptr)) - .Times(1); - ASSERT_DEVICE_ERROR(fence.OnCompletion(2u, ToMockFenceOnCompletion, nullptr)); - - // Can set handler after signaling - queue.Signal(fence, 2); - EXPECT_CALL(*mockFenceOnCompletionCallback, Call(WGPUFenceCompletionStatus_Success, nullptr)) - .Times(1); - fence.OnCompletion(2u, ToMockFenceOnCompletion, nullptr); - - WaitForAllOperations(device); -} - -TEST_F(FenceValidationTest, GetCompletedValueInsideCallback) { - // TODO(crbug.com/dawn/653): This has wrong different behavior on the wire, but fences will be - // removed soon. - DAWN_SKIP_TEST_IF(UsesWire()); - - wgpu::FenceDescriptor descriptor; - descriptor.initialValue = 1; - wgpu::Fence fence; - EXPECT_DEPRECATION_WARNING(fence = queue.CreateFence(&descriptor)); - - queue.Signal(fence, 3); - fence.OnCompletion(2u, ToMockFenceOnCompletion, nullptr); - EXPECT_CALL(*mockFenceOnCompletionCallback, Call(WGPUFenceCompletionStatus_Success, nullptr)) - .WillOnce(Invoke([&](WGPUFenceCompletionStatus status, void* userdata) { - EXPECT_EQ(fence.GetCompletedValue(), 3u); - })); - - WaitForAllOperations(device); -} - -TEST_F(FenceValidationTest, GetCompletedValueAfterCallback) { - wgpu::FenceDescriptor descriptor; - descriptor.initialValue = 1; - wgpu::Fence fence; - EXPECT_DEPRECATION_WARNING(fence = queue.CreateFence(&descriptor)); - - queue.Signal(fence, 2); - fence.OnCompletion(2u, ToMockFenceOnCompletion, nullptr); - EXPECT_CALL(*mockFenceOnCompletionCallback, Call(WGPUFenceCompletionStatus_Success, nullptr)) - .Times(1); - - WaitForAllOperations(device); - EXPECT_EQ(fence.GetCompletedValue(), 2u); -} - -TEST_F(FenceValidationTest, SignalError) { - wgpu::FenceDescriptor descriptor; - descriptor.initialValue = 1; - wgpu::Fence fence; - EXPECT_DEPRECATION_WARNING(fence = queue.CreateFence(&descriptor)); - - // value < fence signaled value - ASSERT_DEVICE_ERROR(queue.Signal(fence, 0)); - - // value == fence signaled value - ASSERT_DEVICE_ERROR(queue.Signal(fence, 1)); -} - -TEST_F(FenceValidationTest, SignalSuccess) { - wgpu::FenceDescriptor descriptor; - descriptor.initialValue = 1; - wgpu::Fence fence; - EXPECT_DEPRECATION_WARNING(fence = queue.CreateFence(&descriptor)); - - // Success - queue.Signal(fence, 2); - WaitForAllOperations(device); - EXPECT_EQ(fence.GetCompletedValue(), 2u); - - // Success increasing fence value by more than 1 - queue.Signal(fence, 6); - WaitForAllOperations(device); - EXPECT_EQ(fence.GetCompletedValue(), 6u); -} - -// Test it is invalid to signal a fence on a different queue than it was created on -// DISABLED until we have support for multiple queues -TEST_F(FenceValidationTest, DISABLED_SignalWrongQueue) { - wgpu::Queue queue2 = device.GetQueue(); - - wgpu::FenceDescriptor descriptor; - descriptor.initialValue = 1; - wgpu::Fence fence; - EXPECT_DEPRECATION_WARNING(fence = queue.CreateFence(&descriptor)); - - ASSERT_DEVICE_ERROR(queue2.Signal(fence, 2)); -} - -// Test that signaling a fence on a wrong queue does not update fence signaled value -// DISABLED until we have support for multiple queues -TEST_F(FenceValidationTest, DISABLED_SignalWrongQueueDoesNotUpdateValue) { - wgpu::Queue queue2 = device.GetQueue(); - - wgpu::FenceDescriptor descriptor; - descriptor.initialValue = 1; - wgpu::Fence fence; - EXPECT_DEPRECATION_WARNING(fence = queue.CreateFence(&descriptor)); - - ASSERT_DEVICE_ERROR(queue2.Signal(fence, 2)); - - // Fence value should be unchanged. - WaitForAllOperations(device); - EXPECT_EQ(fence.GetCompletedValue(), 1u); - - // Signaling with 2 on the correct queue should succeed - queue.Signal(fence, 2); - WaitForAllOperations(device); - EXPECT_EQ(fence.GetCompletedValue(), 2u); -} diff --git a/src/tests/unittests/wire/WireFenceTests.cpp b/src/tests/unittests/wire/WireFenceTests.cpp deleted file mode 100644 index b573345093..0000000000 --- a/src/tests/unittests/wire/WireFenceTests.cpp +++ /dev/null @@ -1,268 +0,0 @@ -// 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 "tests/unittests/wire/WireTest.h" - -#include "dawn_wire/WireClient.h" - -using namespace testing; -using namespace dawn_wire; - -namespace { - - class MockFenceOnCompletionCallback { - public: - MOCK_METHOD(void, Call, (WGPUFenceCompletionStatus status, void* userdata)); - }; - - std::unique_ptr> mockFenceOnCompletionCallback; - void ToMockFenceOnCompletion(WGPUFenceCompletionStatus status, void* userdata) { - mockFenceOnCompletionCallback->Call(status, userdata); - } - -} // anonymous namespace - -class WireFenceTests : public WireTest { - public: - WireFenceTests() { - } - ~WireFenceTests() override = default; - - void SetUp() override { - WireTest::SetUp(); - - mockFenceOnCompletionCallback = - std::make_unique>(); - - { - WGPUFenceDescriptor descriptor = {}; - descriptor.initialValue = 1; - - apiFence = api.GetNewFence(); - fence = wgpuQueueCreateFence(queue, &descriptor); - - EXPECT_CALL(api, QueueCreateFence(apiQueue, _)).WillOnce(Return(apiFence)); - FlushClient(); - } - } - - void TearDown() override { - WireTest::TearDown(); - - mockFenceOnCompletionCallback = nullptr; - } - - void FlushServer() { - WireTest::FlushServer(); - - Mock::VerifyAndClearExpectations(&mockFenceOnCompletionCallback); - } - - protected: - void DoQueueSignal(uint64_t signalValue, - WGPUFenceCompletionStatus status = WGPUFenceCompletionStatus_Success) { - wgpuQueueSignal(queue, fence, signalValue); - EXPECT_CALL(api, QueueSignal(apiQueue, apiFence, signalValue)).Times(1); - - // This callback is generated to update the completedValue of the fence - // on the client - EXPECT_CALL(api, OnFenceOnCompletion(apiFence, signalValue, _, _)) - .WillOnce( - InvokeWithoutArgs([=]() { api.CallFenceOnCompletionCallback(apiFence, status); })) - .RetiresOnSaturation(); - } - - // A successfully created fence - WGPUFence fence; - WGPUFence apiFence; -}; - -// Check that signaling a fence succeeds -TEST_F(WireFenceTests, QueueSignalSuccess) { - DoQueueSignal(2u); - FlushClient(); - FlushServer(); - - EXPECT_EQ(wgpuFenceGetCompletedValue(fence), 2u); -} - -// Check that signaling a fence twice succeeds -TEST_F(WireFenceTests, QueueSignalIncreasing) { - DoQueueSignal(2u); - DoQueueSignal(3u); - FlushClient(); - FlushServer(); - - EXPECT_EQ(wgpuFenceGetCompletedValue(fence), 3u); -} - -// Check that an error in queue signal does not update the completed value. -TEST_F(WireFenceTests, QueueSignalValidationError) { - DoQueueSignal(2u); - DoQueueSignal(1u, WGPUFenceCompletionStatus_Error); - FlushClient(); - FlushServer(); - - // Value should stay at 2 and not be updated to 1. - EXPECT_EQ(wgpuFenceGetCompletedValue(fence), 2u); -} - -// Check that a success in the on completion callback is forwarded to the client. -TEST_F(WireFenceTests, OnCompletionSuccess) { - wgpuFenceOnCompletion(fence, 0, ToMockFenceOnCompletion, nullptr); - EXPECT_CALL(api, OnFenceOnCompletion(apiFence, 0u, _, _)).WillOnce(InvokeWithoutArgs([&]() { - api.CallFenceOnCompletionCallback(apiFence, WGPUFenceCompletionStatus_Success); - })); - FlushClient(); - - EXPECT_CALL(*mockFenceOnCompletionCallback, Call(WGPUFenceCompletionStatus_Success, _)) - .Times(1); - FlushServer(); -} - -// Check that an error in the on completion callback is forwarded to the client. -TEST_F(WireFenceTests, OnCompletionError) { - wgpuFenceOnCompletion(fence, 0, ToMockFenceOnCompletion, nullptr); - EXPECT_CALL(api, OnFenceOnCompletion(apiFence, 0u, _, _)).WillOnce(InvokeWithoutArgs([&]() { - api.CallFenceOnCompletionCallback(apiFence, WGPUFenceCompletionStatus_Error); - })); - FlushClient(); - - EXPECT_CALL(*mockFenceOnCompletionCallback, Call(WGPUFenceCompletionStatus_Error, _)).Times(1); - FlushServer(); -} - -// Test that registering a callback then wire disconnect calls the callback with -// DeviceLost. -TEST_F(WireFenceTests, OnCompletionThenDisconnect) { - wgpuFenceOnCompletion(fence, 0, ToMockFenceOnCompletion, this); - EXPECT_CALL(api, OnFenceOnCompletion(apiFence, 0u, _, _)).WillOnce(InvokeWithoutArgs([&]() { - api.CallFenceOnCompletionCallback(apiFence, WGPUFenceCompletionStatus_Success); - })); - FlushClient(); - - EXPECT_CALL(*mockFenceOnCompletionCallback, Call(WGPUFenceCompletionStatus_DeviceLost, this)) - .Times(1); - GetWireClient()->Disconnect(); -} - -// Test that registering a callback after wire disconnect calls the callback with -// DeviceLost. -TEST_F(WireFenceTests, OnCompletionAfterDisconnect) { - GetWireClient()->Disconnect(); - - EXPECT_CALL(*mockFenceOnCompletionCallback, Call(WGPUFenceCompletionStatus_DeviceLost, this)) - .Times(1); - wgpuFenceOnCompletion(fence, 0, ToMockFenceOnCompletion, this); -} - -// Without any flushes, it is valid to wait on a value less than or equal to -// the last signaled value -TEST_F(WireFenceTests, OnCompletionSynchronousValidationSuccess) { - wgpuQueueSignal(queue, fence, 4u); - wgpuFenceOnCompletion(fence, 2u, ToMockFenceOnCompletion, 0); - wgpuFenceOnCompletion(fence, 3u, ToMockFenceOnCompletion, 0); - wgpuFenceOnCompletion(fence, 4u, ToMockFenceOnCompletion, 0); - - EXPECT_CALL(*mockFenceOnCompletionCallback, Call(WGPUFenceCompletionStatus_Unknown, _)) - .Times(3); -} - -// Check that the fence completed value is initialized -TEST_F(WireFenceTests, GetCompletedValueInitialization) { - EXPECT_EQ(wgpuFenceGetCompletedValue(fence), 1u); -} - -// Check that the fence completed value updates after signaling the fence -TEST_F(WireFenceTests, GetCompletedValueUpdate) { - DoQueueSignal(3u); - FlushClient(); - FlushServer(); - - EXPECT_EQ(wgpuFenceGetCompletedValue(fence), 3u); -} - -// Check that the fence completed value updates after signaling the fence -TEST_F(WireFenceTests, GetCompletedValueUpdateInCallback) { - // Signal the fence - DoQueueSignal(3u); - - // Register the callback - wgpuFenceOnCompletion(fence, 3u, ToMockFenceOnCompletion, this); - EXPECT_CALL(api, OnFenceOnCompletion(apiFence, 3u, _, _)) - .WillOnce(InvokeWithoutArgs([&]() { - api.CallFenceOnCompletionCallback(apiFence, WGPUFenceCompletionStatus_Success); - })) - .RetiresOnSaturation(); - - FlushClient(); - - EXPECT_CALL(*mockFenceOnCompletionCallback, Call(WGPUFenceCompletionStatus_Success, this)) - .WillOnce(InvokeWithoutArgs([&]() { EXPECT_EQ(wgpuFenceGetCompletedValue(fence), 3u); })); - FlushServer(); -} - -// Check that the fence completed value does not update without a flush -TEST_F(WireFenceTests, GetCompletedValueNoUpdate) { - wgpuQueueSignal(queue, fence, 3u); - EXPECT_EQ(wgpuFenceGetCompletedValue(fence), 1u); -} - -// Check that the callback is called with UNKNOWN when the fence is destroyed -// before the completed value is updated -TEST_F(WireFenceTests, DestroyBeforeOnCompletionEnd) { - wgpuQueueSignal(queue, fence, 3u); - wgpuFenceOnCompletion(fence, 2u, ToMockFenceOnCompletion, nullptr); - EXPECT_CALL(*mockFenceOnCompletionCallback, Call(WGPUFenceCompletionStatus_Unknown, _)) - .Times(1); -} - -// Test that signaling a fence on a wrong queue is invalid -// DISABLED until we have support for multiple queues. -TEST_F(WireFenceTests, DISABLED_SignalWrongQueue) { - WGPUQueue queue2 = wgpuDeviceGetQueue(device); - WGPUQueue apiQueue2 = api.GetNewQueue(); - EXPECT_CALL(api, DeviceGetQueue(apiDevice)).WillOnce(Return(apiQueue2)); - FlushClient(); - - wgpuQueueSignal(queue2, fence, 2u); // error - EXPECT_CALL(api, DeviceInjectError(apiDevice, WGPUErrorType_Validation, ValidStringMessage())) - .Times(1); - FlushClient(); -} - -// Test that signaling a fence on a wrong queue does not update fence signaled value -// DISABLED until we have support for multiple queues. -TEST_F(WireFenceTests, DISABLED_SignalWrongQueueDoesNotUpdateValue) { - WGPUQueue queue2 = wgpuDeviceGetQueue(device); - WGPUQueue apiQueue2 = api.GetNewQueue(); - EXPECT_CALL(api, DeviceGetQueue(apiDevice)).WillOnce(Return(apiQueue2)); - FlushClient(); - - wgpuQueueSignal(queue2, fence, 2u); // error - EXPECT_CALL(api, DeviceInjectError(apiDevice, WGPUErrorType_Validation, ValidStringMessage())) - .Times(1); - FlushClient(); - - // Fence value should be unchanged. - FlushClient(); - FlushServer(); - EXPECT_EQ(wgpuFenceGetCompletedValue(fence), 1u); - - // Signaling with 2 on the correct queue should succeed - DoQueueSignal(2u); // success - FlushClient(); - FlushServer(); - EXPECT_EQ(wgpuFenceGetCompletedValue(fence), 2u); -}