带有 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 吗?的主要内容,如果未能解决你的问题,请参考以下文章