在d3d11的图形管道中放置东西的方法更有效?

时间:2012-04-19 16:07:13

标签: c++ directx

因此,通过查看示例和教程,似乎将缓冲区放置在管道中的最常见方法是,每个模型对象都获得它自己的顶点缓冲区,然后在填充缓冲区后,它们会锁定,为每个型号的单个缓冲区设置缓冲区,解锁,设置着色器,绘制和冲洗/重复。在我看来,所有锁定和解锁都会使事情变慢。

所以我想知道模型对象是否可以将所有顶点聚合成一个大数组,所有索引都在一个大数组中,创建一个大缓冲区,锁定一次,设置缓冲区一次,解锁,然后切换着色器并根据需要绘制与这些着色器一样多的多边形,然后沿着缓冲区绘图并像以前一样切换着色器,而不是每次绘制之前都必须在管道中锁定和删除更多顶点。

这会更有效率吗,或者你认为所涉及的所有簿记的开销(例如,从索引a到索引b,使用这个着色器),只会让它比它更有用吗?值得?

另外,如果我在这里错过了d3d的概念,请通知我。 (我是新的)

修改

由于大量的误解,在我提到锁定和解锁的任何地方,实际上应该只是调用IASetVertexBuffer / IASetIndexBuffer。 "修订版"问题或多或少:

是否将场景中所有模型的顶点填充到一个缓冲区中,只需调用IASetVertexBuffer一次就可以改善性能?

2 个答案:

答案 0 :(得分:2)

  

通过查看示例和教程

停止。大多数“示例和教程”都是而不是旨在显示最佳性能实践。除非他们具体关于最佳性能实践。他们试图以最清晰,最干净的方式展示如何执行任务X.优化是另一个完全问题。优化的代码比不是最优的代码更清晰,更干净;因此,许多优化会妨碍教程的既定目的。

所以从不假设只是因为教程以某种方式做到了,这是做某事的最快方法。它只是一种方式。

  

然后填充缓冲区后,它们会锁定,设置缓冲区,解锁,设置着色器,绘制和冲洗/重复每个模型的单个缓冲区。

锁定和解锁用于修改缓冲区。如果你没有修改它...为什么要锁定它?如果你正在修改它,那么你正在做某种形式的缓冲流,这需要特殊处理才能使其高效。

如果您正在进行流式传输,那么您应该问一个不同的问题(即:如何进行高性能顶点流式传输)。

这并不是说将多个对象的数据放在一个缓冲区中并不是一个好主意。但如果是这样的话,它的原因与锁定和解锁关系不大,而更多的是与通过一次绘制调用绘制多个对象的可能性。

答案 1 :(得分:1)

一般来说锁越少越好,每次锁都必须是系统内存和显卡内存之间的同步传输,这会使GPU停顿。您可以将这些转移批处理的越多越好。

然而,更好的改进是留下不会单独改变的缓冲区。你并不总是需要每次重装#1221。单。帧。它永远不会改变(*)。因此,在开始时加载静态艺术,并根据需要绘制它。在您考虑在预处理中剔除一半的工作台之前,请先考虑一下锁定缓冲区的成本,以便在GPU已经知道如何以闪电般速度进行基本剔除时摆脱一些顶点。

(*)假设当然没有改变:)