Metal 最佳实践 - 在渲染期间更改渲染管道描述符

Metal best practices - changing renderPipelineDescriptor during render

在我的渲染管道中,我想使用一些着色器,并且在某些情况下修改 MTLRenderPipelineDescriptor 对象上的参数(例如,更改混合函数)。

在我看来,我有两个选择:

  1. 为每个参数组合(顶点着色器、片段着色器、混合等)创建并预编译一个 MTLRenderPipelineState。我可以有很多这样的状态对象,因为可能有很多组合。

  2. 在渲染过程中创建并编译新的 MTLRenderPipelineState 对象。

哪个选项更好?我还缺少其他选项吗?

对于最佳实践(和最佳性能),您应该遵循选项 1

Transient and Non-transient Objects in Metal 部分,Metal Programming Guide 非常清楚哪些对象应该被视为瞬态或非瞬态,以及非瞬态对象应该被缓存和重用。

特别是对于 MTLRenderPipelineState 对象,以下是指南在 Creating a Render Pipeline State 部分中必须说的内容:

A render pipeline state object is a long-lived persistent object that can be created outside of a render command encoder, cached in advance, and reused across several render command encoders. When describing the same set of graphics state, reusing a previously created render pipeline state object may avoid expensive operations that re-evaluate and translate the specified state to GPU commands.

选项 #1 更好。

对于选项 #2,尚不清楚您是想在每次渲染过程结束时丢弃该对象,还是要缓存它并在下次需要该排列时使用它。

如果您的代码必须支持的可能排列的数量非常大,但您实际要在任何鉴于 运行 相对较小,您没有简单的方法提前确定它。这种场景并不理想,但在编写引擎级代码的上下文中很容易想象,它必须向项目级代码公开很多灵活性。