Reputation: 995
I implemented persistent mapped buffers in a renderer I wrote, very much alike in this tutorial here: persistent-mapped-buffers-in-opengl
To keep it short, its working like this:
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);
Mapping (only once after creation...):
flags = GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT;
myPointer = glMapBufferRange(GL_ARRAY_BUFFER, 0, MY_BUFFER_SIZE, flags);
Update:
// wait for the buffer
glClientWaitSync(Buffer.Sync[Index], GL_SYNC_FLUSH_COMMANDS_BIT, WaitDuration);
// modify underlying data...
lock the buffer:
glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
After I understood the idea, I was able to implement it without further problems, also gaining quite some performance due to it. However due to the game engine I am working with, it can't be avoided that I sometimes get a lot of drawcalls with very small chunks, just a few verts. If this happens I get visual distortions, clearly indicating something goes wrong.
What I tried is to add more waits before and after the buffer is updated. Although this wouldn't have made any sense but just for testing, I tried to remove GL_MAP_COHERENT_BIT and to use glFlushMappedBufferRange, I tried with a single buffer instead of multiple buffers.
For me it looks like the fence wouldn't work correctly, but I can't see how this could happen.
Shouldn't fencing avoid any trouble like this, even if it would mean sacrificing performance?
The same situation however works without any trouble if I use glBufferData instead, or as said already, if the chunks are a few hundred verts instead and reduced drawcalls.
Any hints what this could be caused by or how I could get more information about what is failing would be very helpful.
There are no OpenGL errors at all.
Upvotes: 0
Views: 1122
Reputation: 995
It turned out that the problem was on an entirely different place and a combination of things.
For multiple buffers it was instead setting an index in
glDrawArrays(GL_TRIANGLES, 0, VertSize);
necessary to set the offset for the multiple buffers in
glVertexAttribPointer(VERTEX_COORD_ATTRIB, 3, GL_FLOAT, GL_FALSE, StrideSize, (void*) BeginOffset));
and the problem for the single buffer distortions came due to a missing wait or rather a wrong "if" when having only one.
I hope that this may be useful for someone else running into such a problem to know that it is no general issue with persistent mapped buffers.
Upvotes: 1