I’m banging my head against a wall on this one and I find no solution. Maybe somebody has seen something similar and has an idea what’s going on?
To read back GPU to CPU I support two code path. One uses traditional way of copy shader written to SSBO to a CPU near SSBO using glCopyBufferSubData, then later on map/read/unmap to work with it. The second (faster) code path uses persistent mapped SSBO and does an glCopyNamedBufferSubData with glMemoryBarrier/glFenceSync to read.
So far so good. On Linux both code path work on both AMD/nVidia systems.
On Windows though things go south. The older way of using a copy without persistent buffer works. The 4.5 way though using glCopyNamedBufferSubData fails. The code line in question looks like this:
glCopyNamedBufferSubData(pSSBO, pSSBOLocal, 0, 0, size);
pSSBO is the GPU near buffer which is a regular non-persistent mapped buffer and pSSBOLocal is the CPU near buffer which is persistent mapped like this:
glNamedBufferStorage(pSSBOLocal, size, nullptr, GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT | GL_CLIENT_STORAGE_BIT));
persistentMapped = (char*)glMapNamedBufferRange(pSSBOLocal, 0, size, GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT));
I check using GL_BUFFER_SIZE
that both buffers (at the time of the error) are of size size
(in this example size=16) and checked against the specification of glCopyNamedBufferSubData
for error condition:
-
GL_INVALID_VALUE is generated if any of readOffset, writeOffset or size is negative, if readOffset+size is greater than the size of the source buffer object (its value of GL_BUFFER_SIZE), or if writeOffset+size is greater than the size of the destination buffer object.
- readOffset=0, writeOffset=0, size=16, bufferSize1=16, bufferSize2=16
- readOffset >= 0: PASS
- writeOffset >= 0: PASS
- size >= 0: PASS
- readOffset + size <= bufferSize1: PASS
- writeOffset + size <= bufferSIze2: PASS
-
GL_INVALID_VALUE is generated if the source and destination are the same buffer object, and the ranges readOffset,readOffset+size and writeOffset,writeOffset+size overlap.
- pSSBO != pSSBOLocal: PASS
Hence everything is fine, no errors. Since this error happens only if a “persistently mapped SSBO” is involved I suspect a problem with this under Windows. But that would be a GL_INVALID_OPERATION in my opinion.
I’m out of ideas where to look for the problem. It happens “only” on Windows. Linux is fine.