C++ 直接写入顶点缓冲区

C++ 直接写入顶点缓冲区,c++,directx,buffer,vertex,C++,Directx,Buffer,Vertex,我继承的DirectX 9应用程序/游戏使用动态顶点缓冲区。每一帧,它: 锁定顶点缓冲区 在网格中循环并将顶点数据写入临时缓冲区(在程序启动时动态分配),直到其满为止 将临时缓冲区的内容复制到顶点缓冲区 重复步骤2和3,直到复制所有数据 解锁顶点缓冲区 我的问题是,有临时缓冲区的部分是否必要?是否有理由不将顶点数据直接写入顶点缓冲区? 我还没有在官方文档中找到这种做法的任何证据,我对以前的程序员也不够信任。Discaimer:我不知道DirectX顶点缓冲区是如何工作的,我可能在这里错了 它可能

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

  • 锁定顶点缓冲区
  • 在网格中循环并将顶点数据写入临时缓冲区(在程序启动时动态分配),直到其满为止
  • 将临时缓冲区的内容复制到顶点缓冲区
  • 重复步骤2和3,直到复制所有数据
  • 解锁顶点缓冲区
  • 我的问题是,有临时缓冲区的部分是否必要?是否有理由不将顶点数据直接写入顶点缓冲区?

    我还没有在官方文档中找到这种做法的任何证据,我对以前的程序员也不够信任。

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


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

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

    DirectX动态顶点缓冲区针对GPU的读访问和CPU的写访问进行了优化。写访问优化称为写组合,它涉及一种与普通内存缓存不同的机制。如果以4/8/16字节块和顺序写入内存,CPU将一起批处理写入

    请注意,由驱动程序决定从动态缓冲区上的锁返回哪种类型的内存,它可能不是写组合的,但将其视为最佳选择

    写入组合内存未缓存,因此从中读取会导致性能灾难


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

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

    如果您使用
    D3DLOCK\u DISCARD
    ,则驾驶员没有义务使用任何合理的数据进行读取。因此,实现可以很好地返回
    malloc(size)


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

    我认为你可以直接写入顶点缓冲区。。。。。。虽然我同意如果锁定的顶点缓冲区直接映射到GPU上(参见leftaroundabout的答案),它的性能不会很好。但我有点怀疑从LockVertexBuffer地址直接返回GPU内存的指针。我认为它将在主内存中,通常由驱动程序管理;一旦你解锁顶点缓冲区,就可以自由地将其DMA到卡中。不幸的是,我也不是Direct3D的人——这就是它在OpenGL中的工作原理。是的,这是有道理的我只知道CUDA的GPU编程,在那里你可以直接访问设备内存,但在非硬件特定的图形库中它可能不会以这种方式工作。无论如何,如果没有Direct3D专家来拯救这一天,我认为他应该对它进行基准测试,看看会发生什么:)