Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
DawnQueueManager.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2022 Google LLC
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
9
15
16namespace skgpu::graphite {
17namespace {
18// GpuWorkSubmission with AsyncWait. This is useful for wasm where wgpu::Future
19// is not available yet.
20class [[maybe_unused]] DawnWorkSubmissionWithAsyncWait final : public GpuWorkSubmission {
21public:
22 DawnWorkSubmissionWithAsyncWait(std::unique_ptr<CommandBuffer> cmdBuffer,
23 DawnQueueManager* queueManager,
24 const DawnSharedContext* sharedContext);
25
26private:
27 bool onIsFinished(const SharedContext* sharedContext) override;
28 void onWaitUntilFinished(const SharedContext* sharedContext) override;
29
30 DawnAsyncWait fAsyncWait;
31};
32
33DawnWorkSubmissionWithAsyncWait::DawnWorkSubmissionWithAsyncWait(
34 std::unique_ptr<CommandBuffer> cmdBuffer,
35 DawnQueueManager* queueManager,
36 const DawnSharedContext* sharedContext)
37 : GpuWorkSubmission(std::move(cmdBuffer), queueManager), fAsyncWait(sharedContext) {
38 queueManager->dawnQueue().OnSubmittedWorkDone(
39#if defined(__EMSCRIPTEN__)
40 // This is parameter is being removed:
41 // https://github.com/webgpu-native/webgpu-headers/issues/130
42 /*signalValue=*/0,
43#endif
44 [](WGPUQueueWorkDoneStatus, void* userData) {
45 auto asyncWaitPtr = static_cast<DawnAsyncWait*>(userData);
46 asyncWaitPtr->signal();
47 },
48 &fAsyncWait);
49}
50
51bool DawnWorkSubmissionWithAsyncWait::onIsFinished(const SharedContext*) {
52 return fAsyncWait.yieldAndCheck();
53}
54
55void DawnWorkSubmissionWithAsyncWait::onWaitUntilFinished(const SharedContext*) {
56 fAsyncWait.busyWait();
57}
58
59#if !defined(__EMSCRIPTEN__)
60
61// The version with wgpu::Future. This is not available in wasm yet so we have
62// to guard behind #if
63class DawnWorkSubmissionWithFuture final : public GpuWorkSubmission {
64public:
65 DawnWorkSubmissionWithFuture(std::unique_ptr<CommandBuffer> cmdBuffer,
66 DawnQueueManager* queueManager);
67
68private:
69 bool onIsFinished(const SharedContext* sharedContext) override;
70 void onWaitUntilFinished(const SharedContext* sharedContext) override;
71
72 wgpu::Future fSubmittedWorkDoneFuture;
73};
74
75DawnWorkSubmissionWithFuture::DawnWorkSubmissionWithFuture(std::unique_ptr<CommandBuffer> cmdBuffer,
76 DawnQueueManager* queueManager)
77 : GpuWorkSubmission(std::move(cmdBuffer), queueManager) {
78 wgpu::QueueWorkDoneCallbackInfo callbackInfo{};
79 callbackInfo.mode = wgpu::CallbackMode::WaitAnyOnly;
80 callbackInfo.callback = [](WGPUQueueWorkDoneStatus, void*) {};
81
82 fSubmittedWorkDoneFuture = queueManager->dawnQueue().OnSubmittedWorkDone(callbackInfo);
83}
84
85bool DawnWorkSubmissionWithFuture::onIsFinished(const SharedContext* sharedContext) {
86 wgpu::FutureWaitInfo waitInfo{};
87 waitInfo.future = fSubmittedWorkDoneFuture;
88 const auto& instance = static_cast<const DawnSharedContext*>(sharedContext)
89 ->device()
90 .GetAdapter()
91 .GetInstance();
92 if (instance.WaitAny(1, &waitInfo, /*timeoutNS=*/0) != wgpu::WaitStatus::Success) {
93 return false;
94 }
95
96 return waitInfo.completed;
97}
98
99void DawnWorkSubmissionWithFuture::onWaitUntilFinished(const SharedContext* sharedContext) {
100 wgpu::FutureWaitInfo waitInfo{};
101 waitInfo.future = fSubmittedWorkDoneFuture;
102 const auto& instance = static_cast<const DawnSharedContext*>(sharedContext)
103 ->device()
104 .GetAdapter()
105 .GetInstance();
106 [[maybe_unused]] auto status =
107 instance.WaitAny(1, &waitInfo, /*timeoutNS=*/std::numeric_limits<uint64_t>::max());
108 SkASSERT(status == wgpu::WaitStatus::Success);
109 SkASSERT(waitInfo.completed);
110}
111
112#endif // !defined(__EMSCRIPTEN__)
113
114} // namespace
115
116DawnQueueManager::DawnQueueManager(wgpu::Queue queue, const SharedContext* sharedContext)
117 : QueueManager(sharedContext), fQueue(std::move(queue)) {}
118
119void DawnQueueManager::tick() const { this->dawnSharedContext()->tick(); }
120
121const DawnSharedContext* DawnQueueManager::dawnSharedContext() const {
122 return static_cast<const DawnSharedContext*>(fSharedContext);
123}
124
125std::unique_ptr<CommandBuffer> DawnQueueManager::getNewCommandBuffer(
126 ResourceProvider* resourceProvider) {
127 return DawnCommandBuffer::Make(dawnSharedContext(),
128 static_cast<DawnResourceProvider*>(resourceProvider));
129}
130
133 DawnCommandBuffer* dawnCmdBuffer = static_cast<DawnCommandBuffer*>(fCurrentCommandBuffer.get());
134 auto wgpuCmdBuffer = dawnCmdBuffer->finishEncoding();
135 if (!wgpuCmdBuffer) {
136 fCurrentCommandBuffer->callFinishedProcs(/*success=*/false);
137 return nullptr;
138 }
139
140 fQueue.Submit(/*commandCount=*/1, &wgpuCmdBuffer);
141
142#if defined(__EMSCRIPTEN__)
143 return std::make_unique<DawnWorkSubmissionWithAsyncWait>(
144 std::move(fCurrentCommandBuffer), this, dawnSharedContext());
145#else
146 return std::make_unique<DawnWorkSubmissionWithFuture>(std::move(fCurrentCommandBuffer), this);
147#endif
148}
149
150#if defined(GRAPHITE_TEST_UTILS)
151void DawnQueueManager::startCapture() {
152 // TODO: Dawn doesn't have capturing feature yet.
153}
154
155void DawnQueueManager::stopCapture() {
156 // TODO: Dawn doesn't have capturing feature yet.
157}
158#endif
159
160} // namespace skgpu::graphite
#define SkASSERT(cond)
Definition SkAssert.h:116
static std::unique_ptr< DawnCommandBuffer > Make(const DawnSharedContext *, DawnResourceProvider *)
std::unique_ptr< CommandBuffer > getNewCommandBuffer(ResourceProvider *) override
OutstandingSubmission onSubmitToGpu() override
const SharedContext * fSharedContext
std::unique_ptr< GpuWorkSubmission > OutstandingSubmission
std::unique_ptr< CommandBuffer > fCurrentCommandBuffer
VkDevice device
Definition main.cc:53
VkInstance instance
Definition main.cc:48
VkQueue queue
Definition main.cc:55
Definition ref_ptr.h:256