Mutiple VAOs and VBOs

Started by
27 comments, last by Matias Goldberg 9 years, 5 months ago
I was wondering, which is better or more efficient to do in this scenario?

Lets say I want to use multiple VBOs, they are setup the same, and each frame I change what VBO i'm writing to.

Would it be beneficial to have VAOs too or should I just use the VBOs. For each VBO I would need a VAO right?

Are there any downsides to this?
Advertisement

I'm using a single VAO and switching multiple VBOs. This doesn't seem to have any performance problems, at least in my app. The upside is that from OpenGL 3 Core profile VAOs are mandatory anyway so you might as well start using them. As to should you use one or multiple VAOs depends on your case. Do you have many state changes that a VAO can hold for you? If so then maybe it's better to have multiple VAOs. I think you'll have to measure both to see if it gives you a boost.


I'm using a single VAO and switching multiple VBOs.

VAO are intended to be a light-weight set of bindings. The whole point is that you can cheaply keep one around for each VBO setup, to avoid having to re-bind the VBO each draw call.

Instead, you are keeping a single VAO around, and paying the rebind cost every single draw call. This makes no sense to me.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

This makes no sense to me.

The app I'm talking about previously didn't use VAOs at all. After moving to higher OpenGL versions (where VAO is required) I tested impact of per-VBO VAOs and the performance difference was a noise within a measurement error. All in all it was easier (from refactoring point of view) )to just slap a single VAO across the app.

So in principle I understand and completely agree with your assessment. In practice though I tend to believe in what I see and not what I "think" makes sense.

It might be a driver issue or just a pattern my particular app uses. I'm not discarding VAOs. Not at all. All I'm saying is "measure". I think that's a sensible approach.


In practice though I tend to believe in what I see and not what I "think" makes sense.

Sure, various drivers don't derive any measurable performance benefit from VAOs. There are also still drivers where immediate mode + display lists are still the performance path.

Which is why I'd rather you weren't handing out advice based on generalizing results on a limited set of hardware/drivers.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

In more practical terms it's going to be easier for you to make use of the GL_ARB_vertex_attrib_binding extension.

The problem with a traditional setup is that the buffer specified by glBindBuffer call is latched state. glBindBuffer on it's own doesn't do much at all; it just provides a way to signify to future GL calls which buffer you want them to use. In terms of vertex specification, what this means is that the glVertexAttribPointer call is the one that actually picks up the currently bound buffer and makes it part of the vertex attrib state.

The impact of this is that you can't just change your buffer (via glBindBuffer calls) and expect everything to work: you need to reissue a full set of glVertexAttribPointer calls too.

Sometimes that's what you want (or need to do), but in cases where you just want to change the buffer but leave everything else the same, vertex attrib binding provides a mechanism for it.

So, as a one-time-only step you create and bind your VAO then issue a set of glVertexAttribFormat and glVertexAttribBinding calls.

Then when drawing all that you need is to re-bind your VAO and issue glBindVertexBuffer calls to specify which buffer(s) are using. That's a perfect fit for the use case outlined in the OP.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

Sure, various drivers don't derive any measurable performance benefit from VAOs. There are also still drivers where immediate mode + display lists are still the performance path.

Which is why I'd rather you weren't handing out advice based on generalizing results on a limited set of hardware/drivers.

Non-VAO solutions are not as old as display lists, and frankly still quite wide spread, so I don't see a point in comparing the two (apart from trying to ridicule what I said).

I don't understand your hostility. I specifically indicated these were my results from my app and said that the OP should measure impact in his case.

If you're an advocate for VAOs then that's fine and I don't have anything against them. If they have a real world impact then I'm all for it but why dismiss a valid point that the benefit is not always there?


If you're an advocate for VAOs then that's fine and I don't have anything against them. If they have a real world impact then I'm all for it but why dismiss a valid point that the benefit is not always there?

If you had reproducible data demonstrating that correct use of VAO resulted in decreased performance, I wouldn't have a problem with your statement.

But since your data indicates it to be a wash in your case, and existing benchmarks note measurable performance gains, I'd prefer that we continue to teach best practices.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

If you had reproducible data demonstrating that correct use of VAO resulted in decreased performance, I wouldn't have a problem with your statement.

Why do you keep exaggerating like that? When have I ever said anything about decreased performance?? I merely indicated that the change was negligible in my particular case.

Gosh you are a difficult person to talk to. I don't have the data to back me up (it was some time ago and I don't have the time to redo that test) so I will just go ahead and agree that everyone should use VAOs everywhere and all the time...

There is contradictory information regarding multiple VAOs vs one single VAO and rebind.

Now, there is a 3rd option: AZDO. Azdo is about using one huge single VBO (or very few of them) and manual manipulation using unsynchronized mapping and fences (it's very Mantle-like behavior). Then place all the meshes in the same VBO at different regions (offsets) of the memory. When you've exhausted the VBO pool, create another VBO.

Because there are very few VBOs, now VAOs become more a matter of a "vertex format layout" specification, so you would only need one VAO per vertex format (still accounting there can be two VAOs for the same vertex format if you end up needing a few more vbos).

If you sort your draw calls by vertex format, the draw call overhead approaches zero, as you barely will need to switch vaos or vbos (or respecify any attribute).

This topic is closed to new replies.

Advertisement