带有 glMapBuffer 的 Buffer 会被分配比 glBufferSubData 更慢的 VRAM 吗?

Posted

技术标签:

【中文标题】带有 glMapBuffer 的 Buffer 会被分配比 glBufferSubData 更慢的 VRAM 吗?【英文标题】:Will Buffer with glMapBuffer be allocated a slower VRAM than glBufferSubData? 【发布时间】:2017-12-20 02:22:33 【问题描述】:

我有大量数据要传输到缓冲区,例如 VBO 或 IndirectDrawBuffer,我使用 glMapBuffer 和 glBufferSubData 来执行此操作。我发现使用 glMapBuffer 上传的缓冲区比渲染缓冲区时使用 glBufferSubData 慢得多。 我这样分配缓冲区

glBindBuffer(GL_DRAW_INDIRECT_BUFFER, m_indirectDrawBuffer);
glBufferStorage(GL_DRAW_INDIRECT_BUFFER, buffersize, 0, GL_DYNAMIC_STORAGE_BIT);

我像这样使用 glMapBuffer

m_indirectDrawBufferPtr = (GLubyte*)glMapNamedBuffer(m_indirectDrawBuffer, GL_WRITE_ONLY);
memcpy(m_indirectDrawBufferPtr, m_MultidrawCommands.data(), buffersize);
glUnmapNamedBuffer(m_indirectDrawBuffer);

我像这样使用 glBufferSubData

glNamedBufferSubData(m_indirectDrawBuffer, 0, buffersize, m_MultidrawCommands.data());

为什么会发生这些?

我应该怎么做才能使用 glMapBuffer 获得有效的缓冲区?分配 2 个缓冲区,一个使用 glMapBuffer,另一个使用 glCopyNamedBufferSubData 从第一个缓冲区复制数据,也许是解决这些问题的一种方法。但它会使用更多的 VRAM。这是唯一的方法吗?

【问题讨论】:

为什么您对某些函数使用直接状态访问,而不是全部(如glBufferStorage)? 【参考方案1】:

首先,您不能映射该缓冲区,因此不清楚您的代码为何有效。当您allocate immutable storage for a buffer 时,您必须指定您打算如何访问它。而且你没有说你会映射它来阅读或写作......所以你不能

其次,映射缓冲区是一项相当重量级的操作。如果您的内存块中已经有数据,那么映射缓冲区只是为了复制它然后立即取消映射它是没有意义的。映射允许您将数据直接生成到缓冲区中(理论上),因此您用于填写m_MultidrawCommands 的任何操作都应该用于直接写入映射的缓冲区。

另外,persistent mapping 存在,它允许您永久保留映射的缓冲区。当然,这也需要您跟踪哪些命令正在使用缓冲区的一部分,这样您就不会写入可能被读取的值。

【讨论】:

感谢您的回答。但首先,如果你说的是 GL_MAP_WRITE_BIT,我已经尝试过并得到了相同的结果。其次,我没有像这样复制内存,这是一个简单的例子。实际上,我是在一个线程中复制内存数据,因为它是一个大数据,我不想通过使用 glBufferSubData 来阻塞 CPU 传输 也试过 glBufferData(GL_DRAW_INDIRECT_BUFFER, buffersize, 0, GL_STREAM_DRAW) 来分配缓冲区得到同样的结果

以上是关于带有 glMapBuffer 的 Buffer 会被分配比 glBufferSubData 更慢的 VRAM 吗?的主要内容,如果未能解决你的问题,请参考以下文章

glMapBuffer 不断返回 0x00000000

OpenGL更新缓冲区如何影响速度

OpenGL 2.1:glMapBuffer 和使用提示

OpenGL:如何在 Qt 中使用 glMapBuffer?

使用 glMapBuffer 用一个缓冲区渲染多个对象?

从顶点着色器中修改着色器存储缓冲区对象