When is it okay to delete an OpenGL buffer?

5 May 2016

The short answer

The spec says you can call glDeleteBuffers on a buffer object as soon as you no longer wish to directly reference that buffer. However, in practice you should not delete a buffer until you’re completely done performing any operation relating to the memory referenced by that buffer.

The longer answer

According to the OpenGL specification, you can, for instance, reference a vertex buffer object (VBO) in a vertex array object (VAO) and then immediately delete the VBO. The VAO will retain the reference to the VBO, which will only truly get deleted when all references to it are deleted. The relevant parts from the spec that explain this are section 5.1.2:

Attachments to unbound container objects, such as deletion of a buffer attached to a vertex array object which is not bound to the context, are not affected and continue to act as references on the deleted object, as described in the following section.

And 5.1.3:

When a buffer, texture, sampler, renderbuffer, query, or sync object is deleted, its name immediately becomes invalid (e.g. is marked unused), but the underlying object will not be deleted until it is no longer in use. A buffer, texture, sampler, or renderbuffer object is in use if any of the following conditions are satisfied:

  • the object is attached to any container object
  • the object is bound to a context bind point in any context
  • any other object contains a view of the data store of the object.

The advantages of doing that sort of early buffer deletion are relatively small: deleting things after you’re done referencing them makes the number of things you need to track and delete yourself slightly fewer. It can also prevent you from using a VBO that you didn’t mean to.

However, the drawbacks are not remotely worth it: namely, doing so can cause all kinds of terrible behaviour on some platforms. Segfaults, out of memory errors, and just plain not working were all experienced by some users of my gl-utils library for CHICKEN Scheme. It was an ugly problem to have, as I’ve never used any drivers that were non-conformant in this way, and the issues that arise all happen well away from the source of the problem. Thanks to Negdayen, we were able to isolate the issue to this harmless seeming operation.

The solution is, of course, to simply not delete buffers until you are absolutely done with them. Since this is already something you need to do if you’re doing any dynamic updates to a buffer, it shouldn’t be too painful!