Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Public Member Functions | Static Public Member Functions | Private Member Functions | List of all members
skgpu::graphite::MtlCommandBuffer Class Referencefinal

#include <MtlCommandBuffer.h>

Inheritance diagram for skgpu::graphite::MtlCommandBuffer:
skgpu::graphite::CommandBuffer

Public Member Functions

 ~MtlCommandBuffer () override
 
bool setNewCommandBufferResources () override
 
void addWaitSemaphores (size_t numWaitSemaphores, const BackendSemaphore *waitSemaphores) override
 
void addSignalSemaphores (size_t numSignalSemaphores, const BackendSemaphore *signalSemaphores) override
 
bool isFinished ()
 
void waitUntilFinished ()
 
bool commit ()
 
- Public Member Functions inherited from skgpu::graphite::CommandBuffer
virtual ~CommandBuffer ()
 
void trackResource (sk_sp< Resource > resource)
 
void trackCommandBufferResource (sk_sp< Resource > resource)
 
void resetCommandBuffer ()
 
void addFinishedProc (sk_sp< RefCntedCallback > finishedProc)
 
void callFinishedProcs (bool success)
 
virtual void prepareSurfaceForStateUpdate (SkSurface *targetSurface, const MutableTextureState *newState)
 
void addBuffersToAsyncMapOnSubmit (SkSpan< const sk_sp< Buffer > >)
 
SkSpan< const sk_sp< Buffer > > buffersToAsyncMapOnSubmit () const
 
bool addRenderPass (const RenderPassDesc &, sk_sp< Texture > colorTexture, sk_sp< Texture > resolveTexture, sk_sp< Texture > depthStencilTexture, SkRect viewport, const DrawPassList &drawPasses)
 
bool addComputePass (DispatchGroupSpan dispatchGroups)
 
bool copyBufferToBuffer (const Buffer *srcBuffer, size_t srcOffset, sk_sp< Buffer > dstBuffer, size_t dstOffset, size_t size)
 
bool copyTextureToBuffer (sk_sp< Texture >, SkIRect srcRect, sk_sp< Buffer >, size_t bufferOffset, size_t bufferRowBytes)
 
bool copyBufferToTexture (const Buffer *, sk_sp< Texture >, const BufferTextureCopyData *, int count)
 
bool copyTextureToTexture (sk_sp< Texture > src, SkIRect srcRect, sk_sp< Texture > dst, SkIPoint dstPoint, int mipLevel)
 
bool synchronizeBufferToCpu (sk_sp< Buffer >)
 
bool clearBuffer (const Buffer *buffer, size_t offset, size_t size)
 
void setReplayTranslation (SkIVector translation)
 
void clearReplayTranslation ()
 

Static Public Member Functions

static std::unique_ptr< MtlCommandBufferMake (id< MTLCommandQueue >, const MtlSharedContext *, MtlResourceProvider *)
 

Private Member Functions

void onResetCommandBuffer () override
 
bool onAddRenderPass (const RenderPassDesc &, const Texture *colorTexture, const Texture *resolveTexture, const Texture *depthStencilTexture, SkRect viewport, const DrawPassList &) override
 
bool onAddComputePass (DispatchGroupSpan) override
 
bool onCopyBufferToBuffer (const Buffer *srcBuffer, size_t srcOffset, const Buffer *dstBuffer, size_t dstOffset, size_t size) override
 
bool onCopyTextureToBuffer (const Texture *, SkIRect srcRect, const Buffer *, size_t bufferOffset, size_t bufferRowBytes) override
 
bool onCopyBufferToTexture (const Buffer *, const Texture *, const BufferTextureCopyData *copyData, int count) override
 
bool onCopyTextureToTexture (const Texture *src, SkIRect srcRect, const Texture *dst, SkIPoint dstPoint, int mipLevel) override
 
bool onSynchronizeBufferToCpu (const Buffer *, bool *outDidResultInWork) override
 
bool onClearBuffer (const Buffer *, size_t offset, size_t size) override
 

Additional Inherited Members

- Public Types inherited from skgpu::graphite::CommandBuffer
using DrawPassList = skia_private::TArray< std::unique_ptr< DrawPass > >
 
using DispatchGroupSpan = SkSpan< const std::unique_ptr< DispatchGroup > >
 
- Protected Member Functions inherited from skgpu::graphite::CommandBuffer
 CommandBuffer ()
 
- Protected Attributes inherited from skgpu::graphite::CommandBuffer
SkISize fRenderPassSize
 
SkIVector fReplayTranslation
 

Detailed Description

Definition at line 31 of file MtlCommandBuffer.h.

Constructor & Destructor Documentation

◆ ~MtlCommandBuffer()

skgpu::graphite::MtlCommandBuffer::~MtlCommandBuffer ( )
override

Definition at line 51 of file MtlCommandBuffer.mm.

51 {
52 SkASSERT(!fActiveRenderCommandEncoder);
53 SkASSERT(!fActiveComputeCommandEncoder);
54 SkASSERT(!fActiveBlitCommandEncoder);
55}
#define SkASSERT(cond)
Definition SkAssert.h:116

Member Function Documentation

◆ addSignalSemaphores()

void skgpu::graphite::MtlCommandBuffer::addSignalSemaphores ( size_t  numSignalSemaphores,
const BackendSemaphore signalSemaphores 
)
overridevirtual

Reimplemented from skgpu::graphite::CommandBuffer.

Definition at line 130 of file MtlCommandBuffer.mm.

131 {
132 if (!signalSemaphores) {
133 SkASSERT(numSignalSemaphores == 0);
134 return;
135 }
136
137 // Can only insert events with no active encoder
138 SkASSERT(!fActiveRenderCommandEncoder);
139 SkASSERT(!fActiveComputeCommandEncoder);
140 this->endBlitCommandEncoder();
141
142 if (@available(macOS 10.14, iOS 12.0, tvOS 12.0, *)) {
143 for (size_t i = 0; i < numSignalSemaphores; ++i) {
144 auto semaphore = signalSemaphores[i];
145 if (semaphore.isValid() && semaphore.backend() == BackendApi::kMetal) {
146 id<MTLEvent> mtlEvent = (__bridge id<MTLEvent>)semaphore.getMtlEvent();
147 [(*fCommandBuffer) encodeSignalEvent: mtlEvent
148 value: semaphore.getMtlValue()];
149 }
150 }
151 }
152}
uint8_t value

◆ addWaitSemaphores()

void skgpu::graphite::MtlCommandBuffer::addWaitSemaphores ( size_t  numWaitSemaphores,
const BackendSemaphore waitSemaphores 
)
overridevirtual

Reimplemented from skgpu::graphite::CommandBuffer.

Definition at line 107 of file MtlCommandBuffer.mm.

108 {
109 if (!waitSemaphores) {
110 SkASSERT(numWaitSemaphores == 0);
111 return;
112 }
113
114 // Can only insert events with no active encoder
115 SkASSERT(!fActiveRenderCommandEncoder);
116 SkASSERT(!fActiveComputeCommandEncoder);
117 this->endBlitCommandEncoder();
118 if (@available(macOS 10.14, iOS 12.0, tvOS 12.0, *)) {
119 for (size_t i = 0; i < numWaitSemaphores; ++i) {
120 auto semaphore = waitSemaphores[i];
121 if (semaphore.isValid() && semaphore.backend() == BackendApi::kMetal) {
122 id<MTLEvent> mtlEvent = (__bridge id<MTLEvent>)semaphore.getMtlEvent();
123 [(*fCommandBuffer) encodeWaitForEvent: mtlEvent
124 value: semaphore.getMtlValue()];
125 }
126 }
127 }
128}

◆ commit()

bool skgpu::graphite::MtlCommandBuffer::commit ( )

Definition at line 83 of file MtlCommandBuffer.mm.

83 {
84 SkASSERT(!fActiveRenderCommandEncoder);
85 SkASSERT(!fActiveComputeCommandEncoder);
86 this->endBlitCommandEncoder();
87 [(*fCommandBuffer) commit];
88
89 if ((*fCommandBuffer).status == MTLCommandBufferStatusError) {
90 NSString* description = (*fCommandBuffer).error.localizedDescription;
91 const char* errorString = [description UTF8String];
92 SKGPU_LOG_E("Failure submitting command buffer: %s", errorString);
93 }
94
95 return ((*fCommandBuffer).status != MTLCommandBufferStatusError);
96}
#define SKGPU_LOG_E(fmt,...)
Definition Log.h:38

◆ isFinished()

bool skgpu::graphite::MtlCommandBuffer::isFinished ( )
inline

Definition at line 45 of file MtlCommandBuffer.h.

45 {
46 return (*fCommandBuffer).status == MTLCommandBufferStatusCompleted ||
47 (*fCommandBuffer).status == MTLCommandBufferStatusError;
48
49 }

◆ Make()

std::unique_ptr< MtlCommandBuffer > skgpu::graphite::MtlCommandBuffer::Make ( id< MTLCommandQueue >  queue,
const MtlSharedContext sharedContext,
MtlResourceProvider resourceProvider 
)
static

Definition at line 30 of file MtlCommandBuffer.mm.

32 {
33 auto commandBuffer = std::unique_ptr<MtlCommandBuffer>(
34 new MtlCommandBuffer(queue, sharedContext, resourceProvider));
35 if (!commandBuffer) {
36 return nullptr;
37 }
38 if (!commandBuffer->createNewMTLCommandBuffer()) {
39 return nullptr;
40 }
41 return commandBuffer;
42}

◆ onAddComputePass()

bool skgpu::graphite::MtlCommandBuffer::onAddComputePass ( DispatchGroupSpan  groups)
overrideprivatevirtual

Implements skgpu::graphite::CommandBuffer.

Definition at line 174 of file MtlCommandBuffer.mm.

174 {
175 this->beginComputePass();
176 for (const auto& group : groups) {
177 group->addResourceRefs(this);
178 for (const auto& dispatch : group->dispatches()) {
179 this->bindComputePipeline(group->getPipeline(dispatch.fPipelineIndex));
180 for (const ResourceBinding& binding : dispatch.fBindings) {
181 if (const BufferView* buffer = std::get_if<BufferView>(&binding.fResource)) {
182 this->bindBuffer(buffer->fInfo.fBuffer, buffer->fInfo.fOffset, binding.fIndex);
183 } else if (const TextureIndex* texIdx =
184 std::get_if<TextureIndex>(&binding.fResource)) {
185 SkASSERT(texIdx);
186 this->bindTexture(group->getTexture(texIdx->fValue), binding.fIndex);
187 } else {
188 const SamplerIndex* samplerIdx = std::get_if<SamplerIndex>(&binding.fResource);
189 SkASSERT(samplerIdx);
190 this->bindSampler(group->getSampler(samplerIdx->fValue), binding.fIndex);
191 }
192 }
193 SkASSERT(fActiveComputeCommandEncoder);
194 for (const ComputeStep::WorkgroupBufferDesc& wgBuf : dispatch.fWorkgroupBuffers) {
195 fActiveComputeCommandEncoder->setThreadgroupMemoryLength(
196 SkAlignTo(wgBuf.size, 16),
197 wgBuf.index);
198 }
199 if (const WorkgroupSize* globalSize =
200 std::get_if<WorkgroupSize>(&dispatch.fGlobalSizeOrIndirect)) {
201 this->dispatchThreadgroups(*globalSize, dispatch.fLocalSize);
202 } else {
203 SkASSERT(std::holds_alternative<BufferView>(dispatch.fGlobalSizeOrIndirect));
204 const BufferView& indirect =
205 *std::get_if<BufferView>(&dispatch.fGlobalSizeOrIndirect);
206 this->dispatchThreadgroupsIndirect(
207 dispatch.fLocalSize, indirect.fInfo.fBuffer, indirect.fInfo.fOffset);
208 }
209 }
210 }
211 this->endComputePass();
212 return true;
213}
static constexpr size_t SkAlignTo(size_t x, size_t alignment)
Definition SkAlign.h:33
static const uint8_t buffer[]

◆ onAddRenderPass()

bool skgpu::graphite::MtlCommandBuffer::onAddRenderPass ( const RenderPassDesc renderPassDesc,
const Texture colorTexture,
const Texture resolveTexture,
const Texture depthStencilTexture,
SkRect  viewport,
const DrawPassList drawPasses 
)
overrideprivatevirtual

Implements skgpu::graphite::CommandBuffer.

Definition at line 154 of file MtlCommandBuffer.mm.

159 {
160 if (!this->beginRenderPass(renderPassDesc, colorTexture, resolveTexture, depthStencilTexture)) {
161 return false;
162 }
163
164 this->setViewport(viewport.x(), viewport.y(), viewport.width(), viewport.height(), 0, 1);
165
166 for (const auto& drawPass : drawPasses) {
167 this->addDrawPass(drawPass.get());
168 }
169
170 this->endRenderPass();
171 return true;
172}
constexpr float x() const
Definition SkRect.h:720
constexpr float y() const
Definition SkRect.h:727
constexpr float height() const
Definition SkRect.h:769
constexpr float width() const
Definition SkRect.h:762

◆ onClearBuffer()

bool skgpu::graphite::MtlCommandBuffer::onClearBuffer ( const Buffer buffer,
size_t  offset,
size_t  size 
)
overrideprivatevirtual

Implements skgpu::graphite::CommandBuffer.

Definition at line 939 of file MtlCommandBuffer.mm.

939 {
940 SkASSERT(!fActiveRenderCommandEncoder);
941 SkASSERT(!fActiveComputeCommandEncoder);
942
943 MtlBlitCommandEncoder* blitCmdEncoder = this->getBlitCommandEncoder();
944 if (!blitCmdEncoder) {
945 return false;
946 }
947
948 id<MTLBuffer> mtlBuffer = static_cast<const MtlBuffer*>(buffer)->mtlBuffer();
949 blitCmdEncoder->fillBuffer(mtlBuffer, offset, size, 0);
950
951 return true;
952}
Point offset

◆ onCopyBufferToBuffer()

bool skgpu::graphite::MtlCommandBuffer::onCopyBufferToBuffer ( const Buffer srcBuffer,
size_t  srcOffset,
const Buffer dstBuffer,
size_t  dstOffset,
size_t  size 
)
overrideprivatevirtual

Implements skgpu::graphite::CommandBuffer.

Definition at line 784 of file MtlCommandBuffer.mm.

788 {
789 SkASSERT(!fActiveRenderCommandEncoder);
790 SkASSERT(!fActiveComputeCommandEncoder);
791
792 id<MTLBuffer> mtlSrcBuffer = static_cast<const MtlBuffer*>(srcBuffer)->mtlBuffer();
793 id<MTLBuffer> mtlDstBuffer = static_cast<const MtlBuffer*>(dstBuffer)->mtlBuffer();
794
795 MtlBlitCommandEncoder* blitCmdEncoder = this->getBlitCommandEncoder();
796 if (!blitCmdEncoder) {
797 return false;
798 }
799
800#ifdef SK_ENABLE_MTL_DEBUG_INFO
801 blitCmdEncoder->pushDebugGroup(@"copyBufferToBuffer");
802#endif
803 blitCmdEncoder->copyBufferToBuffer(mtlSrcBuffer, srcOffset, mtlDstBuffer, dstOffset, size);
804#ifdef SK_ENABLE_MTL_DEBUG_INFO
805 blitCmdEncoder->popDebugGroup();
806#endif
807 return true;
808}

◆ onCopyBufferToTexture()

bool skgpu::graphite::MtlCommandBuffer::onCopyBufferToTexture ( const Buffer buffer,
const Texture texture,
const BufferTextureCopyData copyData,
int  count 
)
overrideprivatevirtual

Implements skgpu::graphite::CommandBuffer.

Definition at line 840 of file MtlCommandBuffer.mm.

843 {
844 SkASSERT(!fActiveRenderCommandEncoder);
845 SkASSERT(!fActiveComputeCommandEncoder);
846
847 id<MTLBuffer> mtlBuffer = static_cast<const MtlBuffer*>(buffer)->mtlBuffer();
848 id<MTLTexture> mtlTexture = static_cast<const MtlTexture*>(texture)->mtlTexture();
849
850 MtlBlitCommandEncoder* blitCmdEncoder = this->getBlitCommandEncoder();
851 if (!blitCmdEncoder) {
852 return false;
853 }
854
855#ifdef SK_ENABLE_MTL_DEBUG_INFO
856 blitCmdEncoder->pushDebugGroup(@"copyBufferToTexture");
857#endif
858 for (int i = 0; i < count; ++i) {
859 if (!check_max_blit_width(copyData[i].fRect.width())) {
860 return false;
861 }
862
863 blitCmdEncoder->copyFromBuffer(mtlBuffer,
864 copyData[i].fBufferOffset,
865 copyData[i].fBufferRowBytes,
866 mtlTexture,
867 copyData[i].fRect,
868 copyData[i].fMipLevel);
869 }
870
871#ifdef SK_ENABLE_MTL_DEBUG_INFO
872 blitCmdEncoder->popDebugGroup();
873#endif
874 return true;
875}
SkRect fRect
int count
FlTexture * texture
static bool check_max_blit_width(int widthInPixels)

◆ onCopyTextureToBuffer()

bool skgpu::graphite::MtlCommandBuffer::onCopyTextureToBuffer ( const Texture texture,
SkIRect  srcRect,
const Buffer buffer,
size_t  bufferOffset,
size_t  bufferRowBytes 
)
overrideprivatevirtual

Implements skgpu::graphite::CommandBuffer.

Definition at line 810 of file MtlCommandBuffer.mm.

814 {
815 SkASSERT(!fActiveRenderCommandEncoder);
816 SkASSERT(!fActiveComputeCommandEncoder);
817
818 if (!check_max_blit_width(srcRect.width())) {
819 return false;
820 }
821
822 id<MTLTexture> mtlTexture = static_cast<const MtlTexture*>(texture)->mtlTexture();
823 id<MTLBuffer> mtlBuffer = static_cast<const MtlBuffer*>(buffer)->mtlBuffer();
824
825 MtlBlitCommandEncoder* blitCmdEncoder = this->getBlitCommandEncoder();
826 if (!blitCmdEncoder) {
827 return false;
828 }
829
830#ifdef SK_ENABLE_MTL_DEBUG_INFO
831 blitCmdEncoder->pushDebugGroup(@"copyTextureToBuffer");
832#endif
833 blitCmdEncoder->copyFromTexture(mtlTexture, srcRect, mtlBuffer, bufferOffset, bufferRowBytes);
834#ifdef SK_ENABLE_MTL_DEBUG_INFO
835 blitCmdEncoder->popDebugGroup();
836#endif
837 return true;
838}
constexpr int32_t width() const
Definition SkRect.h:158

◆ onCopyTextureToTexture()

bool skgpu::graphite::MtlCommandBuffer::onCopyTextureToTexture ( const Texture src,
SkIRect  srcRect,
const Texture dst,
SkIPoint  dstPoint,
int  mipLevel 
)
overrideprivatevirtual

Implements skgpu::graphite::CommandBuffer.

Definition at line 877 of file MtlCommandBuffer.mm.

881 {
882 SkASSERT(!fActiveRenderCommandEncoder);
883 SkASSERT(!fActiveComputeCommandEncoder);
884
885 id<MTLTexture> srcMtlTexture = static_cast<const MtlTexture*>(src)->mtlTexture();
886 id<MTLTexture> dstMtlTexture = static_cast<const MtlTexture*>(dst)->mtlTexture();
887
888 MtlBlitCommandEncoder* blitCmdEncoder = this->getBlitCommandEncoder();
889 if (!blitCmdEncoder) {
890 return false;
891 }
892
893#ifdef SK_ENABLE_MTL_DEBUG_INFO
894 blitCmdEncoder->pushDebugGroup(@"copyTextureToTexture");
895#endif
896
897 blitCmdEncoder->copyTextureToTexture(srcMtlTexture, srcRect, dstMtlTexture, dstPoint, mipLevel);
898
899#ifdef SK_ENABLE_MTL_DEBUG_INFO
900 blitCmdEncoder->popDebugGroup();
901#endif
902 return true;
903}
dst
Definition cp.py:12

◆ onResetCommandBuffer()

void skgpu::graphite::MtlCommandBuffer::onResetCommandBuffer ( )
overrideprivatevirtual

Implements skgpu::graphite::CommandBuffer.

Definition at line 98 of file MtlCommandBuffer.mm.

98 {
99 fCommandBuffer.reset();
100 fActiveRenderCommandEncoder.reset();
101 fActiveComputeCommandEncoder.reset();
102 fActiveBlitCommandEncoder.reset();
103 fCurrentIndexBuffer = nil;
104 fCurrentIndexBufferOffset = 0;
105}

◆ onSynchronizeBufferToCpu()

bool skgpu::graphite::MtlCommandBuffer::onSynchronizeBufferToCpu ( const Buffer buffer,
bool *  outDidResultInWork 
)
overrideprivatevirtual

Implements skgpu::graphite::CommandBuffer.

Definition at line 905 of file MtlCommandBuffer.mm.

905 {
906#ifdef SK_BUILD_FOR_MAC
907 SkASSERT(!fActiveRenderCommandEncoder);
908 SkASSERT(!fActiveComputeCommandEncoder);
909
910 id<MTLBuffer> mtlBuffer = static_cast<const MtlBuffer*>(buffer)->mtlBuffer();
911 if ([mtlBuffer storageMode] != MTLStorageModeManaged) {
912 *outDidResultInWork = false;
913 return true;
914 }
915
916 MtlBlitCommandEncoder* blitCmdEncoder = this->getBlitCommandEncoder();
917 if (!blitCmdEncoder) {
918 return false;
919 }
920
921#ifdef SK_ENABLE_MTL_DEBUG_INFO
922 blitCmdEncoder->pushDebugGroup(@"synchronizeToCpu");
923#endif
924 blitCmdEncoder->synchronizeResource(mtlBuffer);
925#ifdef SK_ENABLE_MTL_DEBUG_INFO
926 blitCmdEncoder->popDebugGroup();
927#endif
928
929 *outDidResultInWork = true;
930 return true;
931#else // SK_BUILD_FOR_MAC
932 // Explicit synchronization is never necessary on builds that are not macOS since we never use
933 // discrete GPUs with managed mode buffers outside of macOS.
934 *outDidResultInWork = false;
935 return true;
936#endif // SK_BUILD_FOR_MAC
937}

◆ setNewCommandBufferResources()

bool skgpu::graphite::MtlCommandBuffer::setNewCommandBufferResources ( )
overridevirtual

Implements skgpu::graphite::CommandBuffer.

Definition at line 57 of file MtlCommandBuffer.mm.

57 {
58 return this->createNewMTLCommandBuffer();
59}

◆ waitUntilFinished()

void skgpu::graphite::MtlCommandBuffer::waitUntilFinished ( )
inline

Definition at line 50 of file MtlCommandBuffer.h.

50 {
51 // TODO: it's not clear what do to if status is Enqueued. Commit and then wait?
52 if ((*fCommandBuffer).status == MTLCommandBufferStatusScheduled ||
53 (*fCommandBuffer).status == MTLCommandBufferStatusCommitted) {
54 [(*fCommandBuffer) waitUntilCompleted];
55 }
56 if (!this->isFinished()) {
57 SKGPU_LOG_E("Unfinished command buffer status: %d",
58 (int)(*fCommandBuffer).status);
59 SkASSERT(false);
60 }
61 }

The documentation for this class was generated from the following files: