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_MtlCommandBuffer_DEFINED 9 #define skgpu_MtlCommandBuffer_DEFINED 10 11 #include "experimental/graphite/src/CommandBuffer.h" 12 #include "experimental/graphite/src/GpuWorkSubmission.h" 13 #include "experimental/graphite/src/Log.h" 14 15 #include <memory> 16 17 #include "include/core/SkTypes.h" 18 #include "include/ports/SkCFObject.h" 19 20 #import <Metal/Metal.h> 21 22 namespace skgpu::mtl { 23 class BlitCommandEncoder; 24 class Gpu; 25 class RenderCommandEncoder; 26 27 class CommandBuffer final : public skgpu::CommandBuffer { 28 public: 29 static sk_sp<CommandBuffer> Make(const Gpu*); 30 ~CommandBuffer() override; 31 isFinished()32 bool isFinished() { 33 return (*fCommandBuffer).status == MTLCommandBufferStatusCompleted || 34 (*fCommandBuffer).status == MTLCommandBufferStatusError; 35 36 } waitUntilFinished()37 void waitUntilFinished() { 38 // TODO: it's not clear what do to if status is Enqueued. Commit and then wait? 39 if ((*fCommandBuffer).status == MTLCommandBufferStatusScheduled || 40 (*fCommandBuffer).status == MTLCommandBufferStatusCommitted) { 41 [(*fCommandBuffer) waitUntilCompleted]; 42 } 43 if (!this->isFinished()) { 44 SKGPU_LOG_E("Unfinished command buffer status: %d", 45 (int)(*fCommandBuffer).status); 46 SkASSERT(false); 47 } 48 } 49 bool commit(); 50 51 private: 52 CommandBuffer(sk_cfp<id<MTLCommandBuffer>> cmdBuffer, const Gpu* gpu); 53 54 bool onBeginRenderPass(const RenderPassDesc&, 55 const skgpu::Texture* colorTexture, 56 const skgpu::Texture* resolveTexture, 57 const skgpu::Texture* depthStencilTexture) override; 58 void endRenderPass() override; 59 60 void onBindGraphicsPipeline(const skgpu::GraphicsPipeline*) override; 61 void onBindUniformBuffer(UniformSlot, const skgpu::Buffer*, size_t offset) override; 62 void onBindVertexBuffers(const skgpu::Buffer* vertexBuffer, size_t vertexOffset, 63 const skgpu::Buffer* instanceBuffer, size_t instanceOffset) override; 64 void onBindIndexBuffer(const skgpu::Buffer* indexBuffer, size_t offset) override; 65 66 void onBindTextures(const TextureBindEntry* entries, int count) override; 67 void onBindSamplers(const SamplerBindEntry* entries, int count) override; 68 69 void onSetScissor(unsigned int left, unsigned int top, 70 unsigned int width, unsigned int height) override; 71 void onSetViewport(float x, float y, float width, float height, 72 float minDepth, float maxDepth) override; 73 void onSetBlendConstants(std::array<float, 4> blendConstants) override; 74 75 void onDraw(PrimitiveType type, unsigned int baseVertex, unsigned int vertexCount) override; 76 void onDrawIndexed(PrimitiveType type, unsigned int baseIndex, unsigned int indexCount, 77 unsigned int baseVertex) override; 78 void onDrawInstanced(PrimitiveType type, 79 unsigned int baseVertex, unsigned int vertexCount, 80 unsigned int baseInstance, unsigned int instanceCount) override; 81 void onDrawIndexedInstanced(PrimitiveType type, unsigned int baseIndex, 82 unsigned int indexCount, unsigned int baseVertex, 83 unsigned int baseInstance, unsigned int instanceCount) override; 84 85 bool onCopyTextureToBuffer(const skgpu::Texture*, 86 SkIRect srcRect, 87 const skgpu::Buffer*, 88 size_t bufferOffset, 89 size_t bufferRowBytes) override; 90 bool onCopyBufferToTexture(const skgpu::Buffer*, 91 const skgpu::Texture*, 92 const BufferTextureCopyData* copyData, 93 int count) override; 94 95 BlitCommandEncoder* getBlitCommandEncoder(); 96 void endBlitCommandEncoder(); 97 98 sk_cfp<id<MTLCommandBuffer>> fCommandBuffer; 99 sk_sp<RenderCommandEncoder> fActiveRenderCommandEncoder; 100 sk_sp<BlitCommandEncoder> fActiveBlitCommandEncoder; 101 102 size_t fCurrentVertexStride = 0; 103 size_t fCurrentInstanceStride = 0; 104 id<MTLBuffer> fCurrentIndexBuffer; 105 size_t fCurrentIndexBufferOffset = 0; 106 107 const Gpu* fGpu; 108 }; 109 110 } // namespace skgpu::mtl 111 112 #endif // skgpu_MtlCommandBuffer_DEFINED 113