• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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