具有非常小的块的持久映射缓冲区(glBufferStorage GL_MAP_PERSISTENT_BIT)

时间:2017-05-24 15:51:17

标签: c++ opengl

我在我写的渲染器中实现了持久映射缓冲区,在本教程中非常相似: persistent-mapped-buffers-in-opengl

为了简短起见,它的工作方式如下:

glGenBuffers(1, &vboID);
glBindBuffer(GL_ARRAY_BUFFER, vboID);
flags = GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT;
glBufferStorage(GL_ARRAY_BUFFER, MY_BUFFER_SIZE, 0, flags);

映射(创建后只有一次......):

flags = GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT;
myPointer = glMapBufferRange(GL_ARRAY_BUFFER, 0, MY_BUFFER_SIZE, flags);

更新

// wait for the buffer   
glClientWaitSync(Buffer.Sync[Index], GL_SYNC_FLUSH_COMMANDS_BIT, WaitDuration);

// modify underlying data...

锁定缓冲区:

glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);

在我理解了这个想法之后,我能够在没有进一步问题的情况下实现它,并且因此获得了相当多的性能。 然而,由于我正在使用的游戏引擎,我无法避免使用非常小的块,只有几个顶点来获得大量的drawcall。如果发生这种情况,我会出现视觉扭曲,清楚地表明出现了问题。

我尝试的是在更新缓冲区之前和之后添加更多等待。虽然这对于测试没有任何意义,但我尝试删除GL_MAP_COHERENT_BIT并使用glFlushMappedBufferRange,我尝试使用单个缓冲区而不是多个缓冲区。

对我而言,围栏看起来不会正常工作,但我无法看到这种情况会如何发生。 不应该像这样避免任何麻烦,即使这会意味着牺牲性能吗? 然而,如果我使用glBufferData,或者已经说过,如果块是几百个顶点而且减少了drawcalls,那么同样的情况可以毫无困难地工作。
任何暗示这可能是由什么引起或如何获得有关失败的更多信息将是非常有帮助的。 根本没有OpenGL错误。

1 个答案:

答案 0 :(得分:1)

事实证明,问题出在一个完全不同的地方和事物的组合上。

对于多个缓冲区,它改为在

中设置索引
glDrawArrays(GL_TRIANGLES, 0, VertSize);

需要在

中设置多个缓冲区的偏移量
glVertexAttribPointer(VERTEX_COORD_ATTRIB, 3, GL_FLOAT, GL_FALSE, StrideSize, (void*) BeginOffset));

并且单缓冲区失真的问题是由于缺少等待或者只有一个错误的“if”而导致的。

我希望这可能对遇到此类问题的其他人有用,以便知道持久映射缓冲区不是常见问题。