• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 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/CreatePipelineAsyncTask.h"
16 
17 #include "dawn_native/AsyncTask.h"
18 #include "dawn_native/ComputePipeline.h"
19 #include "dawn_native/Device.h"
20 #include "dawn_native/RenderPipeline.h"
21 #include "dawn_platform/DawnPlatform.h"
22 #include "dawn_platform/tracing/TraceEvent.h"
23 #include "utils/WGPUHelpers.h"
24 
25 namespace dawn_native {
26 
CreatePipelineAsyncCallbackTaskBase(std::string errorMessage,void * userdata)27     CreatePipelineAsyncCallbackTaskBase::CreatePipelineAsyncCallbackTaskBase(
28         std::string errorMessage,
29         void* userdata)
30         : mErrorMessage(errorMessage), mUserData(userdata) {
31     }
32 
CreateComputePipelineAsyncCallbackTask(Ref<ComputePipelineBase> pipeline,std::string errorMessage,WGPUCreateComputePipelineAsyncCallback callback,void * userdata)33     CreateComputePipelineAsyncCallbackTask::CreateComputePipelineAsyncCallbackTask(
34         Ref<ComputePipelineBase> pipeline,
35         std::string errorMessage,
36         WGPUCreateComputePipelineAsyncCallback callback,
37         void* userdata)
38         : CreatePipelineAsyncCallbackTaskBase(errorMessage, userdata),
39           mPipeline(std::move(pipeline)),
40           mCreateComputePipelineAsyncCallback(callback) {
41     }
42 
Finish()43     void CreateComputePipelineAsyncCallbackTask::Finish() {
44         ASSERT(mCreateComputePipelineAsyncCallback != nullptr);
45 
46         if (mPipeline.Get() != nullptr) {
47             mCreateComputePipelineAsyncCallback(WGPUCreatePipelineAsyncStatus_Success,
48                                                 ToAPI(mPipeline.Detach()), "", mUserData);
49         } else {
50             mCreateComputePipelineAsyncCallback(WGPUCreatePipelineAsyncStatus_Error, nullptr,
51                                                 mErrorMessage.c_str(), mUserData);
52         }
53     }
54 
HandleShutDown()55     void CreateComputePipelineAsyncCallbackTask::HandleShutDown() {
56         ASSERT(mCreateComputePipelineAsyncCallback != nullptr);
57 
58         mCreateComputePipelineAsyncCallback(WGPUCreatePipelineAsyncStatus_DeviceDestroyed, nullptr,
59                                             "Device destroyed before callback", mUserData);
60     }
61 
HandleDeviceLoss()62     void CreateComputePipelineAsyncCallbackTask::HandleDeviceLoss() {
63         ASSERT(mCreateComputePipelineAsyncCallback != nullptr);
64 
65         mCreateComputePipelineAsyncCallback(WGPUCreatePipelineAsyncStatus_DeviceLost, nullptr,
66                                             "Device lost before callback", mUserData);
67     }
68 
CreateRenderPipelineAsyncCallbackTask(Ref<RenderPipelineBase> pipeline,std::string errorMessage,WGPUCreateRenderPipelineAsyncCallback callback,void * userdata)69     CreateRenderPipelineAsyncCallbackTask::CreateRenderPipelineAsyncCallbackTask(
70         Ref<RenderPipelineBase> pipeline,
71         std::string errorMessage,
72         WGPUCreateRenderPipelineAsyncCallback callback,
73         void* userdata)
74         : CreatePipelineAsyncCallbackTaskBase(errorMessage, userdata),
75           mPipeline(std::move(pipeline)),
76           mCreateRenderPipelineAsyncCallback(callback) {
77     }
78 
Finish()79     void CreateRenderPipelineAsyncCallbackTask::Finish() {
80         ASSERT(mCreateRenderPipelineAsyncCallback != nullptr);
81 
82         if (mPipeline.Get() != nullptr) {
83             mCreateRenderPipelineAsyncCallback(WGPUCreatePipelineAsyncStatus_Success,
84                                                ToAPI(mPipeline.Detach()), "", mUserData);
85         } else {
86             mCreateRenderPipelineAsyncCallback(WGPUCreatePipelineAsyncStatus_Error, nullptr,
87                                                mErrorMessage.c_str(), mUserData);
88         }
89     }
90 
HandleShutDown()91     void CreateRenderPipelineAsyncCallbackTask::HandleShutDown() {
92         ASSERT(mCreateRenderPipelineAsyncCallback != nullptr);
93 
94         mCreateRenderPipelineAsyncCallback(WGPUCreatePipelineAsyncStatus_DeviceDestroyed, nullptr,
95                                            "Device destroyed before callback", mUserData);
96     }
97 
HandleDeviceLoss()98     void CreateRenderPipelineAsyncCallbackTask::HandleDeviceLoss() {
99         ASSERT(mCreateRenderPipelineAsyncCallback != nullptr);
100 
101         mCreateRenderPipelineAsyncCallback(WGPUCreatePipelineAsyncStatus_DeviceLost, nullptr,
102                                            "Device lost before callback", mUserData);
103     }
104 
CreateComputePipelineAsyncTask(Ref<ComputePipelineBase> nonInitializedComputePipeline,WGPUCreateComputePipelineAsyncCallback callback,void * userdata)105     CreateComputePipelineAsyncTask::CreateComputePipelineAsyncTask(
106         Ref<ComputePipelineBase> nonInitializedComputePipeline,
107         WGPUCreateComputePipelineAsyncCallback callback,
108         void* userdata)
109         : mComputePipeline(std::move(nonInitializedComputePipeline)),
110           mCallback(callback),
111           mUserdata(userdata) {
112         ASSERT(mComputePipeline != nullptr);
113     }
114 
Run()115     void CreateComputePipelineAsyncTask::Run() {
116         const char* eventLabel = utils::GetLabelForTrace(mComputePipeline->GetLabel().c_str());
117         TRACE_EVENT_FLOW_END1(mComputePipeline->GetDevice()->GetPlatform(), General,
118                               "CreateComputePipelineAsyncTask::RunAsync", this, "label",
119                               eventLabel);
120         TRACE_EVENT1(mComputePipeline->GetDevice()->GetPlatform(), General,
121                      "CreateComputePipelineAsyncTask::Run", "label", eventLabel);
122 
123         MaybeError maybeError = mComputePipeline->Initialize();
124         std::string errorMessage;
125         if (maybeError.IsError()) {
126             mComputePipeline = nullptr;
127             errorMessage = maybeError.AcquireError()->GetMessage();
128         }
129 
130         mComputePipeline->GetDevice()->AddComputePipelineAsyncCallbackTask(
131             mComputePipeline, errorMessage, mCallback, mUserdata);
132     }
133 
RunAsync(std::unique_ptr<CreateComputePipelineAsyncTask> task)134     void CreateComputePipelineAsyncTask::RunAsync(
135         std::unique_ptr<CreateComputePipelineAsyncTask> task) {
136         DeviceBase* device = task->mComputePipeline->GetDevice();
137 
138         const char* eventLabel =
139             utils::GetLabelForTrace(task->mComputePipeline->GetLabel().c_str());
140 
141         // Using "taskPtr = std::move(task)" causes compilation error while it should be supported
142         // since C++14:
143         // https://docs.microsoft.com/en-us/cpp/cpp/lambda-expressions-in-cpp?view=msvc-160
144         auto asyncTask = [taskPtr = task.release()] {
145             std::unique_ptr<CreateComputePipelineAsyncTask> innnerTaskPtr(taskPtr);
146             innnerTaskPtr->Run();
147         };
148 
149         TRACE_EVENT_FLOW_BEGIN1(device->GetPlatform(), General,
150                                 "CreateComputePipelineAsyncTask::RunAsync", task.get(), "label",
151                                 eventLabel);
152         device->GetAsyncTaskManager()->PostTask(std::move(asyncTask));
153     }
154 
CreateRenderPipelineAsyncTask(Ref<RenderPipelineBase> nonInitializedRenderPipeline,WGPUCreateRenderPipelineAsyncCallback callback,void * userdata)155     CreateRenderPipelineAsyncTask::CreateRenderPipelineAsyncTask(
156         Ref<RenderPipelineBase> nonInitializedRenderPipeline,
157         WGPUCreateRenderPipelineAsyncCallback callback,
158         void* userdata)
159         : mRenderPipeline(std::move(nonInitializedRenderPipeline)),
160           mCallback(callback),
161           mUserdata(userdata) {
162         ASSERT(mRenderPipeline != nullptr);
163     }
164 
Run()165     void CreateRenderPipelineAsyncTask::Run() {
166         const char* eventLabel = utils::GetLabelForTrace(mRenderPipeline->GetLabel().c_str());
167         TRACE_EVENT_FLOW_END1(mRenderPipeline->GetDevice()->GetPlatform(), General,
168                               "CreateRenderPipelineAsyncTask::RunAsync", this, "label", eventLabel);
169         TRACE_EVENT1(mRenderPipeline->GetDevice()->GetPlatform(), General,
170                      "CreateRenderPipelineAsyncTask::Run", "label", eventLabel);
171 
172         MaybeError maybeError = mRenderPipeline->Initialize();
173         std::string errorMessage;
174         if (maybeError.IsError()) {
175             mRenderPipeline = nullptr;
176             errorMessage = maybeError.AcquireError()->GetMessage();
177         }
178 
179         mRenderPipeline->GetDevice()->AddRenderPipelineAsyncCallbackTask(
180             mRenderPipeline, errorMessage, mCallback, mUserdata);
181     }
182 
RunAsync(std::unique_ptr<CreateRenderPipelineAsyncTask> task)183     void CreateRenderPipelineAsyncTask::RunAsync(
184         std::unique_ptr<CreateRenderPipelineAsyncTask> task) {
185         DeviceBase* device = task->mRenderPipeline->GetDevice();
186 
187         const char* eventLabel = utils::GetLabelForTrace(task->mRenderPipeline->GetLabel().c_str());
188 
189         // Using "taskPtr = std::move(task)" causes compilation error while it should be supported
190         // since C++14:
191         // https://docs.microsoft.com/en-us/cpp/cpp/lambda-expressions-in-cpp?view=msvc-160
192         auto asyncTask = [taskPtr = task.release()] {
193             std::unique_ptr<CreateRenderPipelineAsyncTask> innerTaskPtr(taskPtr);
194             innerTaskPtr->Run();
195         };
196 
197         TRACE_EVENT_FLOW_BEGIN1(device->GetPlatform(), General,
198                                 "CreateRenderPipelineAsyncTask::RunAsync", task.get(), "label",
199                                 eventLabel);
200         device->GetAsyncTaskManager()->PostTask(std::move(asyncTask));
201     }
202 }  // namespace dawn_native
203