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);
98void MtlCommandBuffer::onResetCommandBuffer() {
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()];
154bool MtlCommandBuffer::onAddRenderPass(
const RenderPassDesc& renderPassDesc,
157 const Texture* depthStencilTexture,
159 const DrawPassList& drawPasses) {
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();
174bool MtlCommandBuffer::onAddComputePass(DispatchGroupSpan groups) {
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)) {
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);
194 for (
const ComputeStep::WorkgroupBufferDesc& wgBuf : dispatch.fWorkgroupBuffers) {
195 fActiveComputeCommandEncoder->setThreadgroupMemoryLength(
199 if (
const WorkgroupSize* globalSize =
200 std::get_if<WorkgroupSize>(&dispatch.fGlobalSizeOrIndirect)) {
201 this->dispatchThreadgroups(*globalSize, dispatch.fLocalSize);
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);
211 this->endComputePass();
215bool MtlCommandBuffer::beginRenderPass(
const RenderPassDesc& renderPassDesc,
216 const Texture* colorTexture,
217 const Texture* resolveTexture,
218 const Texture* depthStencilTexture) {
219 SkASSERT(!fActiveRenderCommandEncoder);
220 SkASSERT(!fActiveComputeCommandEncoder);
221 this->endBlitCommandEncoder();
223 const static MTLLoadAction mtlLoadAction[] {
226 MTLLoadActionDontCare
233 const static MTLStoreAction mtlStoreAction[] {
235 MTLStoreActionDontCare
241 sk_cfp<MTLRenderPassDescriptor*> descriptor([[MTLRenderPassDescriptor alloc]
init]);
243 auto& colorInfo = renderPassDesc.fColorAttachment;
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;
270 loadMSAAFromResolve = renderPassDesc.fColorResolveAttachment.fLoadOp ==
LoadOp::kLoad;
278 auto& depthStencilInfo = renderPassDesc.fDepthStencilAttachment;
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);
348 for (
auto[
type, cmdPtr] : drawPass->commands()) {
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: {
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;
500 fActiveRenderCommandEncoder->setVertexBuffer(mtlBuffer,
info.fOffset, bufferIndex);
501 fActiveRenderCommandEncoder->setFragmentBuffer(mtlBuffer,
info.fOffset, bufferIndex);
504void MtlCommandBuffer::bindDrawBuffers(
const BindBufferInfo& vertices,
505 const BindBufferInfo& instances,
506 const BindBufferInfo& indices,
507 const BindBufferInfo& indirect) {
508 this->bindVertexBuffers(vertices.fBuffer,
512 this->bindIndexBuffer(indices.fBuffer, indices.fOffset);
513 this->bindIndirectBuffer(indirect.fBuffer, indirect.fOffset);
516void MtlCommandBuffer::bindVertexBuffers(
const Buffer* vertexBuffer,
518 const Buffer* instanceBuffer,
519 size_t instanceOffset) {
520 SkASSERT(fActiveRenderCommandEncoder);
523 id<MTLBuffer> mtlBuffer =
static_cast<const MtlBuffer*
>(vertexBuffer)->mtlBuffer();
526 SkASSERT((vertexOffset & 0b11) == 0);
527 fActiveRenderCommandEncoder->setVertexBuffer(mtlBuffer, vertexOffset,
530 if (instanceBuffer) {
531 id<MTLBuffer> mtlBuffer =
static_cast<const MtlBuffer*
>(instanceBuffer)->mtlBuffer();
532 SkASSERT((instanceOffset & 0b11) == 0);
533 fActiveRenderCommandEncoder->setVertexBuffer(mtlBuffer, instanceOffset,
538void MtlCommandBuffer::bindIndexBuffer(
const Buffer* indexBuffer,
size_t offset) {
540 fCurrentIndexBuffer =
static_cast<const MtlBuffer*
>(indexBuffer)->mtlBuffer();
541 fCurrentIndexBufferOffset =
offset;
543 fCurrentIndexBuffer = nil;
544 fCurrentIndexBufferOffset = 0;
548void MtlCommandBuffer::bindIndirectBuffer(
const Buffer* indirectBuffer,
size_t offset) {
549 if (indirectBuffer) {
550 fCurrentIndirectBuffer =
static_cast<const MtlBuffer*
>(indirectBuffer)->mtlBuffer();
551 fCurrentIndirectBufferOffset =
offset;
553 fCurrentIndirectBuffer = nil;
554 fCurrentIndirectBufferOffset = 0;
558void MtlCommandBuffer::bindTextureAndSampler(
const Texture*
texture,
560 unsigned int bindIndex) {
562 SkASSERT(fActiveRenderCommandEncoder);
564 id<MTLTexture> mtlTexture = ((
const MtlTexture*)
texture)->mtlTexture();
565 id<MTLSamplerState> mtlSamplerState = ((
const MtlSampler*)sampler)->mtlSamplerState();
566 fActiveRenderCommandEncoder->setFragmentTexture(mtlTexture, bindIndex);
567 fActiveRenderCommandEncoder->setFragmentSamplerState(mtlSamplerState, bindIndex);
570void MtlCommandBuffer::setScissor(
unsigned int left,
unsigned int top,
572 SkASSERT(fActiveRenderCommandEncoder);
576 if (fDrawIsOffscreen) {
580 fActiveRenderCommandEncoder->setScissorRect({
581 static_cast<unsigned int>(scissor.
x()),
582 static_cast<unsigned int>(scissor.
y()),
583 static_cast<unsigned int>(scissor.
width()),
584 static_cast<unsigned int>(scissor.
height()),
588void MtlCommandBuffer::setViewport(
float x,
float y,
float width,
float height,
589 float minDepth,
float maxDepth) {
590 SkASSERT(fActiveRenderCommandEncoder);
597 fActiveRenderCommandEncoder->setViewport(viewport);
599 float invTwoW = 2.f /
width;
600 float invTwoH = 2.f /
height;
604 float rtAdjust[4] = {invTwoW, -invTwoH, -1.f -
x * invTwoW, 1.f +
y * invTwoH};
605 fActiveRenderCommandEncoder->setVertexBytes(rtAdjust, 4 *
sizeof(
float),
609void MtlCommandBuffer::setBlendConstants(
float* blendConstants) {
610 SkASSERT(fActiveRenderCommandEncoder);
612 fActiveRenderCommandEncoder->setBlendColor(blendConstants);
616 const static MTLPrimitiveType mtlPrimitiveType[] {
617 MTLPrimitiveTypeTriangle,
618 MTLPrimitiveTypeTriangleStrip,
619 MTLPrimitiveTypePoint,
626 return mtlPrimitiveType[
static_cast<int>(primitiveType)];
630 unsigned int baseVertex,
631 unsigned int vertexCount) {
632 SkASSERT(fActiveRenderCommandEncoder);
636 fActiveRenderCommandEncoder->drawPrimitives(mtlPrimitiveType, baseVertex, vertexCount);
640 unsigned int indexCount,
unsigned int baseVertex) {
641 SkASSERT(fActiveRenderCommandEncoder);
643 if (@available(macOS 10.11, iOS 9.0, tvOS 9.0, *)) {
645 size_t indexOffset = fCurrentIndexBufferOffset +
sizeof(uint16_t )* baseIndex;
648 fActiveRenderCommandEncoder->drawIndexedPrimitives(mtlPrimitiveType, indexCount,
649 MTLIndexTypeUInt16, fCurrentIndexBuffer,
650 indexOffset, 1, baseVertex, 0);
658 unsigned int vertexCount,
unsigned int baseInstance,
659 unsigned int instanceCount) {
660 SkASSERT(fActiveRenderCommandEncoder);
665 fActiveRenderCommandEncoder->drawPrimitives(mtlPrimitiveType, baseVertex, vertexCount,
666 instanceCount, baseInstance);
670 unsigned int baseIndex,
671 unsigned int indexCount,
672 unsigned int baseVertex,
673 unsigned int baseInstance,
674 unsigned int instanceCount) {
675 SkASSERT(fActiveRenderCommandEncoder);
677 if (@available(macOS 10.11, iOS 9.0, tvOS 9.0, *)) {
679 size_t indexOffset = fCurrentIndexBufferOffset +
sizeof(uint16_t) * baseIndex;
680 fActiveRenderCommandEncoder->drawIndexedPrimitives(mtlPrimitiveType, indexCount,
681 MTLIndexTypeUInt16, fCurrentIndexBuffer,
682 indexOffset, instanceCount,
683 baseVertex, baseInstance);
690 SkASSERT(fActiveRenderCommandEncoder);
693 if (@available(macOS 10.11, iOS 9.0, tvOS 9.0, *)) {
695 fActiveRenderCommandEncoder->drawPrimitives(
696 mtlPrimitiveType, fCurrentIndirectBuffer, fCurrentIndirectBufferOffset);
703 SkASSERT(fActiveRenderCommandEncoder);
706 if (@available(macOS 10.11, iOS 9.0, tvOS 9.0, *)) {
708 fActiveRenderCommandEncoder->drawIndexedPrimitives(mtlPrimitiveType,
711 fCurrentIndexBufferOffset,
712 fCurrentIndirectBuffer,
713 fCurrentIndirectBufferOffset);
719void MtlCommandBuffer::beginComputePass() {
720 SkASSERT(!fActiveRenderCommandEncoder);
721 SkASSERT(!fActiveComputeCommandEncoder);
722 this->endBlitCommandEncoder();
724 fCommandBuffer.get());
727void MtlCommandBuffer::bindComputePipeline(
const ComputePipeline* computePipeline) {
728 SkASSERT(fActiveComputeCommandEncoder);
730 auto mtlPipeline =
static_cast<const MtlComputePipeline*
>(computePipeline);
731 fActiveComputeCommandEncoder->setComputePipelineState(mtlPipeline->mtlPipelineState());
734void MtlCommandBuffer::bindBuffer(
const Buffer*
buffer,
unsigned int offset,
unsigned int index) {
735 SkASSERT(fActiveComputeCommandEncoder);
737 id<MTLBuffer> mtlBuffer =
buffer ?
static_cast<const MtlBuffer*
>(
buffer)->mtlBuffer() : nil;
738 fActiveComputeCommandEncoder->setBuffer(mtlBuffer,
offset, index);
741void MtlCommandBuffer::bindTexture(
const Texture*
texture,
unsigned int index) {
742 SkASSERT(fActiveComputeCommandEncoder);
744 id<MTLTexture> mtlTexture =
745 texture ?
static_cast<const MtlTexture*
>(
texture)->mtlTexture() : nil;
746 fActiveComputeCommandEncoder->setTexture(mtlTexture, index);
749void MtlCommandBuffer::bindSampler(
const Sampler* sampler,
unsigned int index) {
750 SkASSERT(fActiveComputeCommandEncoder);
752 id<MTLSamplerState> mtlSamplerState =
753 sampler ?
static_cast<const MtlSampler*
>(sampler)->mtlSamplerState() : nil;
754 fActiveComputeCommandEncoder->setSamplerState(mtlSamplerState, index);
757void MtlCommandBuffer::dispatchThreadgroups(
const WorkgroupSize& globalSize,
758 const WorkgroupSize& localSize) {
759 SkASSERT(fActiveComputeCommandEncoder);
760 fActiveComputeCommandEncoder->dispatchThreadgroups(globalSize, localSize);
763void MtlCommandBuffer::dispatchThreadgroupsIndirect(
const WorkgroupSize& localSize,
764 const Buffer* indirectBuffer,
765 size_t indirectBufferOffset) {
766 SkASSERT(fActiveComputeCommandEncoder);
768 id<MTLBuffer> mtlIndirectBuffer =
static_cast<const MtlBuffer*
>(indirectBuffer)->mtlBuffer();
769 fActiveComputeCommandEncoder->dispatchThreadgroupsWithIndirectBuffer(
770 mtlIndirectBuffer, indirectBufferOffset, localSize);
773void MtlCommandBuffer::endComputePass() {
774 SkASSERT(fActiveComputeCommandEncoder);
775 fActiveComputeCommandEncoder->endEncoding();
776 fActiveComputeCommandEncoder.reset();
780 if (widthInPixels > 32767) {
787bool MtlCommandBuffer::onCopyBufferToBuffer(
const Buffer* srcBuffer,
789 const Buffer* dstBuffer,
792 SkASSERT(!fActiveRenderCommandEncoder);
793 SkASSERT(!fActiveComputeCommandEncoder);
795 id<MTLBuffer> mtlSrcBuffer =
static_cast<const MtlBuffer*
>(srcBuffer)->mtlBuffer();
796 id<MTLBuffer> mtlDstBuffer =
static_cast<const MtlBuffer*
>(dstBuffer)->mtlBuffer();
798 MtlBlitCommandEncoder* blitCmdEncoder = this->getBlitCommandEncoder();
799 if (!blitCmdEncoder) {
803#ifdef SK_ENABLE_MTL_DEBUG_INFO
804 blitCmdEncoder->pushDebugGroup(
@"copyBufferToBuffer");
806 blitCmdEncoder->copyBufferToBuffer(mtlSrcBuffer, srcOffset, mtlDstBuffer, dstOffset,
size);
807#ifdef SK_ENABLE_MTL_DEBUG_INFO
808 blitCmdEncoder->popDebugGroup();
813bool MtlCommandBuffer::onCopyTextureToBuffer(
const Texture*
texture,
817 size_t bufferRowBytes) {
818 SkASSERT(!fActiveRenderCommandEncoder);
819 SkASSERT(!fActiveComputeCommandEncoder);
825 id<MTLTexture> mtlTexture =
static_cast<const MtlTexture*
>(
texture)->mtlTexture();
826 id<MTLBuffer> mtlBuffer =
static_cast<const MtlBuffer*
>(
buffer)->mtlBuffer();
828 MtlBlitCommandEncoder* blitCmdEncoder = this->getBlitCommandEncoder();
829 if (!blitCmdEncoder) {
833#ifdef SK_ENABLE_MTL_DEBUG_INFO
834 blitCmdEncoder->pushDebugGroup(
@"copyTextureToBuffer");
836 blitCmdEncoder->copyFromTexture(mtlTexture, srcRect, mtlBuffer, bufferOffset, bufferRowBytes);
837#ifdef SK_ENABLE_MTL_DEBUG_INFO
838 blitCmdEncoder->popDebugGroup();
843bool MtlCommandBuffer::onCopyBufferToTexture(
const Buffer*
buffer,
845 const BufferTextureCopyData* copyData,
847 SkASSERT(!fActiveRenderCommandEncoder);
848 SkASSERT(!fActiveComputeCommandEncoder);
850 id<MTLBuffer> mtlBuffer =
static_cast<const MtlBuffer*
>(
buffer)->mtlBuffer();
851 id<MTLTexture> mtlTexture =
static_cast<const MtlTexture*
>(
texture)->mtlTexture();
853 MtlBlitCommandEncoder* blitCmdEncoder = this->getBlitCommandEncoder();
854 if (!blitCmdEncoder) {
858#ifdef SK_ENABLE_MTL_DEBUG_INFO
859 blitCmdEncoder->pushDebugGroup(
@"copyBufferToTexture");
866 blitCmdEncoder->copyFromBuffer(mtlBuffer,
867 copyData[
i].fBufferOffset,
868 copyData[
i].fBufferRowBytes,
871 copyData[
i].fMipLevel);
874#ifdef SK_ENABLE_MTL_DEBUG_INFO
875 blitCmdEncoder->popDebugGroup();
880bool MtlCommandBuffer::onCopyTextureToTexture(
const Texture*
src,
885 SkASSERT(!fActiveRenderCommandEncoder);
886 SkASSERT(!fActiveComputeCommandEncoder);
888 id<MTLTexture> srcMtlTexture =
static_cast<const MtlTexture*
>(
src)->mtlTexture();
889 id<MTLTexture> dstMtlTexture =
static_cast<const MtlTexture*
>(
dst)->mtlTexture();
891 MtlBlitCommandEncoder* blitCmdEncoder = this->getBlitCommandEncoder();
892 if (!blitCmdEncoder) {
896#ifdef SK_ENABLE_MTL_DEBUG_INFO
897 blitCmdEncoder->pushDebugGroup(
@"copyTextureToTexture");
900 blitCmdEncoder->copyTextureToTexture(srcMtlTexture, srcRect, dstMtlTexture, dstPoint, mipLevel);
902#ifdef SK_ENABLE_MTL_DEBUG_INFO
903 blitCmdEncoder->popDebugGroup();
908bool MtlCommandBuffer::onSynchronizeBufferToCpu(
const Buffer*
buffer,
bool* outDidResultInWork) {
909#ifdef SK_BUILD_FOR_MAC
910 SkASSERT(!fActiveRenderCommandEncoder);
911 SkASSERT(!fActiveComputeCommandEncoder);
913 id<MTLBuffer> mtlBuffer =
static_cast<const MtlBuffer*
>(
buffer)->mtlBuffer();
914 if ([mtlBuffer storageMode] != MTLStorageModeManaged) {
915 *outDidResultInWork =
false;
919 MtlBlitCommandEncoder* blitCmdEncoder = this->getBlitCommandEncoder();
920 if (!blitCmdEncoder) {
924#ifdef SK_ENABLE_MTL_DEBUG_INFO
925 blitCmdEncoder->pushDebugGroup(
@"synchronizeToCpu");
927 blitCmdEncoder->synchronizeResource(mtlBuffer);
928#ifdef SK_ENABLE_MTL_DEBUG_INFO
929 blitCmdEncoder->popDebugGroup();
932 *outDidResultInWork =
true;
937 *outDidResultInWork =
false;
942bool MtlCommandBuffer::onClearBuffer(
const Buffer*
buffer,
size_t offset,
size_t size) {
943 SkASSERT(!fActiveRenderCommandEncoder);
944 SkASSERT(!fActiveComputeCommandEncoder);
946 MtlBlitCommandEncoder* blitCmdEncoder = this->getBlitCommandEncoder();
947 if (!blitCmdEncoder) {
951 id<MTLBuffer> mtlBuffer =
static_cast<const MtlBuffer*
>(
buffer)->mtlBuffer();
952 blitCmdEncoder->fillBuffer(mtlBuffer,
offset,
size, 0);
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)
SkIVector fReplayTranslation
void trackResource(sk_sp< Resource > resource)
static sk_sp< MtlBlitCommandEncoder > Make(const SharedContext *sharedContext, id< MTLCommandBuffer > commandBuffer)
void addWaitSemaphores(size_t numWaitSemaphores, const BackendSemaphore *waitSemaphores) override
~MtlCommandBuffer() override
void addSignalSemaphores(size_t numSignalSemaphores, const BackendSemaphore *signalSemaphores) override
static std::unique_ptr< MtlCommandBuffer > Make(id< MTLCommandQueue >, const MtlSharedContext *, MtlResourceProvider *)
bool setNewCommandBufferResources() 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 constexpr unsigned int kGradientBufferIndex
static sk_sp< MtlRenderCommandEncoder > Make(const SharedContext *sharedContext, id< MTLCommandBuffer > commandBuffer, MTLRenderPassDescriptor *descriptor)
sk_sp< MtlGraphicsPipeline > findOrCreateLoadMSAAPipeline(const RenderPassDesc &)
static void Draw(SkCanvas *canvas, const SkRect &rect)
sk_sp< SkBlender > blender SkRect rect
std::function< ProfileSample(void)> Sampler
Sampler is run during SamplingProfiler::SampleRepeatedly. Each platform should implement its version ...
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
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