直接写入顶点缓冲区

时间:2012-05-17 12:46:02

标签: c++ directx buffer vertex

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

  1. 锁定顶点缓冲区
  2. 循环网格并将顶点数据写入临时缓冲区(在程序启动时动态分配),直到它满了
  3. 将临时缓冲区的内容复制到顶点缓冲区
  4. 重复步骤2和3,直到复制完所有数据
  5. 解锁顶点缓冲区
  6. 我的问题是,是否需要使用临时缓冲区?有没有理由不将顶点数据直接写入顶点缓冲区? 我在官方文档中没有找到任何这种做法的证据,我不相信以前的程序员。

3 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:2)

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

DirectX动态顶点缓冲区针对GPU的读取访问和CPU的 write 访问进行了优化。写访问优化称为写入组合,并且涉及与正常内存缓存不同的机制。考虑到您以4/8/16字节块的顺序写入存储器,CPU将批量写入。

请注意,由驱动程序决定从动态缓冲区的锁中获取什么类型的内存,它可能不是写入组合,但是将其视为最佳选择。

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

这可能解释了为什么你继承的游戏在读取和写入临时缓冲区时都使用临时缓冲区,或者不按顺序编写组件 - 例如先定位纹理坐标。

答案 2 :(得分:0)

不需要临时缓冲区。从Lock返回的指针本质上实际上已经是一个临时缓冲区。一旦解锁缓冲区,驱动程序只能在其上实际开始任何有意义的操作。

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

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