GLCOPYBUFFERSUBDATA(3G)
π glCopyBufferSubData(3G) β the manual page, but make it a vibe π
okay so bestie, you know how you sometimes need to copy data from one buffer object to another? like literally just scooping up part of one data store and yeeting it into another? that's what this is. glCopyBufferSubData and glCopyNamedBufferSubData are your girls for that. no cap, it's giving "copy all or part of the data store of a buffer object to the data store of another buffer object" energy. slay. β¨
πΈ C SPECIFICATION πΈ
void glCopyBufferSubData(GLenum readTarget, GLenum writeTarget,
GLintptr readOffset, GLintptr writeOffset,
GLsizeiptr size);
void glCopyNamedBufferSubData(GLuint readBuffer, GLuint writeBuffer,
GLintptr readOffset, GLintptr writeOffset,
GLsizeiptr size);
periodt. those are the two functions. memorize them, bestie. π
π PARAMETERS π
okay let's go through these one by one because i want you to actually understand them, not just smile and nod:
readTargetβ forglCopyBufferSubData, this is the target the source buffer object is bound to. like, which slot is your source chillin' in. iykyk.writeTargetβ forglCopyBufferSubData, this is the target the destination buffer object is bound to. where your data is headed. main character destination energy.readBufferβ forglCopyNamedBufferSubData, this is the name of the source buffer object. not the target, the name. different vibe entirely.writeBufferβ forglCopyNamedBufferSubData, the name of the destination buffer object. again: name, not target. don't mix them up fr fr.readOffsetβ the offset, in basic machine units, within the source buffer's data store, at which the data will be read. like where in the source you start scooping. πwriteOffsetβ the offset, in basic machine units, within the destination buffer's data store, at which the data will be written. where in the destination you start dumping. two different spots, bestie.sizeβ the size, in basic machine units, of the data to be copied from the source buffer to the destination buffer. how many units get copied. slay. π«
β¨ DESCRIPTION β¨
okay so here's the whole situation. glCopyBufferSubData and glCopyNamedBufferSubData copy part of the data store attached to a source buffer object to the data store attached to a destination buffer object. the number of basic machine units indicated by size is copied from the source at offset readOffset to the destination at writeOffset. and just to be clear: readOffset, writeOffset and size are all in terms of basic machine units. not vibes, not bytes-by-accident, basic machine units. π
for glCopyBufferSubData, readTarget and writeTarget specify the targets to which the source and destination buffer objects are bound. and here's the important part bestie: they must each be one of the buffer binding targets in this table. i'm not making this up, it's literally the list:
| Buffer Binding Target | Purpose |
|---|---|
GL_ARRAY_BUFFER | Vertex attributes |
GL_ATOMIC_COUNTER_BUFFER | Atomic counter storage |
GL_COPY_READ_BUFFER | Buffer copy source |
GL_COPY_WRITE_BUFFER | Buffer copy destination |
GL_DISPATCH_INDIRECT_BUFFER | Indirect compute dispatch commands |
GL_DRAW_INDIRECT_BUFFER | Indirect command arguments |
GL_ELEMENT_ARRAY_BUFFER | Vertex array indices |
GL_PIXEL_PACK_BUFFER | Pixel read target |
GL_PIXEL_UNPACK_BUFFER | Texture data source |
GL_QUERY_BUFFER | Query result buffer |
GL_SHADER_STORAGE_BUFFER | Read-write storage for shaders |
GL_TEXTURE_BUFFER | Texture data buffer |
GL_TRANSFORM_FEEDBACK_BUFFER | Transform feedback buffer |
GL_UNIFORM_BUFFER | Uniform block storage |
any of these targets may be used, okay? any of them. but GL_COPY_READ_BUFFER and GL_COPY_WRITE_BUFFER are provided specifically to allow copies between buffers without disturbing other GL state. they're the designated copy besties, the ones who don't drag the rest of your GL state into it. iconic. π
now for the rules, because there are always rules. readOffset, writeOffset and size must all be greater than or equal to zero. all three. don't get cute and use negative numbers, it's not that kind of party. furthermore, $readOffset+size$ must not exceed (yes, the original page spells it "exceeed", i see you typo, you're valid) the size of the source buffer object, and $writeOffset+size$ must not exceed the size of the buffer bound to writeTarget. if the source and destination are the same buffer object, then the source and destination ranges must not overlap. this is important. don't overlap. no cap. π€
π¦ NOTES π¦
okay so some targets are version-gated, bestie, and you need to know about it:
GL_DISPATCH_INDIRECT_BUFFERandGL_SHADER_STORAGE_BUFFERtargets are available only if the GL version is 4.3 or greater. so if you're running something older, no dice.GL_QUERY_BUFFERtarget is available only if the GL version is 4.4 or greater. again: check your version first, don't come crying to me.
π ERRORS π
here we go, the part where things go wrong and you need to know why. buckle up, bestie, this is gonna be a list:
GL_INVALID_ENUMis generated byglCopyBufferSubDataifreadTargetorwriteTargetis not one of the buffer binding targets listed above. so if you typed some made-up target, this is your sign. πGL_INVALID_OPERATIONis generated byglCopyBufferSubDataif zero is bound toreadTargetorwriteTarget. zero is not a buffer. zero is zero. that's the whole thing.GL_INVALID_OPERATIONis generated byglCopyNamedBufferSubDataifreadBufferorwriteBufferis not the name of an existing buffer object. so if you're using a name that doesn't map to anything, that's a problem.GL_INVALID_VALUEis generated if any ofreadOffset,writeOffsetorsizeis negative. negative numbers! not allowed! π«GL_INVALID_VALUEis generated if$readOffset + size$is greater than the size of the source buffer object (its value ofGL_BUFFER_SIZE). that's the source object's own size, for reference.GL_INVALID_VALUEis generated if$writeOffset + size$is greater than the size of the destination buffer object. same situation, other side.GL_INVALID_VALUEis generated if the source and destination are the same buffer object, and the ranges$[readOffset,readOffset+size)$and$[writeOffset,writeOffset+size)$overlap. the overlap thing again. i told you. i literally told you.GL_INVALID_OPERATIONis generated if either the source or destination buffer object is mapped withglMapBufferRange()orglMapBuffer(), unless they were mapped with theGL_MAP_PERSISTENTbit set in theglMapBufferRangeaccess flags. so mapped is a no-go, unless you used the persistent bit. then it's fine. the more you know. π
π VERSION SUPPORT π
okay so the vibe check here is: which versions do these functions exist in? and the answer is in table form, which i will not be retyping into prose because technical accuracy is more important than my aesthetic. but here's the table, bestie, and let me tell you, glCopyNamedBufferSubData is famous for being a late bloomer:
| Function / Feature Name | 2.0 | 2.1 | 3.0 | 3.1 | 3.2 | 3.3 | 4.0 | 4.1 | 4.2 | 4.3 | 4.4 | 4.5 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
glCopyBufferSubData | - | - | - | β | β | β | β | β | β | β | β | β |
glCopyNamedBufferSubData | - | - | - | - | - | - | - | - | - | - | - | β |
so glCopyBufferSubData shows up in 3.1 and later, while glCopyNamedBufferSubData? literally doesn't exist until 4.5. it's the ultimate "better late than never" energy. π
π«Ά SEE ALSO π«Ά
these are the friends, the supporting cast, the ones you should also check out:
glGenBuffers(), glBindBuffer(), glBufferData(), glBufferSubData(), glGetBufferSubData(), glMapBuffer(), glMapBufferRange()
π COPYRIGHT π
Copyright Β© 2010-2014 Khronos Group. This material may be distributed subject to the terms and conditions set forth in the Open Publication License, v 1.0, 8 June 1999. http://opencontent.org/openpub/.
Copyright Β© 2010-2014 Khronos Group
okay bestie, that's the whole page. every option, every error, every version check, every copyright line. you're welcome. now go forth and copy those buffers, but not overlappingly, and not negatively, and not while mapped unless you used GL_MAP_PERSISTENT. the way that i believe in you. πβ¨
this has been the [FIXME: source] edition from 08/09/2021, aka the glCopyBufferSubData era of the manual. slay and goodbye π
π¦ where this page comes from
- centos-stream 9: gl-manpages 1.1-24.20190306.el9 Β· MIT and Open Publication
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms