PDA

View Full Version : glVertexAttribPointer, glBufferSubData,glUniform4fv... basics...



gonkgonk
03-28-2013, 08:51 PM
For functions like glVertexAttribPointer, glBufferSubData,glUniform4fv - these all take pointers as arguments to data that is stored in the client side. At what point am I free to start modifying (or freeing) that data? From what I can tell glBufferSubData copies the data immediately, so I can free my own copy immediately (right?) But, what about the other functions I mentioned? Is it safe to free (or overwrite) the data immediately after calling them? If not, is it safe immediately after glDrawArrays (or glDrawElements)? Or might it not be safe for a while even after that?

Alfonse Reinheart
03-28-2013, 09:48 PM
A good question. Allow me to quote from the OpenGL Wiki article on synchornization (http://www.opengl.org/wiki/Synchronization#Asynchronous_action):



There are several OpenGL functions that can pull data directly from client-side memory, or push data directly into client-side memory. Functions like glTexSubImage2D, glReadPixels, glBufferSubData and so forth.

When ''any'' of these functions have returned, they ''must'' have finished with the client memory. When glReadPixels returns, the pixel data is in your client memory (unless you are reading into a buffer object). When glBufferSubData returns, you can immediately modify or delete whatever memory pointer you gave it, as OpenGL has already read as much as it wants.

Legacy note: The only OpenGL functions that behave differently are functions that end in "Pointer". When these use client-side memory (which is no longer permitted in core OpenGL), the pointers are stored for a period of time. During that period, they must remain valid.

Dark Photon
03-29-2013, 01:23 PM
For functions like glVertexAttribPointer, glBufferSubData,glUniform4fv - these all take pointers as arguments to data that is stored in the client side. At what point am I free to start modifying (or freeing) that data?

Legacy note: The only OpenGL functions that behave differently are functions that end in "Pointer".
To your question gonkgonk, let me also mention one gotcha on the above comment, as it is not legacy. It is applicable regardless.

Whether you're using client arrays or VBOs (with binding or bindless), the "*Pointer" calls (e.g. glVertexAttribPointer) store off a pointer value. That pointer value is not "evaluated" until the batch call(s) that follow for which that vertex attribute is enabled.

In the case of client arrays batches, that pointer is a client side pointer (CPU pointer). In the case of VBO batches, that pointer is a server side pointer (GPU/driver pointer).

As a for instance, if using VBOs to render a batch, you can't stream a few vtx attribs into a VBO, register them with "*Pointer" calls, then orphan the VBO (i.e. reallocate the VBO), and then stream a few more vtx attribs into a VBO, registering them with a "*Pointer" call. The orphan operation just messed up the memory under your first few vtx attrib bindings. Those pointers aren't evaluated until the batch draw call(s).

(NOTE: I use the expression "*Pointer" loosely here, as with bindless batches the corresponding call that provides the pointer is glBufferAddressRangeNV, not glVertexAttrib*Pointer.)