Flutter Engine
The Flutter Engine
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 fSubmittedWorkDoneFuture = queueManager->dawnQueue().OnSubmittedWorkDone(
79 wgpu::CallbackMode::WaitAnyOnly, [](wgpu::QueueWorkDoneStatus) {});
80}
81
82bool DawnWorkSubmissionWithFuture::onIsFinished(const SharedContext* sharedContext) {
83 wgpu::FutureWaitInfo waitInfo{};
84 waitInfo.future = fSubmittedWorkDoneFuture;
85 const auto& instance = static_cast<const DawnSharedContext*>(sharedContext)
86 ->device()
87 .GetAdapter()
88 .GetInstance();
89 if (instance.WaitAny(1, &waitInfo, /*timeoutNS=*/0) != wgpu::WaitStatus::Success) {
90 return false;
91 }
92
93 return waitInfo.completed;
94}
95
96void DawnWorkSubmissionWithFuture::onWaitUntilFinished(const SharedContext* sharedContext) {
97 wgpu::FutureWaitInfo waitInfo{};
98 waitInfo.future = fSubmittedWorkDoneFuture;
99 const auto& instance = static_cast<const DawnSharedContext*>(sharedContext)
100 ->device()
101 .GetAdapter()
102 .GetInstance();
103 [[maybe_unused]] auto status =
104 instance.WaitAny(1, &waitInfo, /*timeoutNS=*/std::numeric_limits<uint64_t>::max());
105 SkASSERT(status == wgpu::WaitStatus::Success);
106 SkASSERT(waitInfo.completed);
107}
108
109#endif // !defined(__EMSCRIPTEN__)
110
111} // namespace
112
113DawnQueueManager::DawnQueueManager(wgpu::Queue queue, const SharedContext* sharedContext)
114 : QueueManager(sharedContext), fQueue(std::move(queue)) {}
115
116void DawnQueueManager::tick() const { this->dawnSharedContext()->tick(); }
117
118const DawnSharedContext* DawnQueueManager::dawnSharedContext() const {
119 return static_cast<const DawnSharedContext*>(fSharedContext);
120}
121
122std::unique_ptr<CommandBuffer> DawnQueueManager::getNewCommandBuffer(
123 ResourceProvider* resourceProvider) {
124 return DawnCommandBuffer::Make(dawnSharedContext(),
125 static_cast<DawnResourceProvider*>(resourceProvider));
126}
127
128QueueManager::OutstandingSubmission DawnQueueManager::onSubmitToGpu() {
130 DawnCommandBuffer* dawnCmdBuffer = static_cast<DawnCommandBuffer*>(fCurrentCommandBuffer.get());
131 auto wgpuCmdBuffer = dawnCmdBuffer->finishEncoding();
132 if (!wgpuCmdBuffer) {
133 fCurrentCommandBuffer->callFinishedProcs(/*success=*/false);
134 return nullptr;
135 }
136
137 fQueue.Submit(/*commandCount=*/1, &wgpuCmdBuffer);
138
139#if defined(__EMSCRIPTEN__)
140 return std::make_unique<DawnWorkSubmissionWithAsyncWait>(
141 std::move(fCurrentCommandBuffer), this, dawnSharedContext());
142#else
143 return std::make_unique<DawnWorkSubmissionWithFuture>(std::move(fCurrentCommandBuffer), this);
144#endif
145}
146
147#if defined(GRAPHITE_TEST_UTILS)
148void DawnQueueManager::startCapture() {
149 // TODO: Dawn doesn't have capturing feature yet.
150}
151
152void DawnQueueManager::stopCapture() {
153 // TODO: Dawn doesn't have capturing feature yet.
154}
155#endif
156
157} // namespace skgpu::graphite
#define SkASSERT(cond)
Definition: SkAssert.h:116
static std::unique_ptr< DawnCommandBuffer > Make(const DawnSharedContext *, DawnResourceProvider *)
const SharedContext * fSharedContext
Definition: QueueManager.h:67
std::unique_ptr< GpuWorkSubmission > OutstandingSubmission
Definition: QueueManager.h:65
std::unique_ptr< CommandBuffer > fCurrentCommandBuffer
Definition: QueueManager.h:68
VkDevice device
Definition: main.cc:53
VkInstance instance
Definition: main.cc:48
VkQueue queue
Definition: main.cc:55
static float max(float r, float g, float b)
Definition: hsl.cpp:49
Definition: ref_ptr.h:256