I have a code like this:
glNamedBufferStorage(atlas, capacity, nullptr, GL_DYNAMIC_STORAGE_BIT | GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
mappedMemory = glMapNamedBufferRange(atlas, 0, cap, GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
GLint cnt = 0;
gpu->glNamedBufferSubData(atlas, count.offset, count.size, &cnt);
glBindBufferRange(GL_ATOMIC_COUNTER_BUFFER, 0, atlasId, count.offset, count.size);
glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 0, atlasId, data.offset, data.size);
glDispatchCompute(x, y, z);
glMemoryBarrier(GL_ALL_BARRIER_BITS);
sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
while(true) {
GLenum v = glClientWaitSync(sync, GL_SYNC_FLUSH_COMMANDS_BIT, 0);
isFinished = (v == GL_ALREADY_SIGNALED) || (v == GL_CONDITION_SATISFIED);
if(isFinished)
break;
}
GLint count = mappedMemory[count.offset];
Data *ddata = mappedMemory + data.offset;
And shader like this:
layout(binding = 0, offset = 0) uniform atomic_uint count;
layout(std430, binding = 0) writeonly buffer Data {
uint data[];
};
const uint recordID = atomicCounterIncrement(count);
data[recordID] = some data;
When I run this code, it sometimes happens that the ddata
is not filled completely when I try to read it. Resp. count
shows more record that what I read from data. For checking, I pre-fill the data memory with some arbitrary values (using glNamedBufferSubData
) and then check the memory against that. And indeed, at some random point in the ddata
(sometimes right from index 0
, sometimes later), I stop reading the right data and start getting the original pre-filled values. Tested on Radeon 5700 XT.
Am I missing something here? That memory barrier is just for checking, since the memory is mapped as coherent the fence sync should be enough.
EDIT: I even tried adding glFinish
right after the memory barrier, still getting the same behavior.
EDIT: it rather seems that the atomic counter was causing the problems. I've reworked the code into using atomicAdd over a SSBO instead of atomic counters and haven't encountered the bug since.