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