• 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 #ifndef skgpu_CommandBuffer_DEFINED
9 #define skgpu_CommandBuffer_DEFINED
10 
11 #include "experimental/graphite/include/TextureInfo.h"
12 #include "experimental/graphite/src/DrawTypes.h"
13 #include "experimental/graphite/src/DrawWriter.h"
14 #include "include/core/SkColor.h"
15 #include "include/core/SkRect.h"
16 #include "include/core/SkRefCnt.h"
17 #include "include/private/SkTArray.h"
18 
19 struct SkIRect;
20 
21 namespace skgpu {
22 class Buffer;
23 class Gpu;
24 class GraphicsPipeline;
25 class Resource;
26 class Sampler;
27 class Texture;
28 class TextureProxy;
29 
30 enum class UniformSlot {
31     // TODO: Want this?
32     // Meant for uniforms that change rarely to never over the course of a render pass
33     // kStatic,
34     // Meant for uniforms that are defined and used by the RenderStep portion of the pipeline shader
35     kRenderStep,
36     // Meant for uniforms that are defined and used by the paint parameters (ie SkPaint subset)
37     kPaint,
38 };
39 
40 struct AttachmentDesc {
41     TextureInfo fTextureInfo;
42     LoadOp fLoadOp;
43     StoreOp fStoreOp;
44 };
45 
46 struct RenderPassDesc {
47     AttachmentDesc fColorAttachment;
48     std::array<float, 4> fClearColor;
49     AttachmentDesc fColorResolveAttachment;
50 
51     AttachmentDesc fDepthStencilAttachment;
52     float fClearDepth;
53     uint32_t fClearStencil;
54 
55     // TODO:
56     // * bounds (TBD whether exact bounds vs. granular)
57     // * input attachments
58 };
59 
60 // specifies a single region for copying, either from buffer to texture, or vice versa
61 struct BufferTextureCopyData {
62     size_t fBufferOffset;
63     size_t fBufferRowBytes;
64     SkIRect fRect;
65     unsigned int fMipLevel;
66 };
67 
68 class CommandBuffer : public SkRefCnt, private DrawDispatcher {
69 public:
70     ~CommandBuffer() override;
71 
72 #ifdef SK_DEBUG
hasWork()73     bool hasWork() { return fHasWork; }
74 #endif
75 
76     void trackResource(sk_sp<Resource> resource);
77 
78     bool beginRenderPass(const RenderPassDesc&,
79                          sk_sp<Texture> colorTexture,
80                          sk_sp<Texture> resolveTexture,
81                          sk_sp<Texture> depthStencilTexture);
82     virtual void endRenderPass() = 0;
83 
84     //---------------------------------------------------------------
85     // Can only be used within renderpasses
86     //---------------------------------------------------------------
87     void bindGraphicsPipeline(sk_sp<GraphicsPipeline> graphicsPipeline);
88     void bindUniformBuffer(UniformSlot, sk_sp<Buffer>, size_t bufferOffset);
89 
90     void bindDrawBuffers(BindBufferInfo vertices,
91                          BindBufferInfo instances,
92                          BindBufferInfo indices) final;
93 
94     struct TextureBindEntry {
95         sk_sp<Texture> fTexture;
96         unsigned int   fBindIndex;
97     };
98     void bindTextures(const TextureBindEntry* entries, int count);
99 
100     struct SamplerBindEntry {
101         sk_sp<Sampler> fSampler;
102         unsigned int   fBindIndex;
103     };
104     void bindSamplers(const SamplerBindEntry* entries, int count);
105 
106     // TODO: do we want to handle multiple scissor rects and viewports?
setScissor(unsigned int left,unsigned int top,unsigned int width,unsigned int height)107     void setScissor(unsigned int left, unsigned int top, unsigned int width, unsigned int height) {
108         this->onSetScissor(left, top, width, height);
109     }
110 
111     void setViewport(float x, float y, float width, float height,
112                      float minDepth = 0, float maxDepth = 1) {
113         this->onSetViewport(x, y, width, height, minDepth, maxDepth);
114     }
115 
setBlendConstants(std::array<float,4> blendConstants)116     void setBlendConstants(std::array<float, 4> blendConstants) {
117         this->onSetBlendConstants(blendConstants);
118     }
119 
draw(PrimitiveType type,unsigned int baseVertex,unsigned int vertexCount)120     void draw(PrimitiveType type, unsigned int baseVertex, unsigned int vertexCount) final {
121         this->onDraw(type, baseVertex, vertexCount);
122         SkDEBUGCODE(fHasWork = true;)
123     }
drawIndexed(PrimitiveType type,unsigned int baseIndex,unsigned int indexCount,unsigned int baseVertex)124     void drawIndexed(PrimitiveType type, unsigned int baseIndex, unsigned int indexCount,
125                      unsigned int baseVertex) final {
126         this->onDrawIndexed(type, baseIndex, indexCount, baseVertex);
127         SkDEBUGCODE(fHasWork = true;)
128     }
drawInstanced(PrimitiveType type,unsigned int baseVertex,unsigned int vertexCount,unsigned int baseInstance,unsigned int instanceCount)129     void drawInstanced(PrimitiveType type, unsigned int baseVertex, unsigned int vertexCount,
130                        unsigned int baseInstance, unsigned int instanceCount) final {
131         this->onDrawInstanced(type, baseVertex, vertexCount, baseInstance, instanceCount);
132         SkDEBUGCODE(fHasWork = true;)
133     }
drawIndexedInstanced(PrimitiveType type,unsigned int baseIndex,unsigned int indexCount,unsigned int baseVertex,unsigned int baseInstance,unsigned int instanceCount)134     void drawIndexedInstanced(PrimitiveType type, unsigned int baseIndex, unsigned int indexCount,
135                               unsigned int baseVertex, unsigned int baseInstance,
136                               unsigned int instanceCount) final {
137         this->onDrawIndexedInstanced(type, baseIndex, indexCount, baseVertex, baseInstance,
138                                      instanceCount);
139         SkDEBUGCODE(fHasWork = true;)
140     }
141 
142     // When using a DrawWriter dispatching directly to a CommandBuffer, binding of pipelines and
143     // uniforms must be coordinated with forNewPipeline() and forDynamicStateChange(). The direct
144     // draw calls and vertex buffer binding calls on CB should not be intermingled with the writer.
asDrawDispatcher()145     DrawDispatcher* asDrawDispatcher() { return this; }
146 
147     //---------------------------------------------------------------
148     // Can only be used outside renderpasses
149     //---------------------------------------------------------------
150     bool copyTextureToBuffer(sk_sp<Texture>,
151                              SkIRect srcRect,
152                              sk_sp<Buffer>,
153                              size_t bufferOffset,
154                              size_t bufferRowBytes);
155     bool copyBufferToTexture(sk_sp<Buffer>,
156                              sk_sp<Texture>,
157                              const BufferTextureCopyData*,
158                              int count);
159 
160 protected:
161     CommandBuffer();
162 
163 private:
164     void releaseResources();
165 
166     // TODO: Once all buffer use goes through the DrawBufferManager, we likely do not need to track
167     // refs every time a buffer is bound, since the DBM will transfer ownership for any used buffer
168     // to the CommandBuffer.
169     void bindVertexBuffers(sk_sp<Buffer> vertexBuffer, size_t vertexOffset,
170                            sk_sp<Buffer> instanceBuffer, size_t instanceOffset);
171     void bindIndexBuffer(sk_sp<Buffer> indexBuffer, size_t bufferOffset);
172 
173     virtual bool onBeginRenderPass(const RenderPassDesc&,
174                                    const Texture* colorTexture,
175                                    const Texture* resolveTexture,
176                                    const Texture* depthStencilTexture) = 0;
177 
178     virtual void onBindGraphicsPipeline(const GraphicsPipeline*) = 0;
179     virtual void onBindUniformBuffer(UniformSlot, const Buffer*, size_t bufferOffset) = 0;
180     virtual void onBindVertexBuffers(const Buffer* vertexBuffer, size_t vertexOffset,
181                                      const Buffer* instanceBuffer, size_t instanceOffset) = 0;
182     virtual void onBindIndexBuffer(const Buffer* indexBuffer, size_t bufferOffset) = 0;
183 
184     virtual void onBindTextures(const TextureBindEntry* entries, int count) = 0;
185     virtual void onBindSamplers(const SamplerBindEntry* entries, int count) = 0;
186 
187     virtual void onSetScissor(unsigned int left, unsigned int top,
188                               unsigned int width, unsigned int height) = 0;
189     virtual void onSetViewport(float x, float y, float width, float height,
190                                float minDepth, float maxDepth) = 0;
191     virtual void onSetBlendConstants(std::array<float, 4> blendConstants) = 0;
192 
193     virtual void onDraw(PrimitiveType type, unsigned int baseVertex, unsigned int vertexCount) = 0;
194     virtual void onDrawIndexed(PrimitiveType type, unsigned int baseIndex, unsigned int indexCount,
195                                unsigned int baseVertex) = 0;
196     virtual void onDrawInstanced(PrimitiveType type,
197                                  unsigned int baseVertex, unsigned int vertexCount,
198                                  unsigned int baseInstance, unsigned int instanceCount) = 0;
199     virtual void onDrawIndexedInstanced(PrimitiveType type, unsigned int baseIndex,
200                                         unsigned int indexCount, unsigned int baseVertex,
201                                         unsigned int baseInstance, unsigned int instanceCount) = 0;
202 
203     virtual bool onCopyTextureToBuffer(const Texture*,
204                                        SkIRect srcRect,
205                                        const Buffer*,
206                                        size_t bufferOffset,
207                                        size_t bufferRowBytes) = 0;
208     virtual bool onCopyBufferToTexture(const Buffer*,
209                                        const Texture*,
210                                        const BufferTextureCopyData*,
211                                        int count) = 0;
212 
213 #ifdef SK_DEBUG
214     bool fHasWork = false;
215 #endif
216 
217     inline static constexpr int kInitialTrackedResourcesCount = 32;
218     SkSTArray<kInitialTrackedResourcesCount, sk_sp<Resource>> fTrackedResources;
219 };
220 
221 } // namespace skgpu
222 
223 #endif // skgpu_CommandBuffer_DEFINED
224