1 /*
2 * Copyright 2021 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 #include "src/gpu/graphite/CommandBuffer.h"
9
10 #include "src/core/SkTraceEvent.h"
11 #include "src/gpu/RefCntedCallback.h"
12 #include "src/gpu/graphite/Buffer.h"
13 #include "src/gpu/graphite/ComputePipeline.h"
14 #include "src/gpu/graphite/GraphicsPipeline.h"
15 #include "src/gpu/graphite/Sampler.h"
16 #include "src/gpu/graphite/Texture.h"
17 #include "src/gpu/graphite/TextureProxy.h"
18
19 namespace skgpu::graphite {
20
CommandBuffer()21 CommandBuffer::CommandBuffer() {}
22
~CommandBuffer()23 CommandBuffer::~CommandBuffer() {
24 this->releaseResources();
25 }
26
releaseResources()27 void CommandBuffer::releaseResources() {
28 TRACE_EVENT0("skia.gpu", TRACE_FUNC);
29
30 fTrackedResources.clear();
31 }
32
resetCommandBuffer()33 void CommandBuffer::resetCommandBuffer() {
34 TRACE_EVENT0("skia.gpu", TRACE_FUNC);
35
36 this->releaseResources();
37 this->onResetCommandBuffer();
38 }
39
trackResource(sk_sp<Resource> resource)40 void CommandBuffer::trackResource(sk_sp<Resource> resource) {
41 fTrackedResources.push_back(std::move(resource));
42 }
43
addFinishedProc(sk_sp<RefCntedCallback> finishedProc)44 void CommandBuffer::addFinishedProc(sk_sp<RefCntedCallback> finishedProc) {
45 fFinishedProcs.push_back(std::move(finishedProc));
46 }
47
callFinishedProcs(bool success)48 void CommandBuffer::callFinishedProcs(bool success) {
49 if (!success) {
50 for (int i = 0; i < fFinishedProcs.size(); ++i) {
51 fFinishedProcs[i]->setFailureResult();
52 }
53 }
54 fFinishedProcs.clear();
55 }
56
addRenderPass(const RenderPassDesc & renderPassDesc,sk_sp<Texture> colorTexture,sk_sp<Texture> resolveTexture,sk_sp<Texture> depthStencilTexture,SkRect viewport,const std::vector<std::unique_ptr<DrawPass>> & drawPasses)57 bool CommandBuffer::addRenderPass(const RenderPassDesc& renderPassDesc,
58 sk_sp<Texture> colorTexture,
59 sk_sp<Texture> resolveTexture,
60 sk_sp<Texture> depthStencilTexture,
61 SkRect viewport,
62 const std::vector<std::unique_ptr<DrawPass>>& drawPasses) {
63 fRenderPassSize = colorTexture->dimensions();
64 if (!this->onAddRenderPass(renderPassDesc,
65 colorTexture.get(),
66 resolveTexture.get(),
67 depthStencilTexture.get(),
68 viewport,
69 drawPasses)) {
70 return false;
71 }
72
73 if (colorTexture) {
74 this->trackResource(std::move(colorTexture));
75 }
76 if (resolveTexture) {
77 this->trackResource(std::move(resolveTexture));
78 }
79 if (depthStencilTexture) {
80 this->trackResource(std::move(depthStencilTexture));
81 }
82 // We just assume if you are adding a render pass that the render pass will actually do work. In
83 // theory we could have a discard load that doesn't submit any draws, clears, etc. But hopefully
84 // something so trivial would be caught before getting here.
85 SkDEBUGCODE(fHasWork = true;)
86
87 return true;
88 }
89
addComputePass(const ComputePassDesc & computePassDesc,sk_sp<ComputePipeline> pipeline,const std::vector<ResourceBinding> & bindings)90 bool CommandBuffer::addComputePass(const ComputePassDesc& computePassDesc,
91 sk_sp<ComputePipeline> pipeline,
92 const std::vector<ResourceBinding>& bindings) {
93 if (!this->onAddComputePass(computePassDesc, pipeline.get(), bindings)) {
94 return false;
95 }
96
97 this->trackResource(std::move(pipeline));
98
99 SkDEBUGCODE(fHasWork = true;)
100
101 return true;
102 }
103
copyBufferToBuffer(sk_sp<Buffer> srcBuffer,size_t srcOffset,sk_sp<Buffer> dstBuffer,size_t dstOffset,size_t size)104 bool CommandBuffer::copyBufferToBuffer(sk_sp<Buffer> srcBuffer,
105 size_t srcOffset,
106 sk_sp<Buffer> dstBuffer,
107 size_t dstOffset,
108 size_t size) {
109 SkASSERT(srcBuffer);
110 SkASSERT(dstBuffer);
111
112 if (!this->onCopyBufferToBuffer(srcBuffer.get(), srcOffset, dstBuffer.get(), dstOffset, size)) {
113 return false;
114 }
115
116 this->trackResource(std::move(srcBuffer));
117 this->trackResource(std::move(dstBuffer));
118
119 SkDEBUGCODE(fHasWork = true;)
120
121 return true;
122 }
123
copyTextureToBuffer(sk_sp<Texture> texture,SkIRect srcRect,sk_sp<Buffer> buffer,size_t bufferOffset,size_t bufferRowBytes)124 bool CommandBuffer::copyTextureToBuffer(sk_sp<Texture> texture,
125 SkIRect srcRect,
126 sk_sp<Buffer> buffer,
127 size_t bufferOffset,
128 size_t bufferRowBytes) {
129 SkASSERT(texture);
130 SkASSERT(buffer);
131
132 if (!this->onCopyTextureToBuffer(texture.get(), srcRect, buffer.get(), bufferOffset,
133 bufferRowBytes)) {
134 return false;
135 }
136
137 this->trackResource(std::move(texture));
138 this->trackResource(std::move(buffer));
139
140 SkDEBUGCODE(fHasWork = true;)
141
142 return true;
143 }
144
copyBufferToTexture(const Buffer * buffer,sk_sp<Texture> texture,const BufferTextureCopyData * copyData,int count)145 bool CommandBuffer::copyBufferToTexture(const Buffer* buffer,
146 sk_sp<Texture> texture,
147 const BufferTextureCopyData* copyData,
148 int count) {
149 SkASSERT(buffer);
150 SkASSERT(texture);
151 SkASSERT(count > 0 && copyData);
152
153 if (!this->onCopyBufferToTexture(buffer, texture.get(), copyData, count)) {
154 return false;
155 }
156
157 this->trackResource(std::move(texture));
158
159 SkDEBUGCODE(fHasWork = true;)
160
161 return true;
162 }
163
copyTextureToTexture(sk_sp<Texture> src,SkIRect srcRect,sk_sp<Texture> dst,SkIPoint dstPoint)164 bool CommandBuffer::copyTextureToTexture(sk_sp<Texture> src,
165 SkIRect srcRect,
166 sk_sp<Texture> dst,
167 SkIPoint dstPoint) {
168 SkASSERT(src);
169 SkASSERT(dst);
170
171 if (!this->onCopyTextureToTexture(src.get(), srcRect, dst.get(), dstPoint)) {
172 return false;
173 }
174
175 this->trackResource(std::move(src));
176 this->trackResource(std::move(dst));
177
178 SkDEBUGCODE(fHasWork = true;)
179
180 return true;
181 }
182
synchronizeBufferToCpu(sk_sp<Buffer> buffer)183 bool CommandBuffer::synchronizeBufferToCpu(sk_sp<Buffer> buffer) {
184 SkASSERT(buffer);
185
186 bool didResultInWork = false;
187 if (!this->onSynchronizeBufferToCpu(buffer.get(), &didResultInWork)) {
188 return false;
189 }
190
191 if (didResultInWork) {
192 this->trackResource(std::move(buffer));
193 SkDEBUGCODE(fHasWork = true;)
194 }
195
196 return true;
197 }
198
clearBuffer(const Buffer * buffer,size_t offset,size_t size)199 bool CommandBuffer::clearBuffer(const Buffer* buffer, size_t offset, size_t size) {
200 SkASSERT(buffer);
201
202 if (!this->onClearBuffer(buffer, offset, size)) {
203 return false;
204 }
205
206 SkDEBUGCODE(fHasWork = true;)
207
208 return true;
209 }
210
211 #ifdef SK_ENABLE_PIET_GPU
renderPietScene(const skgpu::piet::Scene & scene,sk_sp<Texture> target)212 void CommandBuffer::renderPietScene(const skgpu::piet::Scene& scene, sk_sp<Texture> target) {
213 this->onRenderPietScene(scene, target.get());
214 this->trackResource(std::move(target));
215 }
216 #endif
217
218 } // namespace skgpu::graphite
219