在 D3D11 的图形管道中放置内容的哪种方法更有效

which method of placing things in the graphics pipeline for d3d11 is more efficient?

本文关键字:有效 方法 图形 D3D11 管道      更新时间:2023-10-16

因此,从示例和教程来看,似乎在管道中放置缓冲区的最常见方法是,每个模型对象都获得自己的顶点缓冲区,然后在缓冲区填充后,它们锁定、设置缓冲区、解锁、设置着色器、绘制和冲洗/重复每个模型单独的缓冲区。 在我看来,所有这些锁定和解锁都会减慢速度。

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

这会更有效吗,或者你认为所有涉及的簿记的开销(例如,从索引 a 到索引 b,使用此着色器)只会使这项工作超出其价值?

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

编辑

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

将场景中所有模型的顶点填充到一个缓冲区中,并简单地调用IASetVertexBuffer一次,是否会提高性能?

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

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

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

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

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

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

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

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

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

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