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