代码之家  ›  专栏  ›  技术社区  ›  kennyc

命令编码器之间的同步何时需要MTLFence或MTLEvent?

  •  0
  • kennyc  · 技术社区  · 6 年前

    注意:在许多方面,这是对 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];
    
      // Is synchronization with the blit encoder required here? 
      // 
      // The fragment shader is going to sample from masterTexture and will
      // expect that the blit command above will have been completed.
    
      [renderEncoder setFragmentTexture:masterTexture atIndex:0];
    
      [renderEncoder drawPrimitives:...];
      [commandBuffer commit];
    }
    

    previous question ,我相信答案是“不”。但看看苹果使用围栏和事件的示例代码,我相信答案是肯定的。

    如果不需要同步,那么这个伪代码和苹果的示例代码有什么不同?

    多亏了Ken在下面的回答,我很快在苹果开发者论坛上找到了一条相关的线索,涵盖了这个确切的问题。

    苹果开发者论坛: MTLFence detailed behaviour?

    正如Ken正确指出的,需要理解的关键细节是跟踪纹理和未跟踪纹理之间的区别。

    1 回复  |  直到 6 年前
        1
  •  4
  •   Community CDub    4 年前

    只有Metal不会自动跟踪的资源才需要手动同步。从分配的资源 MTLHeap 不会自动跟踪。使用 MTLResourceHazardTrackingModeUntracked 选项也未跟踪。

    Optimize Resource Allocation and Performance

    当从设备分配资源时,Metal创建并跟踪附加状态,以确保在需要给定资源的任何命令缓冲区的整个生命周期内分配、同步资源内存并使其可用。即使资源本身在命令缓冲区开始执行之前被销毁,它也会这样做。

    尽管Metal也对堆执行此过程,但它对堆内的资源不执行此过程。相反,当应用程序从堆中创建对象并重用内存时,它必须执行显式细粒度同步。