glMapNamedBufferRange
Gives the CPU a pointer into part of a buffer's memory, by ID.
Signature
void *glMapNamedBufferRange(GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access);
How it works
The DSA form of glMapBufferRange. Instead of copying data in with glNamedBufferSubData, you write (or read) through the returned pointer directly.
With storage created by glNamedBufferStorage using GL_MAP_PERSISTENT_BIT, the buffer can stay mapped forever: map once at start-up and write each frame into a region the GPU is not reading, protected by fences (glFenceSync). That is the fastest way to stream data every frame.
Parameters
The buffer.
First byte to map.
Number of bytes.
What you will do, combined with |.
Common values
- GL_MAP_WRITE_BIT / GL_MAP_READ_BIT
- Write into it / read from it.
- GL_MAP_INVALIDATE_RANGE_BIT
- The old contents can be thrown away: no wait for the GPU to finish with them.
- GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT
- Stay mapped while the GPU uses the buffer, with writes visible without a flush (the storage needs the same flags).
- GL_MAP_FLUSH_EXPLICIT_BIT
- You say which parts changed with glFlushMappedNamedBufferRange.
Return value
A pointer to the mapped bytes, or nullptr on error.
Tips & pitfalls
Direct State Access (GL 4.5): the object is passed as a parameter, so nothing needs to be bound and no global state is disturbed.
Never keep using a non-persistent pointer after
glUnmapNamedBuffer, and never read from a pointer mapped only for writing: it can be uncached memory and very slow.
Errors
When the call is invalid it does nothing and sets an error, which glGetError returns:
- GL_INVALID_VALUE
- The range goes outside the buffer.
- GL_INVALID_OPERATION
- The buffer is already mapped, or access asks for something the storage flags do not allow.
Example
1GLbitfield flags = GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT;
2glNamedBufferStorage(buf, 3 * regionSize, nullptr, flags);
3char *ptr = (char *)glMapNamedBufferRange(buf, 0, 3 * regionSize, flags);
4// each frame: write into ptr + frame % 3 * regionSize