Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
DispatchGroup.h
Go to the documentation of this file.
1/*
2 * Copyright 2023 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
8#ifndef skgpu_graphite_compute_DispatchGroup_DEFINED
9#define skgpu_graphite_compute_DispatchGroup_DEFINED
10
19
20#include <variant>
21
22namespace skgpu::graphite {
23
24class CommandBuffer;
25class ComputePipeline;
26class Recorder;
28
29using BindingIndex = uint32_t;
30struct TextureIndex { uint32_t fValue; };
31struct SamplerIndex { uint32_t fValue; };
32
37
38using DispatchResource = std::variant<BufferView, TextureIndex, SamplerIndex>;
40 std::variant<std::monostate, BufferView, TextureIndex, SamplerIndex>;
41
46
47/**
48 * DispatchGroup groups a series of compute pipeline dispatches that need to execute sequentially
49 * (i.e. with a barrier). Dispatches are stored in the order that they will be encoded
50 * in the eventual command buffer.
51 *
52 * A DispatchGroup can be constructed from a series of ComputeSteps using a Builder. The Builder
53 * verifies that the data flow specification between successive ComputeSteps are compatible.
54 * The resources required by a ComputeStep (such as Buffers and TextureProxies) are created by
55 * the Builder as they get added.
56 *
57 * Once a DispatchGroup is finalized, it is immutable. It contains the complete ResourceBinding list
58 * for each dispatch. A list of finalized DispatchGroups can be submitted to the command buffer in a
59 * ComputeTask.
60 */
61class DispatchGroup final {
62public:
63 class Builder;
64
74
76
77 const skia_private::TArray<Dispatch>& dispatches() const { return fDispatchList; }
78
79 const ComputePipeline* getPipeline(size_t index) const { return fPipelines[index].get(); }
80 const Texture* getTexture(size_t index) const;
81 const Sampler* getSampler(size_t index) const;
82
84 void addResourceRefs(CommandBuffer*) const;
85
86 // Returns a single tasks that must execute before this DispatchGroup or nullptr if the group
87 // has no task dependencies.
89
90private:
92
93 DispatchGroup() = default;
94
95 // Disallow copy and move.
96 DispatchGroup(const DispatchGroup&) = delete;
97 DispatchGroup(DispatchGroup&&) = delete;
98
100
101 // The list of all buffers that must be cleared before the dispatches.
103
104 // Pipelines are referenced by index by each Dispatch in `fDispatchList`. They are stored as a
105 // pipeline description until instantiated in `prepareResources()`.
108
109 // Resources instantiated by `prepareResources()`
113};
114
116public:
117 // Contains the resource handles assigned to the outputs of the most recently inserted
118 // ComputeStep.
119 struct OutputTable {
120 // Contains the std::monostate variant if the slot is uninitialized
122
123 OutputTable() = default;
124
125 void reset() { *this = {}; }
126 };
127
128 explicit Builder(Recorder*);
129
130 const OutputTable& outputTable() const { return fOutputTable; }
131
132 // Add a new compute step to the dispatch group and initialize its required resources if
133 // necessary.
134 //
135 // If the global dispatch size (i.e. workgroup count) is known ahead of time it can be
136 // optionally provided here while appending a step. If provided, the ComputeStep will not
137 // receive a call to `calculateGlobalDispatchSize`.
138 bool appendStep(const ComputeStep*, std::optional<WorkgroupSize> globalSize = std::nullopt);
139
140 // Add a new compute step to the dispatch group with an indirectly specified global dispatch
141 // size. Initialize the required resources if necessary.
142 //
143 // The global dispatch size is determined by the GPU by reading the entries in `indirectBuffer`.
144 // The contents of this buffer must conform to the layout of the `IndirectDispatchArgs`
145 // structure declared in ComputeTypes.h.
146 //
147 // The ComputeStep will not receive a call to `calculateGlobalDispatchSize`.
148 bool appendStepIndirect(const ComputeStep*, BufferView indirectBuffer);
149
150 // Directly assign a buffer range to a shared slot. ComputeSteps that are appended after this
151 // call will use this resouce if they reference the given `slot` index. Builder will not
152 // allocate the resource internally and ComputeSteps will not receive calls to
153 // `calculateBufferSize`.
154 //
155 // If the slot is already assigned a buffer, it will be overwritten. Calling this method does
156 // not have any effect on previously appended ComputeSteps that were already bound that
157 // resource.
158 //
159 // If `cleared` is kYes, the contents of the given view will be cleared to 0 before the current
160 // DispatchGroup gets submitted.
162 unsigned int slot,
163 ClearBuffer cleared = ClearBuffer::kNo);
164
165 // Directly assign a texture to a shared slot. ComputeSteps that are appended after this call
166 // will use this resource if they reference the given `slot` index. Builder will not allocate
167 // the resource internally and ComputeSteps will not receive calls to
168 // `calculateTextureParameters`.
169 //
170 // If the slot is already assigned a texture, it will be overwritten. Calling this method does
171 // not have any effect on previously appended ComputeSteps that were already bound that
172 // resource.
173 void assignSharedTexture(sk_sp<TextureProxy> texture, unsigned int slot);
174
175 // Finalize and return the constructed DispatchGroup.
176 //
177 // The Builder can be used to construct a new DispatchGroup by calling "reset()" after this
178 // method returns.
179 std::unique_ptr<DispatchGroup> finalize();
180
181#if defined(GRAPHITE_TEST_UTILS)
182 // Clear old state and start a new DispatchGroup.
183 void reset();
184#endif
185
186 // Returns the buffer resource assigned to the shared slot with the given index, if any.
187 BindBufferInfo getSharedBufferResource(unsigned int slot) const;
188
189 // Returns the texture resource assigned to the shared slot with the given index, if any.
190 sk_sp<TextureProxy> getSharedTextureResource(unsigned int slot) const;
191
192private:
193 bool appendStepInternal(const ComputeStep*, const std::variant<WorkgroupSize, BufferView>&);
194
195 // Allocate a resource that can be assigned to the shared or private data flow slots. Returns a
196 // std::monostate if allocation fails.
197 DispatchResourceOptional allocateResource(const ComputeStep* step,
198 const ComputeStep::ResourceDesc& resource,
199 int resourceIdx);
200
201 // The object under construction.
202 std::unique_ptr<DispatchGroup> fObj;
203
204 Recorder* fRecorder;
205 OutputTable fOutputTable;
206};
207
208} // namespace skgpu::graphite
209
210#endif // skgpu_graphite_compute_DispatchGroup_DEFINED
static int step(int x, SkScalar min, SkScalar max)
Definition BlurTest.cpp:215
m reset()
bool appendStepIndirect(const ComputeStep *, BufferView indirectBuffer)
void assignSharedBuffer(BufferView buffer, unsigned int slot, ClearBuffer cleared=ClearBuffer::kNo)
sk_sp< TextureProxy > getSharedTextureResource(unsigned int slot) const
std::unique_ptr< DispatchGroup > finalize()
bool appendStep(const ComputeStep *, std::optional< WorkgroupSize > globalSize=std::nullopt)
const OutputTable & outputTable() const
void assignSharedTexture(sk_sp< TextureProxy > texture, unsigned int slot)
BindBufferInfo getSharedBufferResource(unsigned int slot) const
void addResourceRefs(CommandBuffer *) const
const ComputePipeline * getPipeline(size_t index) const
const Texture * getTexture(size_t index) const
const skia_private::TArray< Dispatch > & dispatches() const
bool prepareResources(ResourceProvider *)
const Sampler * getSampler(size_t index) const
static const uint8_t buffer[]
FlTexture * texture
std::variant< BufferView, TextureIndex, SamplerIndex > DispatchResource
constexpr int kMaxComputeDataFlowSlots
uint32_t BindingIndex
std::variant< std::monostate, BufferView, TextureIndex, SamplerIndex > DispatchResourceOptional
DispatchResourceOptional fSharedSlots[kMaxComputeDataFlowSlots]
skia_private::TArray< ComputeStep::WorkgroupBufferDesc > fWorkgroupBuffers
std::optional< WorkgroupSize > fGlobalDispatchSize
std::variant< WorkgroupSize, BufferView > fGlobalSizeOrIndirect
skia_private::TArray< ResourceBinding > fBindings