1

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

所以我想知道模型对象是否可以改为将它们的所有顶点聚合到一个大数组中,一个大数组中的所有索引,创建1个大缓冲区,锁定一次,设置一次缓冲区,解锁,然后切换着色器并绘制这些着色器需要尽可能多的多边形,并且只需像以前一样沿着缓冲区绘图和切换着色器工作,而不必每次在绘制之前都在管道中锁定和丢弃更多顶点。

这会更有效,还是您认为所有涉及的簿记的开销(例如,从索引 a 到索引 b,使用此着色器)只会使这比它的价值更多工作?

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

编辑

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

将场景中所有模型的顶点填充到一个缓冲区中,并且只需调用一次 IASetVertexBuffer 就可以提高性能吗?

4

2 回答 2

3

因此,通过查看示例和教程

停止。大多数“示例和教程”都不是为了展示最佳性能实践。除非它们专门针对最佳性能实践。他们试图以最清晰和最干净的方式展示如何执行任务 X。优化是完全不同的问题。优化的代码比非优化的代码更不清晰和干净;因此,许多优化会妨碍本教程的既定目的。

所以永远不要认为仅仅因为教程以某种方式做到了,那就是做某事的最快方法。这只是一种方法。

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

锁定和解锁是为了修改缓冲区。如果您不修改它...为什么要锁定它?如果你正在修改它,那么你正在做某种形式的缓冲流,这需要特殊处理以使其高效。

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

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

于 2012-04-19T16:21:29.200 回答
1

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

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

(*) 假设它当然不会改变:)

于 2012-04-19T16:21:04.787 回答