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