Metal 最佳实践:三重缓冲 – 纹理?

Posted

技术标签:

【中文标题】Metal 最佳实践:三重缓冲 – 纹理?【英文标题】:Metal Best Practice: Triple-buffering – Textures too? 【发布时间】:2018-03-27 07:01:44 【问题描述】:

Metal Best Practices Guide 中,它指出为了获得最佳性能,应该“实施三重缓冲模型来更新动态缓冲区数据”,并且“动态缓冲区数据是指存储在缓冲区中的频繁更新的数据”。

如果需要每帧更新MTLTexture,它是否符合“存储在缓冲区中的频繁更新数据”的条件?以上指南中的所有示例都集中在MTLBuffers。

我注意到 Apple 在 MetalKit 中的实现有一个 nextDrawable 的概念,所以也许这就是这里发生的事情?

【问题讨论】:

【参考方案1】:

如果一个命令正在运行,并且它可以访问(读取/采样/写入)纹理,而您正在 CPU 上修改相同的纹理(例如,使用 -replaceRegion:... 方法之一或通过写入支持iosurface),那么您将需要多缓冲技术,是的。

如果您只是在 GPU 上修改纹理(通过渲染到它,从着色器函数写入它,或者使用 blit 命令编码器方法复制到它),那么您不需要多缓冲。您可能需要在着色器函数中使用纹理围栏,或者您可能需要在绘制调用之间在渲染命令编码器上调用 -textureBarrier,具体取决于您正在做什么。

是的,nextDrawable 提供了一种多缓冲形式。但是,在这种情况下,这不是由于 CPU 访问。您将渲染到一个纹理,而之前渲染的纹理可能仍在前往屏幕的途中。您不想对两者使用相同的纹理,因为新的渲染可能会在纹理刚刚显示在屏幕上之前过度绘制纹理,从而显示损坏的结果。

【讨论】:

很有趣,谢谢。因此,在多通道渲染的情况下——即一个通道将背景渲染为纹理,下一个通道将叠加层渲染为另一个纹理,最后一个通道将前两个纹理合成在一起,这将面临相同的风险没有对前两遍和最后一遍的目标纹理进行多重缓冲的损坏? 如果我理解您所描述的场景,那么,不,不需要多缓冲。一帧的两个纹理的合成将在它们被下一帧覆盖之前完成(除非以错误的顺序排列命令)。

以上是关于Metal 最佳实践:三重缓冲 – 纹理?的主要内容,如果未能解决你的问题,请参考以下文章

Vulkan中统一缓冲区的最佳实践

缓冲要在 UART 上发送的数据的最佳实践 [关闭]

如何定义通道缓冲区的最佳大小? [关闭]

用于创建大型 CSV 文件的 java IO 最佳实践

最佳实践生产者和消费者模式中的双缓冲技术

针对多个 iDevice 时资源管理的最佳实践?