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