33 auto commandBuffer = std::unique_ptr<MtlCommandBuffer>(
38 if (!commandBuffer->createNewMTLCommandBuffer()) {
44MtlCommandBuffer::MtlCommandBuffer(id<MTLCommandQueue> queue,
48 , fSharedContext(sharedContext)
49 , fResourceProvider(resourceProvider) {}
52 SkASSERT(!fActiveRenderCommandEncoder);
53 SkASSERT(!fActiveComputeCommandEncoder);
54 SkASSERT(!fActiveBlitCommandEncoder);
58 return this->createNewMTLCommandBuffer();
61bool MtlCommandBuffer::createNewMTLCommandBuffer() {
67 if (@available(macOS 11.0, iOS 14.0, tvOS 14.0, *)) {
68 sk_cfp<MTLCommandBufferDescriptor*> desc([[MTLCommandBufferDescriptor alloc] init]);
69 (*desc).retainedReferences = NO;
70#ifdef SK_ENABLE_MTL_DEBUG_INFO
71 (*desc).errorOptions = MTLCommandBufferErrorOptionEncoderExecutionStatus;
74 fCommandBuffer.reset([[fQueue commandBufferWithDescriptor:desc.get()] retain]);
77 fCommandBuffer.reset([[fQueue commandBufferWithUnretainedReferences] retain]);
80 return fCommandBuffer != nil;
84 SkASSERT(!fActiveRenderCommandEncoder);
85 SkASSERT(!fActiveComputeCommandEncoder);
86 this->endBlitCommandEncoder();
87 [(*fCommandBuffer)
commit];
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);
95 return ((*fCommandBuffer).status != MTLCommandBufferStatusError);
99 fCommandBuffer.reset();
100 fActiveRenderCommandEncoder.reset();
101 fActiveComputeCommandEncoder.reset();
102 fActiveBlitCommandEncoder.reset();
103 fCurrentIndexBuffer = nil;
104 fCurrentIndexBufferOffset = 0;
109 if (!waitSemaphores) {
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];
122 id<MTLEvent> mtlEvent = (__bridge id<MTLEvent>)semaphore.getMtlEvent();
123 [(*fCommandBuffer) encodeWaitForEvent: mtlEvent
124 value: semaphore.getMtlValue()];
132 if (!signalSemaphores) {
138 SkASSERT(!fActiveRenderCommandEncoder);
139 SkASSERT(!fActiveComputeCommandEncoder);
140 this->endBlitCommandEncoder();
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];
146 id<MTLEvent> mtlEvent = (__bridge id<MTLEvent>)semaphore.getMtlEvent();
147 [(*fCommandBuffer) encodeSignalEvent: mtlEvent
148 value: semaphore.getMtlValue()];
157 const Texture* depthStencilTexture,
160 if (!this->beginRenderPass(renderPassDesc, colorTexture, resolveTexture, depthStencilTexture)) {
164 this->setViewport(viewport.
x(), viewport.
y(), viewport.
width(), viewport.
height(), 0, 1);
166 for (
const auto& drawPass : drawPasses) {
167 this->addDrawPass(drawPass.get());
170 this->endRenderPass();
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));
181 if (
const BufferView*
buffer = std::get_if<BufferView>(&binding.fResource)) {
182 this->bindBuffer(
buffer->fInfo.fBuffer,
buffer->fInfo.fOffset, binding.fIndex);
184 std::get_if<TextureIndex>(&binding.fResource)) {
186 this->bindTexture(group->getTexture(texIdx->fValue), binding.fIndex);
188 const SamplerIndex* samplerIdx = std::get_if<SamplerIndex>(&binding.fResource);
190 this->bindSampler(group->getSampler(samplerIdx->
fValue), binding.fIndex);
193 SkASSERT(fActiveComputeCommandEncoder);
195 fActiveComputeCommandEncoder->setThreadgroupMemoryLength(
200 std::get_if<WorkgroupSize>(&dispatch.fGlobalSizeOrIndirect)) {
201 this->dispatchThreadgroups(*globalSize, dispatch.fLocalSize);
203 SkASSERT(std::holds_alternative<BufferView>(dispatch.fGlobalSizeOrIndirect));
205 *std::get_if<BufferView>(&dispatch.fGlobalSizeOrIndirect);
206 this->dispatchThreadgroupsIndirect(
211 this->endComputePass();
215bool MtlCommandBuffer::beginRenderPass(
const RenderPassDesc& renderPassDesc,
218 const Texture* depthStencilTexture) {
219 SkASSERT(!fActiveRenderCommandEncoder);
220 SkASSERT(!fActiveComputeCommandEncoder);
221 this->endBlitCommandEncoder();
223 const static MTLLoadAction mtlLoadAction[] {
226 MTLLoadActionDontCare
231 static_assert(std::size(mtlLoadAction) ==
kLoadOpCount);
233 const static MTLStoreAction mtlStoreAction[] {
235 MTLStoreActionDontCare
241 sk_cfp<MTLRenderPassDescriptor*> descriptor([[MTLRenderPassDescriptor alloc] init]);
244 bool loadMSAAFromResolve =
false;
247 auto colorAttachment = (*descriptor).colorAttachments[0];
248 colorAttachment.texture = ((
const MtlTexture*)colorTexture)->mtlTexture();
249 const std::array<float, 4>& clearColor = renderPassDesc.
fClearColor;
250 colorAttachment.clearColor =
251 MTLClearColorMake(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
252 colorAttachment.loadAction = mtlLoadAction[
static_cast<int>(colorInfo.fLoadOp)];
253 colorAttachment.storeAction = mtlStoreAction[
static_cast<int>(colorInfo.fStoreOp)];
255 if (resolveTexture) {
258 colorAttachment.resolveTexture = ((
const MtlTexture*)resolveTexture)->mtlTexture();
261 if (@available(macOS 10.12, iOS 10.0, tvOS 10.0, *)) {
262 SkASSERT(colorAttachment.storeAction == MTLStoreActionDontCare);
263 colorAttachment.storeAction = MTLStoreActionMultisampleResolve;
279 if (depthStencilTexture) {
281 id<MTLTexture> mtlTexture = ((
const MtlTexture*)depthStencilTexture)->mtlTexture();
283 auto depthAttachment = (*descriptor).depthAttachment;
284 depthAttachment.texture = mtlTexture;
285 depthAttachment.clearDepth = renderPassDesc.
fClearDepth;
286 depthAttachment.loadAction =
287 mtlLoadAction[
static_cast<int>(depthStencilInfo.fLoadOp)];
288 depthAttachment.storeAction =
289 mtlStoreAction[
static_cast<int>(depthStencilInfo.fStoreOp)];
292 auto stencilAttachment = (*descriptor).stencilAttachment;
293 stencilAttachment.texture = mtlTexture;
294 stencilAttachment.clearStencil = renderPassDesc.
fClearStencil;
295 stencilAttachment.loadAction =
296 mtlLoadAction[
static_cast<int>(depthStencilInfo.fLoadOp)];
297 stencilAttachment.storeAction =
298 mtlStoreAction[
static_cast<int>(depthStencilInfo.fStoreOp)];
301 SkASSERT(!depthStencilInfo.fTextureInfo.isValid());
305 fCommandBuffer.get(),
309 if (loadMSAAFromResolve) {
315 SKGPU_LOG_E(
"Unable to create pipeline to load resolve texture into MSAA attachment");
318 this->bindGraphicsPipeline(loadPipeline.get());
321 fActiveRenderCommandEncoder->setFragmentTexture(
322 ((
const MtlTexture*) resolveTexture)->mtlTexture(), 0);
329void MtlCommandBuffer::endRenderPass() {
330 SkASSERT(fActiveRenderCommandEncoder);
331 fActiveRenderCommandEncoder->endEncoding();
332 fActiveRenderCommandEncoder.reset();
333 fDrawIsOffscreen =
false;
336void MtlCommandBuffer::addDrawPass(
const DrawPass* drawPass) {
346 drawPass->addResourceRefs(
this);
350 if (fDrawIsOffscreen) {
352 case DrawPassCommands::Type::kDraw:
353 case DrawPassCommands::Type::kDrawIndexed:
354 case DrawPassCommands::Type::kDrawInstanced:
355 case DrawPassCommands::Type::kDrawIndexedInstanced:
363 case DrawPassCommands::Type::kBindGraphicsPipeline: {
364 auto bgp =
static_cast<DrawPassCommands::BindGraphicsPipeline*
>(cmdPtr);
365 this->bindGraphicsPipeline(drawPass->getPipeline(bgp->fPipelineIndex));
368 case DrawPassCommands::Type::kSetBlendConstants: {
369 auto sbc =
static_cast<DrawPassCommands::SetBlendConstants*
>(cmdPtr);
370 this->setBlendConstants(sbc->fBlendConstants);
373 case DrawPassCommands::Type::kBindUniformBuffer: {
374 auto bub =
static_cast<DrawPassCommands::BindUniformBuffer*
>(cmdPtr);
375 this->bindUniformBuffer(bub->fInfo, bub->fSlot);
378 case DrawPassCommands::Type::kBindDrawBuffers: {
379 auto bdb =
static_cast<DrawPassCommands::BindDrawBuffers*
>(cmdPtr);
380 this->bindDrawBuffers(
381 bdb->fVertices, bdb->fInstances, bdb->fIndices, bdb->fIndirect);
384 case DrawPassCommands::Type::kBindTexturesAndSamplers: {
385 auto bts =
static_cast<DrawPassCommands::BindTexturesAndSamplers*
>(cmdPtr);
386 for (
int j = 0; j < bts->fNumTexSamplers; ++j) {
387 this->bindTextureAndSampler(drawPass->getTexture(bts->fTextureIndices[j]),
388 drawPass->getSampler(bts->fSamplerIndices[j]),
393 case DrawPassCommands::Type::kSetScissor: {
394 auto ss =
static_cast<DrawPassCommands::SetScissor*
>(cmdPtr);
399 case DrawPassCommands::Type::kDraw: {
400 auto draw =
static_cast<DrawPassCommands::Draw*
>(cmdPtr);
401 this->draw(draw->fType, draw->fBaseVertex, draw->fVertexCount);
404 case DrawPassCommands::Type::kDrawIndexed: {
405 auto draw =
static_cast<DrawPassCommands::DrawIndexed*
>(cmdPtr);
406 this->drawIndexed(draw->fType,
412 case DrawPassCommands::Type::kDrawInstanced: {
413 auto draw =
static_cast<DrawPassCommands::DrawInstanced*
>(cmdPtr);
414 this->drawInstanced(draw->fType,
418 draw->fInstanceCount);
421 case DrawPassCommands::Type::kDrawIndexedInstanced: {
422 auto draw =
static_cast<DrawPassCommands::DrawIndexedInstanced*
>(cmdPtr);
423 this->drawIndexedInstanced(draw->fType,
428 draw->fInstanceCount);
431 case DrawPassCommands::Type::kDrawIndirect: {
432 auto draw =
static_cast<DrawPassCommands::DrawIndirect*
>(cmdPtr);
433 this->drawIndirect(draw->fType);
436 case DrawPassCommands::Type::kDrawIndexedIndirect: {
437 auto draw =
static_cast<DrawPassCommands::DrawIndexedIndirect*
>(cmdPtr);
438 this->drawIndexedIndirect(draw->fType);
445MtlBlitCommandEncoder* MtlCommandBuffer::getBlitCommandEncoder() {
446 if (fActiveBlitCommandEncoder) {
447 return fActiveBlitCommandEncoder.get();
452 if (!fActiveBlitCommandEncoder) {
459 return fActiveBlitCommandEncoder.get();
462void MtlCommandBuffer::endBlitCommandEncoder() {
463 if (fActiveBlitCommandEncoder) {
464 fActiveBlitCommandEncoder->endEncoding();
465 fActiveBlitCommandEncoder.reset();
469void MtlCommandBuffer::bindGraphicsPipeline(
const GraphicsPipeline* graphicsPipeline) {
470 SkASSERT(fActiveRenderCommandEncoder);
472 auto mtlPipeline =
static_cast<const MtlGraphicsPipeline*
>(graphicsPipeline);
473 auto pipelineState = mtlPipeline->mtlPipelineState();
474 fActiveRenderCommandEncoder->setRenderPipelineState(pipelineState);
475 auto depthStencilState = mtlPipeline->mtlDepthStencilState();
476 fActiveRenderCommandEncoder->setDepthStencilState(depthStencilState);
477 uint32_t stencilRefValue = mtlPipeline->stencilReferenceValue();
478 fActiveRenderCommandEncoder->setStencilReferenceValue(stencilRefValue);
481void MtlCommandBuffer::bindUniformBuffer(
const BindBufferInfo&
info,
UniformSlot slot) {
482 SkASSERT(fActiveRenderCommandEncoder);
484 id<MTLBuffer> mtlBuffer =
info.fBuffer ?
485 static_cast<const MtlBuffer*
>(
info.fBuffer)->mtlBuffer() :
nullptr;
487 unsigned int bufferIndex;
497 fActiveRenderCommandEncoder->setVertexBuffer(mtlBuffer,
info.fOffset, bufferIndex);
498 fActiveRenderCommandEncoder->setFragmentBuffer(mtlBuffer,
info.fOffset, bufferIndex);
501void MtlCommandBuffer::bindDrawBuffers(
const BindBufferInfo& vertices,
502 const BindBufferInfo& instances,
503 const BindBufferInfo& indices,
504 const BindBufferInfo& indirect) {
505 this->bindVertexBuffers(vertices.fBuffer,
509 this->bindIndexBuffer(indices.fBuffer, indices.fOffset);
510 this->bindIndirectBuffer(indirect.fBuffer, indirect.fOffset);
513void MtlCommandBuffer::bindVertexBuffers(
const Buffer* vertexBuffer,
515 const Buffer* instanceBuffer,
516 size_t instanceOffset) {
517 SkASSERT(fActiveRenderCommandEncoder);
520 id<MTLBuffer> mtlBuffer =
static_cast<const MtlBuffer*
>(vertexBuffer)->mtlBuffer();
523 SkASSERT((vertexOffset & 0b11) == 0);
524 fActiveRenderCommandEncoder->setVertexBuffer(mtlBuffer, vertexOffset,
527 if (instanceBuffer) {
528 id<MTLBuffer> mtlBuffer =
static_cast<const MtlBuffer*
>(instanceBuffer)->mtlBuffer();
529 SkASSERT((instanceOffset & 0b11) == 0);
530 fActiveRenderCommandEncoder->setVertexBuffer(mtlBuffer, instanceOffset,
535void MtlCommandBuffer::bindIndexBuffer(
const Buffer* indexBuffer,
size_t offset) {
537 fCurrentIndexBuffer =
static_cast<const MtlBuffer*
>(indexBuffer)->mtlBuffer();
538 fCurrentIndexBufferOffset =
offset;
540 fCurrentIndexBuffer = nil;
541 fCurrentIndexBufferOffset = 0;
545void MtlCommandBuffer::bindIndirectBuffer(
const Buffer* indirectBuffer,
size_t offset) {
546 if (indirectBuffer) {
547 fCurrentIndirectBuffer =
static_cast<const MtlBuffer*
>(indirectBuffer)->mtlBuffer();
548 fCurrentIndirectBufferOffset =
offset;
550 fCurrentIndirectBuffer = nil;
551 fCurrentIndirectBufferOffset = 0;
555void MtlCommandBuffer::bindTextureAndSampler(
const Texture*
texture,
556 const Sampler* sampler,
557 unsigned int bindIndex) {
559 SkASSERT(fActiveRenderCommandEncoder);
561 id<MTLTexture> mtlTexture = ((
const MtlTexture*)
texture)->mtlTexture();
562 id<MTLSamplerState> mtlSamplerState = ((
const MtlSampler*)sampler)->mtlSamplerState();
563 fActiveRenderCommandEncoder->setFragmentTexture(mtlTexture, bindIndex);
564 fActiveRenderCommandEncoder->setFragmentSamplerState(mtlSamplerState, bindIndex);
567void MtlCommandBuffer::setScissor(
unsigned int left,
unsigned int top,
569 SkASSERT(fActiveRenderCommandEncoder);
573 if (fDrawIsOffscreen) {
577 fActiveRenderCommandEncoder->setScissorRect({
578 static_cast<unsigned int>(scissor.
x()),
579 static_cast<unsigned int>(scissor.
y()),
580 static_cast<unsigned int>(scissor.
width()),
581 static_cast<unsigned int>(scissor.
height()),
585void MtlCommandBuffer::setViewport(
float x,
float y,
float width,
float height,
586 float minDepth,
float maxDepth) {
587 SkASSERT(fActiveRenderCommandEncoder);
594 fActiveRenderCommandEncoder->setViewport(viewport);
596 float invTwoW = 2.f /
width;
597 float invTwoH = 2.f /
height;
601 float rtAdjust[4] = {invTwoW, -invTwoH, -1.f -
x * invTwoW, 1.f +
y * invTwoH};
602 fActiveRenderCommandEncoder->setVertexBytes(rtAdjust, 4 *
sizeof(
float),
606void MtlCommandBuffer::setBlendConstants(
float* blendConstants) {
607 SkASSERT(fActiveRenderCommandEncoder);
609 fActiveRenderCommandEncoder->setBlendColor(blendConstants);
613 const static MTLPrimitiveType mtlPrimitiveType[] {
614 MTLPrimitiveTypeTriangle,
615 MTLPrimitiveTypeTriangleStrip,
616 MTLPrimitiveTypePoint,
623 return mtlPrimitiveType[
static_cast<int>(primitiveType)];
627 unsigned int baseVertex,
628 unsigned int vertexCount) {
629 SkASSERT(fActiveRenderCommandEncoder);
633 fActiveRenderCommandEncoder->drawPrimitives(mtlPrimitiveType, baseVertex, vertexCount);
637 unsigned int indexCount,
unsigned int baseVertex) {
638 SkASSERT(fActiveRenderCommandEncoder);
640 if (@available(macOS 10.11, iOS 9.0, tvOS 9.0, *)) {
642 size_t indexOffset = fCurrentIndexBufferOffset +
sizeof(uint16_t )* baseIndex;
645 fActiveRenderCommandEncoder->drawIndexedPrimitives(mtlPrimitiveType, indexCount,
646 MTLIndexTypeUInt16, fCurrentIndexBuffer,
647 indexOffset, 1, baseVertex, 0);
655 unsigned int vertexCount,
unsigned int baseInstance,
656 unsigned int instanceCount) {
657 SkASSERT(fActiveRenderCommandEncoder);
662 fActiveRenderCommandEncoder->drawPrimitives(mtlPrimitiveType, baseVertex, vertexCount,
663 instanceCount, baseInstance);
667 unsigned int baseIndex,
668 unsigned int indexCount,
669 unsigned int baseVertex,
670 unsigned int baseInstance,
671 unsigned int instanceCount) {
672 SkASSERT(fActiveRenderCommandEncoder);
674 if (@available(macOS 10.11, iOS 9.0, tvOS 9.0, *)) {
676 size_t indexOffset = fCurrentIndexBufferOffset +
sizeof(uint16_t) * baseIndex;
677 fActiveRenderCommandEncoder->drawIndexedPrimitives(mtlPrimitiveType, indexCount,
678 MTLIndexTypeUInt16, fCurrentIndexBuffer,
679 indexOffset, instanceCount,
680 baseVertex, baseInstance);
687 SkASSERT(fActiveRenderCommandEncoder);
690 if (@available(macOS 10.11, iOS 9.0, tvOS 9.0, *)) {
692 fActiveRenderCommandEncoder->drawPrimitives(
693 mtlPrimitiveType, fCurrentIndirectBuffer, fCurrentIndirectBufferOffset);
700 SkASSERT(fActiveRenderCommandEncoder);
703 if (@available(macOS 10.11, iOS 9.0, tvOS 9.0, *)) {
705 fActiveRenderCommandEncoder->drawIndexedPrimitives(mtlPrimitiveType,
708 fCurrentIndexBufferOffset,
709 fCurrentIndirectBuffer,
710 fCurrentIndirectBufferOffset);
716void MtlCommandBuffer::beginComputePass() {
717 SkASSERT(!fActiveRenderCommandEncoder);
718 SkASSERT(!fActiveComputeCommandEncoder);
719 this->endBlitCommandEncoder();
721 fCommandBuffer.get());
724void MtlCommandBuffer::bindComputePipeline(
const ComputePipeline* computePipeline) {
725 SkASSERT(fActiveComputeCommandEncoder);
727 auto mtlPipeline =
static_cast<const MtlComputePipeline*
>(computePipeline);
728 fActiveComputeCommandEncoder->setComputePipelineState(mtlPipeline->mtlPipelineState());
731void MtlCommandBuffer::bindBuffer(
const Buffer*
buffer,
unsigned int offset,
unsigned int index) {
732 SkASSERT(fActiveComputeCommandEncoder);
734 id<MTLBuffer> mtlBuffer =
buffer ?
static_cast<const MtlBuffer*
>(
buffer)->mtlBuffer() : nil;
735 fActiveComputeCommandEncoder->setBuffer(mtlBuffer,
offset, index);
738void MtlCommandBuffer::bindTexture(
const Texture*
texture,
unsigned int index) {
739 SkASSERT(fActiveComputeCommandEncoder);
741 id<MTLTexture> mtlTexture =
742 texture ?
static_cast<const MtlTexture*
>(
texture)->mtlTexture() : nil;
743 fActiveComputeCommandEncoder->setTexture(mtlTexture, index);
746void MtlCommandBuffer::bindSampler(
const Sampler* sampler,
unsigned int index) {
747 SkASSERT(fActiveComputeCommandEncoder);
749 id<MTLSamplerState> mtlSamplerState =
750 sampler ?
static_cast<const MtlSampler*
>(sampler)->mtlSamplerState() : nil;
751 fActiveComputeCommandEncoder->setSamplerState(mtlSamplerState, index);
754void MtlCommandBuffer::dispatchThreadgroups(
const WorkgroupSize& globalSize,
755 const WorkgroupSize& localSize) {
756 SkASSERT(fActiveComputeCommandEncoder);
757 fActiveComputeCommandEncoder->dispatchThreadgroups(globalSize, localSize);
760void MtlCommandBuffer::dispatchThreadgroupsIndirect(
const WorkgroupSize& localSize,
761 const Buffer* indirectBuffer,
762 size_t indirectBufferOffset) {
763 SkASSERT(fActiveComputeCommandEncoder);
765 id<MTLBuffer> mtlIndirectBuffer =
static_cast<const MtlBuffer*
>(indirectBuffer)->mtlBuffer();
766 fActiveComputeCommandEncoder->dispatchThreadgroupsWithIndirectBuffer(
767 mtlIndirectBuffer, indirectBufferOffset, localSize);
770void MtlCommandBuffer::endComputePass() {
771 SkASSERT(fActiveComputeCommandEncoder);
772 fActiveComputeCommandEncoder->endEncoding();
773 fActiveComputeCommandEncoder.reset();
777 if (widthInPixels > 32767) {
789 SkASSERT(!fActiveRenderCommandEncoder);
790 SkASSERT(!fActiveComputeCommandEncoder);
792 id<MTLBuffer> mtlSrcBuffer =
static_cast<const MtlBuffer*
>(srcBuffer)->mtlBuffer();
793 id<MTLBuffer> mtlDstBuffer =
static_cast<const MtlBuffer*
>(dstBuffer)->mtlBuffer();
796 if (!blitCmdEncoder) {
800#ifdef SK_ENABLE_MTL_DEBUG_INFO
803 blitCmdEncoder->
copyBufferToBuffer(mtlSrcBuffer, srcOffset, mtlDstBuffer, dstOffset, size);
804#ifdef SK_ENABLE_MTL_DEBUG_INFO
814 size_t bufferRowBytes) {
815 SkASSERT(!fActiveRenderCommandEncoder);
816 SkASSERT(!fActiveComputeCommandEncoder);
822 id<MTLTexture> mtlTexture =
static_cast<const MtlTexture*
>(
texture)->mtlTexture();
823 id<MTLBuffer> mtlBuffer =
static_cast<const MtlBuffer*
>(
buffer)->mtlBuffer();
826 if (!blitCmdEncoder) {
830#ifdef SK_ENABLE_MTL_DEBUG_INFO
833 blitCmdEncoder->
copyFromTexture(mtlTexture, srcRect, mtlBuffer, bufferOffset, bufferRowBytes);
834#ifdef SK_ENABLE_MTL_DEBUG_INFO
844 SkASSERT(!fActiveRenderCommandEncoder);
845 SkASSERT(!fActiveComputeCommandEncoder);
847 id<MTLBuffer> mtlBuffer =
static_cast<const MtlBuffer*
>(
buffer)->mtlBuffer();
848 id<MTLTexture> mtlTexture =
static_cast<const MtlTexture*
>(
texture)->mtlTexture();
851 if (!blitCmdEncoder) {
855#ifdef SK_ENABLE_MTL_DEBUG_INFO
858 for (
int i = 0; i <
count; ++i) {
864 copyData[i].fBufferOffset,
865 copyData[i].fBufferRowBytes,
868 copyData[i].fMipLevel);
871#ifdef SK_ENABLE_MTL_DEBUG_INFO
882 SkASSERT(!fActiveRenderCommandEncoder);
883 SkASSERT(!fActiveComputeCommandEncoder);
885 id<MTLTexture> srcMtlTexture =
static_cast<const MtlTexture*
>(src)->mtlTexture();
886 id<MTLTexture> dstMtlTexture =
static_cast<const MtlTexture*
>(dst)->mtlTexture();
889 if (!blitCmdEncoder) {
893#ifdef SK_ENABLE_MTL_DEBUG_INFO
897 blitCmdEncoder->
copyTextureToTexture(srcMtlTexture, srcRect, dstMtlTexture, dstPoint, mipLevel);
899#ifdef SK_ENABLE_MTL_DEBUG_INFO
906#ifdef SK_BUILD_FOR_MAC
907 SkASSERT(!fActiveRenderCommandEncoder);
908 SkASSERT(!fActiveComputeCommandEncoder);
910 id<MTLBuffer> mtlBuffer =
static_cast<const MtlBuffer*
>(
buffer)->mtlBuffer();
911 if ([mtlBuffer storageMode] != MTLStorageModeManaged) {
912 *outDidResultInWork =
false;
917 if (!blitCmdEncoder) {
921#ifdef SK_ENABLE_MTL_DEBUG_INFO
924 blitCmdEncoder->synchronizeResource(mtlBuffer);
925#ifdef SK_ENABLE_MTL_DEBUG_INFO
929 *outDidResultInWork =
true;
934 *outDidResultInWork =
false;
940 SkASSERT(!fActiveRenderCommandEncoder);
941 SkASSERT(!fActiveComputeCommandEncoder);
944 if (!blitCmdEncoder) {
948 id<MTLBuffer> mtlBuffer =
static_cast<const MtlBuffer*
>(
buffer)->mtlBuffer();
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
#define SKGPU_LOG_E(fmt,...)
static constexpr size_t SkAlignTo(size_t x, size_t alignment)
static bool left(const SkPoint &p0, const SkPoint &p1)
Type::kYUV Type::kRGBA() int(0.7 *637)
SkIVector fReplayTranslation
void trackResource(sk_sp< Resource > resource)
void fillBuffer(id< MTLBuffer > buffer, size_t bufferOffset, size_t bytes, uint8_t value)
void pushDebugGroup(NSString *string)
static sk_sp< MtlBlitCommandEncoder > Make(const SharedContext *sharedContext, id< MTLCommandBuffer > commandBuffer)
void copyFromTexture(id< MTLTexture > texture, SkIRect srcRect, id< MTLBuffer > buffer, size_t bufferOffset, size_t bufferRowBytes)
void copyTextureToTexture(id< MTLTexture > srcTexture, SkIRect srcRect, id< MTLTexture > dstTexture, SkIPoint dstPoint, int mipLevel)
void copyBufferToBuffer(id< MTLBuffer > srcBuffer, size_t srcOffset, id< MTLBuffer > dstBuffer, size_t dstOffset, size_t size)
void copyFromBuffer(id< MTLBuffer > buffer, size_t bufferOffset, size_t bufferRowBytes, id< MTLTexture > texture, SkIRect dstRect, unsigned int dstLevel)
void addWaitSemaphores(size_t numWaitSemaphores, const BackendSemaphore *waitSemaphores) override
bool onSynchronizeBufferToCpu(const Buffer *, bool *outDidResultInWork) override
~MtlCommandBuffer() override
bool onCopyBufferToTexture(const Buffer *, const Texture *, const BufferTextureCopyData *copyData, int count) override
bool onCopyTextureToBuffer(const Texture *, SkIRect srcRect, const Buffer *, size_t bufferOffset, size_t bufferRowBytes) override
void addSignalSemaphores(size_t numSignalSemaphores, const BackendSemaphore *signalSemaphores) override
static std::unique_ptr< MtlCommandBuffer > Make(id< MTLCommandQueue >, const MtlSharedContext *, MtlResourceProvider *)
void onResetCommandBuffer() override
bool onCopyTextureToTexture(const Texture *src, SkIRect srcRect, const Texture *dst, SkIPoint dstPoint, int mipLevel) override
bool onCopyBufferToBuffer(const Buffer *srcBuffer, size_t srcOffset, const Buffer *dstBuffer, size_t dstOffset, size_t size) override
bool onAddComputePass(DispatchGroupSpan) override
bool onClearBuffer(const Buffer *, size_t offset, size_t size) override
bool setNewCommandBufferResources() override
bool onAddRenderPass(const RenderPassDesc &, const Texture *colorTexture, const Texture *resolveTexture, const Texture *depthStencilTexture, SkRect viewport, const DrawPassList &) override
static sk_sp< MtlComputeCommandEncoder > Make(const SharedContext *sharedContext, id< MTLCommandBuffer > commandBuffer)
static constexpr unsigned int kVertexBufferIndex
static constexpr unsigned int kInstanceBufferIndex
static constexpr unsigned int kPaintUniformBufferIndex
static constexpr unsigned int kRenderStepUniformBufferIndex
static constexpr unsigned int kIntrinsicUniformBufferIndex
static sk_sp< MtlRenderCommandEncoder > Make(const SharedContext *sharedContext, id< MTLCommandBuffer > commandBuffer, MTLRenderPassDescriptor *descriptor)
sk_sp< MtlGraphicsPipeline > findOrCreateLoadMSAAPipeline(const RenderPassDesc &)
static const uint8_t buffer[]
sk_sp< SkBlender > blender SkRect rect
static constexpr int kLoadOpCount
static bool check_max_blit_width(int widthInPixels)
static constexpr int kStoreOpCount
static MTLPrimitiveType graphite_to_mtl_primitive(PrimitiveType primitiveType)
bool MtlFormatIsStencil(MTLPixelFormat format)
bool MtlFormatIsDepth(MTLPixelFormat format)
constexpr int32_t y() const
constexpr int32_t x() const
constexpr int32_t x() const
constexpr int32_t y() const
bool intersect(const SkIRect &r)
static bool Intersects(const SkIRect &a, const SkIRect &b)
constexpr int32_t height() const
static constexpr SkIRect MakeSize(const SkISize &size)
constexpr int32_t width() const
constexpr SkIRect makeOffset(int32_t dx, int32_t dy) const
static constexpr SkIRect MakeXYWH(int32_t x, int32_t y, int32_t w, int32_t h)
constexpr float x() const
constexpr float y() const
constexpr float height() const
constexpr float width() const
AttachmentDesc fDepthStencilAttachment
AttachmentDesc fColorResolveAttachment
std::array< float, 4 > fClearColor
AttachmentDesc fColorAttachment