直接写入顶点缓冲区

Writing directly into vertex buffer

本文关键字:顶点 缓冲区      更新时间:2023-10-16

我继承的 DirectX 9 应用程序/游戏使用动态顶点缓冲区。每一帧,它:

  1. 锁定顶点缓冲区
  2. 循环浏览网格并将顶点数据写入临时缓冲区(在程序启动时动态分配(,直到数据已满
  3. 将临时缓冲区的内容复制到顶点缓冲区
  4. 重复步骤 2 和 3,直到复制所有数据
  5. 解锁顶点缓冲区

我的问题是,带有临时缓冲区的部分是必要的吗?有什么理由不应该将顶点数据直接写入顶点缓冲区吗?
我在官方文档中没有找到这种做法的任何证据,而且我不够信任以前的程序员。

Discaimer:我不知道 DirectX 顶点缓冲区是如何工作的,我在这里可能是错的。

它可能会更慢:分配一个顶点缓冲区来优化来自 GPU 的访问,即最好在 GPU 自己的内存中的某个地方。这意味着直接从CPU访问它比访问普通RAM慢得多。另一方面,复制整个数组可以相对较快地完成,因此最好在主内存中准备这样一个数组,并一次性将其复制到顶点缓冲区。

临时缓冲区不是必需的,但需要注意。

DirectX 动态顶点缓冲区针对 GPU 的读取访问和 CPU 的写入访问进行了优化。写入访问优化称为写入组合,涉及与普通内存缓存不同的机制。CPU 将一起批量写入,前提是您按 4/8/16 字节块并按顺序写入内存。

请注意,由

驱动程序决定从动态缓冲区上的锁中获取哪种内存,它可能不会合并写入,但将其视为最佳选择。

写入组合内存缓存,因此从中读取是性能灾难。

这也许可以解释为什么你继承的游戏使用临时缓冲区,如果它读取和写入临时缓冲区,或者不努力按顺序写入组件 - 例如,首先定位然后放置纹理坐标。

不需要

临时缓冲区。从Lock返回的指针实际上已经是一个临时缓冲区。只有在解锁缓冲区后,驱动程序才能实际开始对其执行任何有意义的操作。

如果您使用 D3DLOCK_DISCARD ,则驱动程序没有义务使用任何合理的数据来兑现读取。因此,实现可以很好地返回malloc(size)

如果你不使用D3DLOCK_DISCARD,那么,好吧,这是一个单独的问题,真的。