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