• 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_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 
21 namespace skgpu::mtl {
22 class BlitCommandEncoder;
23 class Gpu;
24 class RenderCommandEncoder;
25 
26 class CommandBuffer final : public skgpu::CommandBuffer {
27 public:
28     static sk_sp<CommandBuffer> Make(const Gpu*);
29     ~CommandBuffer() override;
30 
isFinished()31     bool isFinished() {
32         return (*fCommandBuffer).status == MTLCommandBufferStatusCompleted ||
33                (*fCommandBuffer).status == MTLCommandBufferStatusError;
34 
35     }
waitUntilFinished()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 
50 private:
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