iOS

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

此操作不会产生任何成本,并且在渲染通道开始时像素值始终未定义。


不需要考虑加载操作.png



  • 不需要渲染目标的先前内容,只需渲染其部分像素时,选择 MTLLoadAction.clear

此操作会产生将渲染目标的清除值写入每个像素的成本。


清楚成本.png



  • 需要渲染目标的先前内容,并且只渲染到它的一些像素时,选择 MTLLoadAction.load

此操作会产生从内存中加载每个像素的先前值的成本,明显慢于 MTLLoadAction.dontCare 或 MTLLoadAction.clear。


加载成本.png


选择存储操作


有多个存储操作选项可用,选择哪一个选项,取决渲染目标的存储需求。



  • 不需要保留渲染目标的内容,选择 MTLStoreAction.dontCare

 此操作不会产生任何成本,并且在渲染通道结束时像素值始终未定义。 在渲染通道中,为中间渲染目标选择此操作,之后不需要该中间的结果。 对于深度和模板渲染目标这是正确的选择。


不关心存储.png



  • 确实需要保留渲染目标的内容,选择 MTLStoreAction.store

此操作将每个像素的值存储到内存,会产生成本。 对于可绘制对象,这始终是正确的选择。


存储成本.png



  • 渲染目标是多重采样纹理

当执行多重采样时,可以选择存储渲染目标的多重采样或解析数据。 对于多重采样数据,其存储在渲染目标的 texture 属性中。 对于解析的数据,其存储在渲染目标的 resolveTexture 属性中。 多重采样时,请参考此表选择存储操作: 





































多重采样数据存储解析数据存储需要解析纹理需要的存储操作
是 是 是  MTLStoreAction.storeAndMultisampleResolve
 MTLStoreAction.store
 MTLStoreAction.multisampleResolve
  MTLStoreAction.dontCare

要在单个渲染通道中存储和解析多采样纹理,请始终选择 MTLStoreAction.storeAndMultisampleResolve 操作并使用单个渲染命令编码器。



  • 需要推迟存储选择 

在某些情况下,在收集更多渲染通道信息之前,可能不知道要对特定渲染目标使用哪个存储操作。 要推迟存储操作选择,请在创建 MTLRenderPassAttachmentDescriptor 对象时设置 MTLStoreAction.unknown 值。 设置未知的存储操作,可以避免消耗潜在的成本(因为设置另一个存储操作成本更高)。 但是,在完成对渲染通道的编码之前,必须指定有效的存储操作; 否则,会发生错误。


评估渲染通道之间的操作


可以在多个渲染过程中使用相同的渲染目标。 对于任何两个渲染通道之间的同一渲染目标,可能有多种加载和存储组合,选择哪一种组合,取决于渲染目标从一个渲染通道到另一个渲染通道的需求。



  • 下一个渲染通道中,不需要渲染目标的先前内容 

在第一个渲染通道中,选择 MTLStoreAction.dontCare 以避免存储渲染目标的内容。 在第二个渲染通道中,选择 MTLLoadAction.dontCare 或 MTLLoadAction.clear 以避免加载渲染目标的内容。


渲染通道的评估1.png


渲染通道的评估2.png



  • 需要在下一个渲染通道中使用渲染目标的先前内容

在第一个渲染通道中,选择 MTLStoreAction.store、MTLStoreAction.multisampleResolve 或 MTLStoreAction.storeAndMultisampleResolve 来存储渲染目标的内容。 在第二个渲染通道中,选择 MTLLoadAction.load 以加载渲染目标的内容。


渲染通道间内容传递.png


总结


本文介绍了根据渲染的需要,来设置渲染目标的加载和存储操作,合理的设置这些操作,可以避免昂贵且不必要的工作。通过图文详细介绍了,根据不同的渲染需求,设置不同的加载和存储操作达到的渲染效果。


作者:__sky
链接:https://juejin.cn/post/7033731322850148366
来源:稀土掘金

0 个评论

要回复文章请先登录注册