OpenGL映射内存未更新
我有这样一个代码:OpenGL映射内存未更新,opengl,opengl-4,Opengl,Opengl 4,我有这样一个代码: 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_COH
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;
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;
像这样:
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;
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;
当我运行这段代码时,有时在我尝试读取时,ddata
没有完全填充。分别<代码>计数显示比我从数据中读取的记录更多的记录。为了进行检查,我使用一些任意值(使用glNamedBufferSubData
)预先填充数据内存,然后对照该值检查内存。事实上,在ddata
中的某个随机点(有时从索引0
,有时更晚),我停止读取正确的数据,开始获取原始的预填充值。在Radeon 5700 XT上测试
我是不是遗漏了什么?该内存屏障仅用于检查,因为内存映射为一致的,所以围栏同步应该足够了
编辑:我甚至尝试在内存障碍之后添加glFinish
,仍然得到相同的行为
编辑:似乎是原子计数器造成了问题。我重新编写了代码,在SSBO上使用atomicAdd而不是原子计数器,从那以后就再也没有遇到过错误。您是否尝试过@SzabolcsDombi我没有映射用于写入的缓冲区,而是用于读取的缓冲区。对于数据上传,我使用的是
glBuferSubData
。在我看来,代码还行,如果您在这方面遇到驱动程序错误,我也不会感到惊讶。@derhass-Oh-hey-derhass:)在我看来确实是个驱动程序错误:/在进一步的测试中,我开始从原子计数器获得一些荒谬的值。我使用atomicAdd从原子计数器缓冲区切换到标准SSBO,问题似乎消失了。