1 // Copyright 2018 The Dawn Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include "dawn_native/Fence.h" 16 17 #include "common/Assert.h" 18 #include "dawn_native/Device.h" 19 #include "dawn_native/Queue.h" 20 #include "dawn_native/ValidationUtils_autogen.h" 21 22 #include <utility> 23 24 namespace dawn_native { 25 ValidateFenceDescriptor(const FenceDescriptor * descriptor)26 MaybeError ValidateFenceDescriptor(const FenceDescriptor* descriptor) { 27 if (descriptor->nextInChain != nullptr) { 28 return DAWN_VALIDATION_ERROR("nextInChain must be nullptr"); 29 } 30 31 return {}; 32 } 33 34 // Fence 35 FenceBase(QueueBase * queue,const FenceDescriptor * descriptor)36 FenceBase::FenceBase(QueueBase* queue, const FenceDescriptor* descriptor) 37 : ObjectBase(queue->GetDevice()), 38 mSignalValue(descriptor->initialValue), 39 mCompletedValue(descriptor->initialValue), 40 mQueue(queue) { 41 } 42 FenceBase(DeviceBase * device,ObjectBase::ErrorTag tag)43 FenceBase::FenceBase(DeviceBase* device, ObjectBase::ErrorTag tag) : ObjectBase(device, tag) { 44 } 45 ~FenceBase()46 FenceBase::~FenceBase() { 47 for (auto& request : mRequests.IterateAll()) { 48 ASSERT(!IsError()); 49 request.completionCallback(DAWN_FENCE_COMPLETION_STATUS_UNKNOWN, request.userdata); 50 } 51 mRequests.Clear(); 52 } 53 54 // static MakeError(DeviceBase * device)55 FenceBase* FenceBase::MakeError(DeviceBase* device) { 56 return new FenceBase(device, ObjectBase::kError); 57 } 58 GetCompletedValue() const59 uint64_t FenceBase::GetCompletedValue() const { 60 if (IsError()) { 61 return 0; 62 } 63 return mCompletedValue; 64 } 65 OnCompletion(uint64_t value,dawn::FenceOnCompletionCallback callback,void * userdata)66 void FenceBase::OnCompletion(uint64_t value, 67 dawn::FenceOnCompletionCallback callback, 68 void* userdata) { 69 if (GetDevice()->ConsumedError(ValidateOnCompletion(value))) { 70 callback(DAWN_FENCE_COMPLETION_STATUS_ERROR, userdata); 71 return; 72 } 73 ASSERT(!IsError()); 74 75 if (value <= mCompletedValue) { 76 callback(DAWN_FENCE_COMPLETION_STATUS_SUCCESS, userdata); 77 return; 78 } 79 80 OnCompletionData request; 81 request.completionCallback = callback; 82 request.userdata = userdata; 83 mRequests.Enqueue(std::move(request), value); 84 } 85 GetSignaledValue() const86 uint64_t FenceBase::GetSignaledValue() const { 87 ASSERT(!IsError()); 88 return mSignalValue; 89 } 90 GetQueue() const91 const QueueBase* FenceBase::GetQueue() const { 92 ASSERT(!IsError()); 93 return mQueue.Get(); 94 } 95 SetSignaledValue(uint64_t signalValue)96 void FenceBase::SetSignaledValue(uint64_t signalValue) { 97 ASSERT(!IsError()); 98 ASSERT(signalValue > mSignalValue); 99 mSignalValue = signalValue; 100 } 101 SetCompletedValue(uint64_t completedValue)102 void FenceBase::SetCompletedValue(uint64_t completedValue) { 103 ASSERT(!IsError()); 104 ASSERT(completedValue <= mSignalValue); 105 ASSERT(completedValue > mCompletedValue); 106 mCompletedValue = completedValue; 107 108 for (auto& request : mRequests.IterateUpTo(mCompletedValue)) { 109 request.completionCallback(DAWN_FENCE_COMPLETION_STATUS_SUCCESS, request.userdata); 110 } 111 mRequests.ClearUpTo(mCompletedValue); 112 } 113 ValidateOnCompletion(uint64_t value) const114 MaybeError FenceBase::ValidateOnCompletion(uint64_t value) const { 115 DAWN_TRY(GetDevice()->ValidateObject(this)); 116 if (value > mSignalValue) { 117 return DAWN_VALIDATION_ERROR("Value greater than fence signaled value"); 118 } 119 return {}; 120 } 121 122 } // namespace dawn_native 123