<p>My question is : to allocate <strong>static</strong> mesh data (vertex/index buffers that never change), is it best :</p>

<ul>
<li>To go the "obvious" way : "1 mesh = 1 VBO", submitting data using glBufferData with GL_STATIC_DRAW flag.</li>
<li>To preallocate big buffers (say, a few megabytes) using glBufferStorage with a GL_DYNAMIC_STORAGE_BIT flag, and using glBufferSubData to "fill" the buffer with actual mesh data, side by side in the same VBO. I keep the VBO ID and offset in the VBO of every mesh.</li>
<li>Besides, to transfer data there is also the <a href="https://www.khronos.org/opengl/wiki/Buffer_Object#Persistent_mapping" rel="nofollow noreferrer">persistent-mapped buffer</a> technique. I could map all or part of the buffer, and write to it directly (no glBufferSubData needed). I don't see the point for static data. Perhaps I'm mistaken?</li>
</ul>

<p>I implemented <a href="https://bitsquid.blogspot.com/2015/08/allocation-adventures-3-buddy-allocator.html" rel="nofollow noreferrer">a buddy allocator</a> allowing me to split an OpenGL buffer in power-of-2 blocks to follow my second alternative. It allows me to "pack" multiple meshes in the same VBO, and to keep reusing it as mesh allocation/deallocation occurs.</p>

<p>It works great, but no huge speedup is observed vs. a more classic approach.
Then reading <a href="http://on-demand.gputechconf.com/gtc/2014/presentations/S4379-opengl-44-scene-rendering-techniques.pdf" rel="nofollow noreferrer">these slides</a> for example (especially slide 24), they're basically saying this approach isn't the efficient path except for very specific cases (uniform buffer, less than 64 kb, offsets have to be multiple of 4 !). </p>

<p>Are there some "best practices" regarding buffer data management ? Is it useful to worry about it at all ?</p>

<p>I've read tons of material regarding OpenGL buffer management lately, and now I feel a bit lost. It would be great to have a "recap" of all the possibilities and expected relative performance of each vs. the others.</p>

<p>(Note : I'm targeting OpenGL 4.5, so DSA is allowed).</p>

CC BY-SA 4.0
2020-04-30T05:43:40.930Z
It's not clear to me how this data can be "static" if you're unaware of how much data you're actually going to put into it. If you are modifying it, then it isn't "static".
Nicol Bolas
CC BY-SA 4.0
2020-04-30T06:32:04.173Z
@NicolBolas I think he is referring to static data that is loaded and unloaded during runtime, like the geometry of a specific section in a large computer game world, which won't change after it is loaded. However, in case I am right, I would like to know why this is a concern. It shouldn't be a regular event? So no real performance concern, or am I missing something? Apart from that, the obvious benefit of a large buffer should be that you can render more stuff with a single draw call.
wychmaster
CC BY-SA 4.0
2020-04-30T13:30:24.233Z
Excuse my poor choice of wording. @wychmaster is right. I render a game world where a lot of 3D mesh data can come and go because these are game entities. But the data is "static" (i.e. uploaded on GPU once, then read-only). By "render more stuff with a single draw call", did you think about the glDraw*Indirect family of functions ? That's something I've yet to try.
Scylardor
CC BY-SA 4.0
2020-04-30T14:48:07.347Z
@Scylardor: "*But the data is "static" (i.e. uploaded on GPU once, then read-only).*" The "data" may be static, but the *buffer* is not, since you're uploading multiple times. It seems to me that you're not talking about a static case; you're talking about streaming content where you're progressively adding and removing content based on the current level/camera position/etc.
Nicol Bolas
CC BY-SA 4.0
2020-04-30T14:52:33.283Z
@Scylardor: Ultimately, there are no "best practices", as any kind of buffer usage depends entirely on your uploading patterns. That is, when are you uploading data, is there any coherency to the uploads, when does data become irrelevant and thus can go away, etc. There's no one-size-fits-all solution; it has to be tailored to your specific needs, or you will be sacrificing performance.
Nicol Bolas
CC BY-SA 4.0
2020-05-01T08:56:47.467Z
@Scylardor Yes. Try searching "approaching zero driver overhead opengl" (short AZDO). It is a collection of techniques to find the "fastest paths" through the OpenGL API. Here is a nice talk about it: https://www.gdcvault.com/play/1020791/Approaching-Zero-Driver-Overhead-in --- It will address the thing I mentioned (if I remember correctly)
wychmaster
CC BY-SA 4.0
2020-05-06T00:42:00.490Z
Thank you :-) I already watched that talk. Cool information about sparse bindless textures etc. TBH I'm not there yet, still trying to figure out correct buffer usage for my application first, so it's going to take some time to test things out. I'll maybe update that question or make a new one when I have more relevant info.
Scylardor
<opengl>
Best practices fo OpenGL static buffer data : what is best for performance?
Scylardor
# Best practices fo OpenGL static buffer data : what is best for performance?

(Asked by: username_0 on 2020-04-30)

My question is : to allocate **static** mesh data (vertex/index buffers that never change), is it best :

* To go the "obvious" way : "1 mesh = 1 VBO", submitting data using glBufferData with GL\_STATIC\_DRAW flag.
* To preallocate big buffers (say, a few megabytes) using glBufferStorage with a GL\_DYNAMIC\_STORAGE\_BIT flag, and using glBufferSubData to "fill" the buffer with actual mesh data, side by side in the same VBO. I keep the VBO ID and offset in the VBO of every mesh.
* Besides, to transfer data there is also the [persistent-mapped buffer](https://www.khronos.org/opengl/wiki/Buffer_Object#Persistent_mapping) technique. I could map all or part of the buffer, and write to it directly (no glBufferSubData needed). I don't see the point for static data. Perhaps I'm mistaken?

I implemented [a buddy allocator](https://bitsquid.blogspot.com/2015/08/allocation-adventures-3-buddy-allocator.html) allowing me to split an OpenGL buffer in power-of-2 blocks to follow my second alternative. It allows me to "pack" multiple meshes in the same VBO, and to keep reusing it as mesh allocation/deallocation occurs.

It works great, but no huge speedup is observed vs. a more classic approach.
Then reading [these slides](http://on-demand.gputechconf.com/gtc/2014/presentations/S4379-opengl-44-scene-rendering-techniques.pdf) for example (especially slide 24), they're basically saying this approach isn't the efficient path except for very specific cases (uniform buffer, less than 64 kb, offsets have to be multiple of 4 !).

Are there some "best practices" regarding buffer data management ? Is it useful to worry about it at all ?

I've read tons of material regarding OpenGL buffer management lately, and now I feel a bit lost. It would be great to have a "recap" of all the possibilities and expected relative performance of each vs. the others.

(Note : I'm targeting OpenGL 4.5, so DSA is allowed).

**Tags:** opengl

> **Comments:**
> **username_1**: It's not clear to me how this data can be "static" if you're unaware of how much data you're actually going to put into it. If you are modifying it, then it isn't "static".  
> **username_2**: @username_1 I think he is referring to static data that is loaded and unloaded during runtime, like the geometry of a specific section in a large computer game world, which won't change after it is loaded. However, in case I am right, I would like to know why this is a concern. It shouldn't be a regular event? So no real performance concern, or am I missing something? Apart from that, the obvious benefit of a large buffer should be that you can render more stuff with a single draw call.  
> **username_0**: Excuse my poor choice of wording. @username_2 is right. I render a game world where a lot of 3D mesh data can come and go because these are game entities. But the data is "static" (i.e. uploaded on GPU once, then read-only). By "render more stuff with a single draw call", did you think about the glDraw*Indirect family of functions ? That's something I've yet to try.  
> **username_1**: @username_0: "*But the data is "static" (i.e. uploaded on GPU once, then read-only).*" The "data" may be static, but the *buffer* is not, since you're uploading multiple times. It seems to me that you're not talking about a static case; you're talking about streaming content where you're progressively adding and removing content based on the current level/camera position/etc.  
> **username_1**: @username_0: Ultimately, there are no "best practices", as any kind of buffer usage depends entirely on your uploading patterns. That is, when are you uploading data, is there any coherency to the uploads, when does data become irrelevant and thus can go away, etc. There's no one-size-fits-all solution; it has to be tailored to your specific needs, or you will be sacrificing performance.  
> **username_2**: @username_0 Yes. Try searching "approaching zero driver overhead opengl" (short AZDO). It is a collection of techniques to find the "fastest paths" through the OpenGL API. Here is a nice talk about it: https://www.gdcvault.com/play/1020791/Approaching-Zero-Driver-Overhead-in --- It will address the thing I mentioned (if I remember correctly)  
> **username_0**: Thank you :-) I already watched that talk. Cool information about sparse bindless textures etc. TBH I'm not there yet, still trying to figure out correct buffer usage for my application first, so it's going to take some time to test things out. I'll maybe update that question or make a new one when I have more relevant info.  

---

## 0 answers

