Gnampf
Gnampf

Reputation: 995

Peristent mapped buffer (glBufferStorage GL_MAP_PERSISTENT_BIT) with very small chunks

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

Answers (1)

Gnampf
Gnampf

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

Related Questions