注意:在许多方面,这是对
How do you synchronize a Metal Performance Shader with an MTLBlitCommandEncoder?
当顺序命令编码器之间需要显式同步时,以及由于Metal的体系结构而不需要同步时,我仍然有点困惑。
在上面链接的问题中,引用了苹果的文档:
记忆障碍
在命令编码器之间
在给定命令编码器中执行的所有资源写入在下一个命令编码器中可见。这对于渲染和计算命令编码器都是正确的。
MTLRenderCommandEncoder
不需要与上一个服务器显式同步
MTLBlitCommandEncoder
如果它们都在同一个命令缓冲区中,并且一个接一个地出现。
出现
反驳这一点。在里面
Image Filter Graph with Heaps and Fences
MTLFence
MTLBitCommandEncoder
然后是两个连续的
MTLComputeCommandEncoder
电话(一个用于水平模糊,另一个用于垂直模糊。)
See:
AAPLFilter.m (L:199)
AAPLRenderer.m (L:413)
MTLComputer命令编码器
blit
如前所述,如果“在给定命令编码器中执行的所有资源写入在下一个命令编码器中可见”,则第二个计算编码器为什么需要等待第一个计算编码器?
伪示例代码:
- (void)drawInMTKView:(nonnull MTKView *)view {
id <MTLCommandBuffer> commandBuffer = [_commandQueue commandBuffer];
id<MTLTexture> masterTexture = self.masterTexture;
id<MTLTexture> incomingTexture = [self dequeueRenderedTextureIfPresent];
id<MTLBlitCommandEncoder> blitEncoder = commandBuffer.blitCommandEncoder;
[blitEncoder copyFromTexture:incomingTexture ... toTexture:masterTexture];
[blitEncoder endEncoding];
id <MTLRenderCommandEncoder> renderEncoder = [commandBuffer renderCommandEncoderWithDescriptor];
[renderEncoder setFragmentTexture:masterTexture atIndex:0];
[renderEncoder drawPrimitives:...];
[commandBuffer commit];
}
previous question
,我相信答案是“不”。但看看苹果使用围栏和事件的示例代码,我相信答案是肯定的。
如果不需要同步,那么这个伪代码和苹果的示例代码有什么不同?
多亏了Ken在下面的回答,我很快在苹果开发者论坛上找到了一条相关的线索,涵盖了这个确切的问题。
苹果开发者论坛:
MTLFence detailed behaviour?
正如Ken正确指出的,需要理解的关键细节是跟踪纹理和未跟踪纹理之间的区别。