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 14#include <memory> 15 16#include "include/core/SkTypes.h" 17#include "include/ports/SkCFObject.h" 18 19#import <Metal/Metal.h> 20 21namespace skgpu::mtl { 22class BlitCommandEncoder; 23class Gpu; 24class RenderCommandEncoder; 25 26class CommandBuffer final : public skgpu::CommandBuffer { 27public: 28 static sk_sp<CommandBuffer> Make(const Gpu*); 29 ~CommandBuffer() override; 30 31 bool isFinished() { 32 return (*fCommandBuffer).status == MTLCommandBufferStatusCompleted || 33 (*fCommandBuffer).status == MTLCommandBufferStatusError; 34 35 } 36 void waitUntilFinished() { 37 // TODO: it's not clear what do to if status is Enqueued. Commit and then wait? 38 if ((*fCommandBuffer).status == MTLCommandBufferStatusScheduled || 39 (*fCommandBuffer).status == MTLCommandBufferStatusCommitted) { 40 [(*fCommandBuffer) waitUntilCompleted]; 41 } 42 if (!this->isFinished()) { 43 SkDebugf("Unfinished command buffer status: %d\n", 44 (int)(*fCommandBuffer).status); 45 SkASSERT(false); 46 } 47 } 48 bool commit(); 49 50private: 51 CommandBuffer(sk_cfp<id<MTLCommandBuffer>> cmdBuffer, const Gpu* gpu); 52 53 void onBeginRenderPass(const RenderPassDesc&) override; 54 void endRenderPass() override; 55 56 void onBindGraphicsPipeline(const skgpu::GraphicsPipeline*) override; 57 void onBindUniformBuffer(const skgpu::Buffer*, size_t offset) override; 58 void onBindVertexBuffers(const skgpu::Buffer* vertexBuffer, size_t vertexOffset, 59 const skgpu::Buffer* instanceBuffer, size_t instanceOffset) override; 60 void onBindIndexBuffer(const skgpu::Buffer* indexBuffer, size_t offset) override; 61 62 void onDraw(PrimitiveType type, unsigned int baseVertex, unsigned int vertexCount) override; 63 void onDrawIndexed(PrimitiveType type, unsigned int baseIndex, unsigned int indexCount, 64 unsigned int baseVertex) override; 65 void onDrawInstanced(PrimitiveType type, 66 unsigned int baseVertex, unsigned int vertexCount, 67 unsigned int baseInstance, unsigned int instanceCount) override; 68 void onDrawIndexedInstanced(PrimitiveType type, unsigned int baseIndex, 69 unsigned int indexCount, unsigned int baseVertex, 70 unsigned int baseInstance, unsigned int instanceCount) override; 71 72 void onCopyTextureToBuffer(const skgpu::Texture*, 73 SkIRect srcRect, 74 const skgpu::Buffer*, 75 size_t bufferOffset, 76 size_t bufferRowBytes) override; 77 78 BlitCommandEncoder* getBlitCommandEncoder(); 79 void endBlitCommandEncoder(); 80 81 sk_cfp<id<MTLCommandBuffer>> fCommandBuffer; 82 sk_sp<RenderCommandEncoder> fActiveRenderCommandEncoder; 83 sk_sp<BlitCommandEncoder> fActiveBlitCommandEncoder; 84 85 size_t fCurrentVertexStride = 0; 86 size_t fCurrentInstanceStride = 0; 87 id<MTLBuffer> fCurrentIndexBuffer; 88 size_t fCurrentIndexBufferOffset = 0; 89 90 const Gpu* fGpu; 91}; 92 93} // namespace skgpu::mtl 94 95#endif // skgpu_MtlCommandBuffer_DEFINED 96