View more

View more

View more

Image of the Day Submit

IOTD | Top Screenshots

The latest, straight to your Inbox.

Subscribe to GameDev.net Direct to receive the latest updates and exclusive content.

Vertex Array Object + Direct State Access

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

20 replies to this topic

#1Chris_F  Members

Posted 02 December 2013 - 10:15 PM

As a disclaimer I am really not versed in OpenGL. I am trying to convert the following to use DSA:

glBindVertexArray(vao);

glBindBuffer(GL_ARRAY_BUFFER, vertex_attrib_buffers[0]);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);

glBindBuffer(GL_ARRAY_BUFFER, vertex_attrib_buffers[1]);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, NULL);

glBindBuffer(GL_ARRAY_BUFFER, vertex_attrib_buffers[2]);
glVertexAttribPointer(2, 3, GL_UNSIGNED_BYTE, GL_TRUE, 0, NULL);

glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);


I have found the following functions:

glVertexArrayBindVertexBufferEXT()
glVertexArrayVertexAttribBindingEXT()
glVertexArrayVertexAttribFormatEXT()
glEnableVertexArrayAttribEXT()


but I am unsure of how to use them. I can find almost nothing about them online.

Edited by Chris_F, 02 December 2013 - 10:53 PM.

#2michalferko  Members

Posted 03 December 2013 - 01:42 AM

These are described in the actual DSA extension: http://www.opengl.org/registry/specs/EXT/direct_state_access.txt

You can get arguments and their names from that site.

If you are unsure, the usual approach is that whatever you call in a Bind function (BindVertexArray, BindTexture) becomes the first parameters of the DSA call. The other parameters are then the exact same parameters that you would use in a non-DSA function.

Also take a look at this: http://www.g-truc.net/post-0363.html

Keep in mind that when working with vertex array objects, there is one thing you cannot do with DSA and must use the old way: http://stackoverflow.com/questions/3776726/how-to-bind-a-element-buffer-array-to-vertex-array-object-using-direct-state-a

#3Chris_F  Members

Posted 03 December 2013 - 06:07 PM

These are described in the actual DSA extension: http://www.opengl.org/registry/specs/EXT/direct_state_access.txt

You can get arguments and their names from that site.

Yes, I read that. It is not complete. There is no mentioning at all of the first three functions I listed anywhere in that document.

#4L. Spiro  Members

Posted 03 December 2013 - 10:02 PM

but I am unsure of how to use them.

Move back to VBO’s.

L. Spiro

#5Chris_F  Members

Posted 04 December 2013 - 05:09 PM

Keep in mind that when working with vertex array objects, there is one thing you cannot do with DSA and must use the old way: http://stackoverflow.com/questions/3776726/how-to-bind-a-element-buffer-array-to-vertex-array-object-using-direct-state-a

Wow, that is strange. I take it they accidentally left something like this out of the spec for some reason?

void glVertexArrayBindElementArrayBufferEXT(GLuint vao, GLuint buffer)


I guess it would be easy enough to implement on your own...

Move back to VBO’s.

OK, I'm confused now. I thought that VAOs were not optional in modern OpenGL. By "don't use VAOs," do you mean only use a single VAO and just keep modifying that one? Also, is it "vertex attribute object" or "vertex array object," or are those actually two distinct things?

Edited by Chris_F, 04 December 2013 - 05:11 PM.

#6Kaptein  Prime Members

Posted 04 December 2013 - 05:25 PM

I'm confused as well.

I have 300 VBOs, give or take, that all have the same attributes. Hence why I chose VAOs because they remember my attribute bindings.

My reasoning is that I only end up with 2 calls to render something:

glBindVertexArray(vao);

glDraw...();

What is the correct course of action here?

Edited by Kaptein, 04 December 2013 - 05:26 PM.

#7L. Spiro  Members

Posted 04 December 2013 - 09:05 PM

do you mean only use a single VAO and just keep modifying that one?

I definitely don’t mean that; that would be the worst-case scenario possible.

And they are not required as far as I know; the very fact that they appear in your list of functions as extensions means in any case you definitely are not strictly required to use them, and since they build on top of basic VBO functionality I doubt they will ever be strictly required.

Also, is it "vertex attribute object" or "vertex array object,"

Vertex Array Objects.

Hence why I chose VAOs because they remember my attribute bindings.

Or you could just set the attribute states once manually and render all of your VBO’s; that would be faster, especially if you are re-binding the VAO for each draw.

What is the correct course of action here?

Until VAO performance meets standards, the generally accepted course is to use raw VBO’s.
And if you emulate VAO functionality manually with a layer to remove redundant state changes (something you should be doing no matter what) a VAO will likely never be as fast as your manual setup calls.

L. Spiro

Edited by L. Spiro, 04 December 2013 - 09:07 PM.

#8Chris_F  Members

Posted 04 December 2013 - 10:26 PM

I definitely don’t mean that; that would be the worst-case scenario possible.

And they are not required as far as I know;

I am even more confused now. Can you point me to an example of how to render with just VBOs and no VAO?

Edit: Are you talking about using functions like glVertexPointer in conjunction with VBOs? If so I should point out that all of that has been deprecated and is not even available in core profile as far as I know.

the very fact that they appear in your list of functions as extensions means in any case you definitely are not strictly required to use them, and since they build on top of basic VBO functionality I doubt they will ever be strictly required.

DSA is an extension, not VAOs. VAOs are core functionality.

Edited by Chris_F, 04 December 2013 - 10:58 PM.

#9phantom  Members

Posted 05 December 2013 - 06:19 PM

VAOs are certainly NOT a requirement for OpenGL... god, if it was, the horror... something you HAD to use with a bind-to-edit model... sweet jesus.

The commands you'd be after, based on the GL4.4 reference card, are those such as glVertexAttribPointer and friends ( http://www.opengl.org/wiki/Category:Core_API_Ref_Vertex_Arrays ) which allow you to setup buffer input via attributes on the shaders.

#10Chris_F  Members

Posted 05 December 2013 - 08:25 PM

VAOs are certainly NOT a requirement for OpenGL... god, if it was, the horror... something you HAD to use with a bind-to-edit model... sweet jesus.

The commands you'd be after, based on the GL4.4 reference card, are those such as glVertexAttribPointer and friends ( http://www.opengl.org/wiki/Category:Core_API_Ref_Vertex_Arrays ) which allow you to setup buffer input via attributes on the shaders.

Then how do you render in GL 3.3/4.x core profile without a VAO? I was under the impression that glVertexAttribPointer was only for VAOs.

EDIT: Just removed my VAO, bound my buffers, called glVertexAttribPointer and all I have is a black screen.

Edited by Chris_F, 05 December 2013 - 08:34 PM.

#11Kaptein  Prime Members

Posted 05 December 2013 - 08:30 PM

I also tried using glVertexAttribPointer without VAOs and it simply didn't work.

How about a simple pseudo code example?

#12beans222  Members

Posted 05 December 2013 - 08:37 PM

To go one wiki page further, under glVertexAttribPointer: "GL_INVALID_OPERATION​ is generated if no vertex array object is bound."

The following thread is also relevant, but nobody explicitly says anything like "yes, I've fallen back to older GLSL and non-generic attributes":

http://www.gamedev.net/topic/649916-valve-opengl-tips-and-tricks/

New C/C++ Build Tool 'Stir' (doesn't just generate Makefiles, it does the build): https://github.com/space222/stir

#13Chris_F  Members

Posted 05 December 2013 - 08:44 PM

To go one wiki page further, under glVertexAttribPointer: "GL_INVALID_OPERATION​ is generated if no vertex array object is bound."

The following thread is also relevant, but nobody explicitly says anything like "yes, I've fallen back to older GLSL and non-generic attributes":

http://www.gamedev.net/topic/649916-valve-opengl-tips-and-tricks/

VAO is mandatory. Just not for people who are using compatibility mode with deprecated functionality apparently.

#14phantom  Members

Posted 06 December 2013 - 04:12 AM

Upon slightly more careful reading of the Red Book it seems this is the case... well played GL, well played.

I guess this will make sense once the ARB_multi_bind extension is common as you can use VAOs for VB attributes (types, stride etc) and use multi-bind to replace all the buffer bindings in one shot... either based on the performance and usage case issues I'd pretty much only use it for that right now; bind the attributes to a VAO (probably drag it around with my materials/shaders) and just over write the buffer bindings as required.

#15mhagain  Members

Posted 06 December 2013 - 04:54 AM

ARB_vertex_attrib_binding also helps make VAOs make more sense - you can set up your formats, layouts, strides, etc in a VAO and then just bind the VAO and replace the buffers as required.  This is a better match to the common usage pattern of having the same vertex format but different buffers.

Unfortunately vertex attrib binding is not commonly supported either (thanks a lot, AMD and Intel).

The first 3 functions mentioned in the OP are part of ARB_vertex_attrib_binding and are documented with that extension.

It appears that the gentleman thought C++ was extremely difficult and he was overjoyed that the machine was absorbing it; he understood that good C++ is difficult but the best C++ is well-nigh unintelligible.

#16Chris_F  Members

Posted 06 December 2013 - 02:41 PM

ARB_vertex_attrib_binding also helps make VAOs make more sense - you can set up your formats, layouts, strides, etc in a VAO and then just bind the VAO and replace the buffers as required.  This is a better match to the common usage pattern of having the same vertex format but different buffers.

Unfortunately vertex attrib binding is not commonly supported either (thanks a lot, AMD and Intel).

The first 3 functions mentioned in the OP are part of ARB_vertex_attrib_binding and are documented with that extension.

Luckily I'm targeting OpenGL 4.3+ so I have access to ARB_vertex_attrib_binding as a core feature.

#17phantom  Members

Posted 10 December 2013 - 05:59 AM

So, it turns out that you might want to be using VAOs after all....

http://www.openglsuperbible.com/2013/12/09/vertex-array-performance/

Which makes me wonder what Valve were doing to come to their conclusion, or maybe NV's Linux drivers just suck more than the Windows ones in this respect (NV benchmark pretty poorly in the above link too compared to AMD)

#18Kaptein  Prime Members

Posted 10 December 2013 - 09:39 AM

The linux drivers for both AMD and Nvidia aren't as mature as their windows counterparts. It might be that it's just a collection of performance tips relating specially to linux. There is no viable alternative to VAOs though, which is why we are all so confused. You can't skip VAOs because you often have 300 VBOs with the same attribs, and attribs aren't remembered for VBOs, or anything else, except VAOs.

Note: I have had better performance on Linux overall though!

OpenGL is a bit ...-backwards sometimes.

You ideally just "enable" your 5 attribs, and then proceed to render 300 VBOs. You can't. It sucks.

Instead I have to create 300 VAOs, with 5 "enabled" attribs each. Then render 300 VAOs.

The madness stops at GL 4.x (from superbible):

"However, these functions were introduced in OpenGL 4.3 and so may not have widespread support just yet, whereas VAO has been in core OpenGL since version 3.0"

What were they thinking?

Edited by Kaptein, 10 December 2013 - 09:42 AM.

#19L. Spiro  Members

Posted 10 December 2013 - 04:05 PM

So, it turns out that you might want to be using VAOs after all....

http://www.openglsuperbible.com/2013/12/09/vertex-array-performance/

Which makes me wonder what Valve were doing to come to their conclusion, or maybe NV's Linux drivers just suck more than the Windows ones in this respect (NV benchmark pretty poorly in the above link too compared to AMD)

I would like to see his benchmarks when he is not redundantly calling glEnableVertexAttribArray() and glDisableVertexAttribArray().

L. Spiro

#20Dark Helmet  Members

Posted 13 December 2013 - 08:49 PM

There is no viable alternative to VAOs though, which is why we are all so confused.

Cross-platform, no. But on NVidia, bindless can easily exceed the performance you get from VAOs, and the reason is intuitive.

You ideally just "enable" your 5 attribs, and then proceed to render 300 VBOs. You can't. It sucks.

Instead I have to create 300 VAOs, with 5 "enabled" attribs each. Then render 300 VAOs.

No you don't. Having a bazillion little VAOs floating around with all the cache misses that go with them isn't necessarily the best approach. Best case, use bindless (does an end-run around the cache issues, but is NV-only) or a streaming VBO approach with reuse (which keeps the bind count down, and works cross-platform).

If you have a number of separate, preloaded VBOs, you absolutely can't/refuse to make them large enough to keep you from being CPU bound for some reason, and you can't/won't use bindless, then fall back on (in the order of the performance I've observed on NVidia) 1) VBOs with VAOs, one per batch state combination, 2) client arrays, or 3) VBOs without VAOs or with one VAO for all.

In case it's not obvious, I do what gives me the best performance. I'm not a core purist.

Its really unfortunate AMD hasn't stepped up and supported bindless in their OpenGL drivers, at least for launching batches (vertex attribute and index list specification).

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.