2

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.

Danol
  • 368
  • 1
  • 15
  • did you try [glFlushMappedBufferRange](https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glFlushMappedBufferRange.xhtml) – Szabolcs Dombi Sep 21 '20 at 08:47
  • @SzabolcsDombi I'm not mapping the buffer for writing, but for reading only. For the data upload, I'm using `glBuferSubData`. – Danol Sep 21 '20 at 09:03
  • 1
    Code looks OK to me, I wouldn't be surprised if you ran into a driver bug in this area. – derhass Sep 21 '20 at 14:43
  • @derhass Oh hey derhass :) It looks like a driver bug to me indeed :/ In further testing, I started getting some ridiculous values from the atomic counter. I switched from atomic counter buffers to standard SSBO with using atomicAdd and the problem seems to have gone away. – Danol Sep 21 '20 at 15:06

0 Answers0