xref: /aosp_15_r20/external/skia/src/gpu/graphite/task/ComputeTask.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/task/ComputeTask.h"
9*c8dee2aaSAndroid Build Coastguard Worker 
10*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/Buffer.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/CommandBuffer.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/ResourceProvider.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/compute/DispatchGroup.h"
14*c8dee2aaSAndroid Build Coastguard Worker 
15*c8dee2aaSAndroid Build Coastguard Worker namespace skgpu::graphite {
16*c8dee2aaSAndroid Build Coastguard Worker 
Make(DispatchGroupList dispatchGroups)17*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ComputeTask> ComputeTask::Make(DispatchGroupList dispatchGroups) {
18*c8dee2aaSAndroid Build Coastguard Worker     return sk_sp<ComputeTask>(new ComputeTask(std::move(dispatchGroups)));
19*c8dee2aaSAndroid Build Coastguard Worker }
20*c8dee2aaSAndroid Build Coastguard Worker 
ComputeTask(DispatchGroupList dispatchGroups)21*c8dee2aaSAndroid Build Coastguard Worker ComputeTask::ComputeTask(DispatchGroupList dispatchGroups)
22*c8dee2aaSAndroid Build Coastguard Worker         : fDispatchGroups(std::move(dispatchGroups)), fChildTasks(fDispatchGroups.size()) {
23*c8dee2aaSAndroid Build Coastguard Worker     for (auto& group : fDispatchGroups) {
24*c8dee2aaSAndroid Build Coastguard Worker         fChildTasks.push_back(group->snapChildTask());
25*c8dee2aaSAndroid Build Coastguard Worker     }
26*c8dee2aaSAndroid Build Coastguard Worker }
27*c8dee2aaSAndroid Build Coastguard Worker 
28*c8dee2aaSAndroid Build Coastguard Worker ComputeTask::~ComputeTask() = default;
29*c8dee2aaSAndroid Build Coastguard Worker 
prepareResources(ResourceProvider * provider,ScratchResourceManager * scratchManager,const RuntimeEffectDictionary * rtd)30*c8dee2aaSAndroid Build Coastguard Worker Task::Status ComputeTask::prepareResources(ResourceProvider* provider,
31*c8dee2aaSAndroid Build Coastguard Worker                                            ScratchResourceManager* scratchManager,
32*c8dee2aaSAndroid Build Coastguard Worker                                            const RuntimeEffectDictionary* rtd) {
33*c8dee2aaSAndroid Build Coastguard Worker     for (auto& child : fChildTasks) {
34*c8dee2aaSAndroid Build Coastguard Worker         if (child) {
35*c8dee2aaSAndroid Build Coastguard Worker             Status status = child->prepareResources(provider, scratchManager, rtd);
36*c8dee2aaSAndroid Build Coastguard Worker             if (status == Status::kFail) {
37*c8dee2aaSAndroid Build Coastguard Worker                 return Status::kFail;
38*c8dee2aaSAndroid Build Coastguard Worker             } else if (status == Status::kDiscard) {
39*c8dee2aaSAndroid Build Coastguard Worker                 child.reset();
40*c8dee2aaSAndroid Build Coastguard Worker             }
41*c8dee2aaSAndroid Build Coastguard Worker         }
42*c8dee2aaSAndroid Build Coastguard Worker     }
43*c8dee2aaSAndroid Build Coastguard Worker     for (const auto& group : fDispatchGroups) {
44*c8dee2aaSAndroid Build Coastguard Worker         // TODO: Allow ComputeTasks to instantiate with scratch textures and return them.
45*c8dee2aaSAndroid Build Coastguard Worker         if (!group->prepareResources(provider)) {
46*c8dee2aaSAndroid Build Coastguard Worker             return Status::kFail;
47*c8dee2aaSAndroid Build Coastguard Worker         }
48*c8dee2aaSAndroid Build Coastguard Worker     }
49*c8dee2aaSAndroid Build Coastguard Worker     return Status::kSuccess;
50*c8dee2aaSAndroid Build Coastguard Worker }
51*c8dee2aaSAndroid Build Coastguard Worker 
addCommands(Context * ctx,CommandBuffer * commandBuffer,ReplayTargetData rtd)52*c8dee2aaSAndroid Build Coastguard Worker Task::Status ComputeTask::addCommands(Context* ctx,
53*c8dee2aaSAndroid Build Coastguard Worker                                       CommandBuffer* commandBuffer,
54*c8dee2aaSAndroid Build Coastguard Worker                                       ReplayTargetData rtd) {
55*c8dee2aaSAndroid Build Coastguard Worker     if (fDispatchGroups.empty()) {
56*c8dee2aaSAndroid Build Coastguard Worker         return Status::kDiscard;
57*c8dee2aaSAndroid Build Coastguard Worker     }
58*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(fDispatchGroups.size() == fChildTasks.size());
59*c8dee2aaSAndroid Build Coastguard Worker     const std::unique_ptr<DispatchGroup>* currentSpanPtr = &fDispatchGroups[0];
60*c8dee2aaSAndroid Build Coastguard Worker     size_t currentSpanSize = 0u;
61*c8dee2aaSAndroid Build Coastguard Worker     for (int i = 0; i < fDispatchGroups.size(); ++i) {
62*c8dee2aaSAndroid Build Coastguard Worker         // If the next DispatchGroup has a dependent task, then encode the accumulated span as a
63*c8dee2aaSAndroid Build Coastguard Worker         // compute pass now. CommandBuffer encodes each compute pass with a separate encoder, so
64*c8dee2aaSAndroid Build Coastguard Worker         // the dependent task can use a non-compute encoder if needed.
65*c8dee2aaSAndroid Build Coastguard Worker         Task* child = fChildTasks[i].get();
66*c8dee2aaSAndroid Build Coastguard Worker         if (child) {
67*c8dee2aaSAndroid Build Coastguard Worker             if (currentSpanSize > 0u) {
68*c8dee2aaSAndroid Build Coastguard Worker                 if (!commandBuffer->addComputePass({currentSpanPtr, currentSpanSize})) {
69*c8dee2aaSAndroid Build Coastguard Worker                     return Status::kFail;
70*c8dee2aaSAndroid Build Coastguard Worker                 }
71*c8dee2aaSAndroid Build Coastguard Worker                 currentSpanPtr = &fDispatchGroups[i];
72*c8dee2aaSAndroid Build Coastguard Worker                 currentSpanSize = 0u;
73*c8dee2aaSAndroid Build Coastguard Worker             }
74*c8dee2aaSAndroid Build Coastguard Worker 
75*c8dee2aaSAndroid Build Coastguard Worker             Status status = child->addCommands(ctx, commandBuffer, rtd);
76*c8dee2aaSAndroid Build Coastguard Worker             if (status == Status::kFail) {
77*c8dee2aaSAndroid Build Coastguard Worker                 return Status::kFail;
78*c8dee2aaSAndroid Build Coastguard Worker             } else if (status == Status::kDiscard) {
79*c8dee2aaSAndroid Build Coastguard Worker                 fChildTasks[i].reset();
80*c8dee2aaSAndroid Build Coastguard Worker             }
81*c8dee2aaSAndroid Build Coastguard Worker         }
82*c8dee2aaSAndroid Build Coastguard Worker         currentSpanSize++;
83*c8dee2aaSAndroid Build Coastguard Worker     }
84*c8dee2aaSAndroid Build Coastguard Worker     return (currentSpanSize == 0u ||
85*c8dee2aaSAndroid Build Coastguard Worker             commandBuffer->addComputePass({currentSpanPtr, currentSpanSize})) ? Status::kSuccess
86*c8dee2aaSAndroid Build Coastguard Worker                                                                               : Status::kFail;
87*c8dee2aaSAndroid Build Coastguard Worker }
88*c8dee2aaSAndroid Build Coastguard Worker 
89*c8dee2aaSAndroid Build Coastguard Worker }  // namespace skgpu::graphite
90