Metal 框架之设置加载和存储操作
Metal 框架之设置加载和存储操作
「这是我参与11月更文挑战的第19天,活动详情查看:2021最后一次更文挑战」
概述
通过设置 MTLLoadAction 和 MTLStoreAction 属性,可以定义渲染通道加载和存储 MTLRenderPassAttachmentDescriptor 对象 的方式。为渲染目标设置适当的操作,在渲染通道的开始(加载)或结束(存储)时,可以避免昂贵且不必要的工作。
在 texture 属性上设置渲染目标的纹理,在 loadAction 和 storeAction 属性上设置它的动作:
let renderPassDescriptor = MTLRenderPassDescriptor()
// Color render target
renderPassDescriptor.colorAttachments[0].texture = colorTexture
renderPassDescriptor.colorAttachments[0].loadAction = .clear
renderPassDescriptor.colorAttachments[0].storeAction = .store
// Depth render target
renderPassDescriptor.colorAttachments[0].texture = depthTexture
renderPassDescriptor.colorAttachments[0].loadAction = .dontCare
renderPassDescriptor.colorAttachments[0].storeAction = .dontCare
// Stencil render target
renderPassDescriptor.colorAttachments[0].texture = stencilTexture
renderPassDescriptor.colorAttachments[0].loadAction = .dontCare
renderPassDescriptor.colorAttachments[0].storeAction = .dontCare
选择加载操作
有多个加载操作选项可用,选择哪一个选项,取决于渲染目标的加载需求。
- 不需要渲染目标的先前内容,而是渲染到其所有像素时,选择 MTLLoadAction.dontCare
此操作不会产生任何成本,并且在渲染通道开始时像素值始终未定义。
- 不需要渲染目标的先前内容,只需渲染其部分像素时,选择 MTLLoadAction.clear
此操作会产生将渲染目标的清除值写入每个像素的成本。
- 需要渲染目标的先前内容,并且只渲染到它的一些像素时,选择 MTLLoadAction.load
此操作会产生从内存中加载每个像素的先前值的成本,明显慢于 MTLLoadAction.dontCare 或 MTLLoadAction.clear。
选择存储操作
有多个存储操作选项可用,选择哪一个选项,取决渲染目标的存储需求。
- 不需要保留渲染目标的内容,选择 MTLStoreAction.dontCare
此操作不会产生任何成本,并且在渲染通道结束时像素值始终未定义。 在渲染通道中,为中间渲染目标选择此操作,之后不需要该中间的结果。 对于深度和模板渲染目标这是正确的选择。
- 确实需要保留渲染目标的内容,选择 MTLStoreAction.store
此操作将每个像素的值存储到内存,会产生成本。 对于可绘制对象,这始终是正确的选择。
- 渲染目标是多重采样纹理
当执行多重采样时,可以选择存储渲染目标的多重采样或解析数据。 对于多重采样数据,其存储在渲染目标的 texture 属性中。 对于解析的数据,其存储在渲染目标的 resolveTexture 属性中。 多重采样时,请参考此表选择存储操作:
多重采样数据存储 | 解析数据存储 | 需要解析纹理 | 需要的存储操作 |
---|---|---|---|
是 | 是 | 是 | MTLStoreAction.storeAndMultisampleResolve |
是 | 否 | 否 | MTLStoreAction.store |
否 | 是 | 是 | MTLStoreAction.multisampleResolve |
否 | 否 | 否 | MTLStoreAction.dontCare |
要在单个渲染通道中存储和解析多采样纹理,请始终选择 MTLStoreAction.storeAndMultisampleResolve 操作并使用单个渲染命令编码器。
- 需要推迟存储选择
在某些情况下,在收集更多渲染通道信息之前,可能不知道要对特定渲染目标使用哪个存储操作。 要推迟存储操作选择,请在创建 MTLRenderPassAttachmentDescriptor 对象时设置 MTLStoreAction.unknown 值。 设置未知的存储操作,可以避免消耗潜在的成本(因为设置另一个存储操作成本更高)。 但是,在完成对渲染通道的编码之前,必须指定有效的存储操作; 否则,会发生错误。
评估渲染通道之间的操作
可以在多个渲染过程中使用相同的渲染目标。 对于任何两个渲染通道之间的同一渲染目标,可能有多种加载和存储组合,选择哪一种组合,取决于渲染目标从一个渲染通道到另一个渲染通道的需求。
- 下一个渲染通道中,不需要渲染目标的先前内容
在第一个渲染通道中,选择 MTLStoreAction.dontCare 以避免存储渲染目标的内容。 在第二个渲染通道中,选择 MTLLoadAction.dontCare 或 MTLLoadAction.clear 以避免加载渲染目标的内容。
- 需要在下一个渲染通道中使用渲染目标的先前内容
在第一个渲染通道中,选择 MTLStoreAction.store、MTLStoreAction.multisampleResolve 或 MTLStoreAction.storeAndMultisampleResolve 来存储渲染目标的内容。 在第二个渲染通道中,选择 MTLLoadAction.load 以加载渲染目标的内容。
总结
本文介绍了根据渲染的需要,来设置渲染目标的加载和存储操作,合理的设置这些操作,可以避免昂贵且不必要的工作。通过图文详细介绍了,根据不同的渲染需求,设置不同的加载和存储操作达到的渲染效果。
作者:__sky
链接:https://juejin.cn/post/7033731322850148366
来源:稀土掘金