直接写入顶点缓冲区
Writing directly into vertex buffer
我继承的 DirectX 9 应用程序/游戏使用动态顶点缓冲区。每一帧,它:
- 锁定顶点缓冲区
- 循环浏览网格并将顶点数据写入临时缓冲区(在程序启动时动态分配(,直到数据已满
- 将临时缓冲区的内容复制到顶点缓冲区
- 重复步骤 2 和 3,直到复制所有数据
- 解锁顶点缓冲区
我的问题是,带有临时缓冲区的部分是必要的吗?有什么理由不应该将顶点数据直接写入顶点缓冲区吗?
我在官方文档中没有找到这种做法的任何证据,而且我不够信任以前的程序员。
Discaimer:我不知道 DirectX 顶点缓冲区是如何工作的,我在这里可能是错的。
它可能会更慢:分配一个顶点缓冲区来优化来自 GPU 的访问,即最好在 GPU 自己的内存中的某个地方。这意味着直接从CPU访问它比访问普通RAM慢得多。另一方面,复制整个数组可以相对较快地完成,因此最好在主内存中准备这样一个数组,并一次性将其复制到顶点缓冲区。
临时缓冲区不是必需的,但需要注意。
DirectX 动态顶点缓冲区针对 GPU 的读取访问和 CPU 的写入访问进行了优化。写入访问优化称为写入组合,涉及与普通内存缓存不同的机制。CPU 将一起批量写入,前提是您按 4/8/16 字节块并按顺序写入内存。
请注意,由驱动程序决定从动态缓冲区上的锁中获取哪种内存,它可能不会合并写入,但将其视为最佳选择。
写入组合内存未缓存,因此从中读取是性能灾难。
这也许可以解释为什么你继承的游戏使用临时缓冲区,如果它读取和写入临时缓冲区,或者不努力按顺序写入组件 - 例如,首先定位然后放置纹理坐标。
临时缓冲区。从Lock
返回的指针实际上已经是一个临时缓冲区。只有在解锁缓冲区后,驱动程序才能实际开始对其执行任何有意义的操作。
如果您使用 D3DLOCK_DISCARD
,则驱动程序没有义务使用任何合理的数据来兑现读取。因此,实现可以很好地返回malloc(size)
。
如果你不使用D3DLOCK_DISCARD
,那么,好吧,这是一个单独的问题,真的。
- 从返回的顶点缓冲区查询顶点结构
- Vulkan 中的动态顶点缓冲区格式设置
- 在 DirectX 11 中从 GPU 读回顶点缓冲区(并获取顶点)
- DirectX11只绘制填充索引和顶点缓冲区中的一半顶点
- tiny_obj_loader到 Direct3D 顶点缓冲区和索引缓冲区数组
- OpenGL 顶点缓冲区类重定义和模板方法错误
- D3D11:映射顶点缓冲区时E_OUTOFMEMORY
- C DirectX 11从第二个顶点缓冲区呈现麻烦
- 我可以将单个顶点索引与具有所有属性(位置、法线、texCoord)的顶点缓冲区一起使用吗?
- DirectX:如果绑定索引缓冲区但不绑定顶点缓冲区,会发生什么情况
- Directx 11 - 是将顶点缓冲区中的所有顶点推送到顶点着色器,还是仅编制索引
- 自动生成的顶点缓冲区和索引缓冲区不起作用
- 为什么我的顶点缓冲区对象出现访问冲突错误?
- 为什么我的 openGL 顶点缓冲区对象不会绘制任何内容?
- 在OpenGL中,如何从内存中编辑特定的顶点缓冲区属性
- 我是否需要OpenGL中类似对象的多个顶点缓冲区
- (DirectX 11)单个顶点缓冲区是否可以一次绑定到多个 IA 输入槽
- Directx 10:使用CopySubresourceRegion更新顶点缓冲区
- 具有X文件的非相干顶点缓冲区
- 在DX9上为顶点缓冲区创建结构