Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Page 1 of 2 12 LastLast
Results 1 to 10 of 16

Thread: VAO: Performance questions

  1. #1
    Intern Contributor
    Join Date
    Oct 2011
    Posts
    57

    VAO: Performance questions

    I'm having a lot of trouble finding decent documentation about VAOs beyond how to use them, which is clear enough. I'm mostly concerned about the impact of changing a VAO state as I'm not sure how the driver is going to react to this.

    The context of the problem:

    I'm using meshes with a large amount of triangles which require some form of spatial subdivision. As a first design alternative, this is being implemented as a single VAO with the attached VBOs that contain the mesh information and an IBO with the whole index that would allow to draw the whole mesh, if necessary (rarely used in this case, but still).

    The mesh is subdivided with an Octree-like structure and each node contains an IBO with the index data of the triangles stored in the node. There's obviously other data stored that's not used for rendering, including other topology data, which is irrelevant to the question.

    When rendering, the sections that are to be drawn are culled, the IBOs gathered and finally the single VAO is bound and its IBO is reassigned before a glDrawElements call is issued. So it goes:
    - Bind VAO
    - Loop for each IBO
    --- Bind IBO with glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,iboID)
    --- Render with glDrawElements

    The question:

    What would be the expected impact of changing a VAO's state bind state? I understand this is a very relative question, but I'm ok with a relative answer as well. Is the impact expected to be the same as changing any other bind or is it going to cause something more expensive like a client side rebuilding of all the VAO data and subsequent upload to the GPU?

    Two alternative implementations that come to mind are:
    - Store each node's data into separate VAOs, so it would be interesting if I could get some insight in the cost of swaping a VAO compared to swaping a VAO's buffer.

    - Create a huge single IBO that is generated as the mesh is split in pieces and store in each node only the starting index and element count then use glMultiDrawElements to send all the calls at once. Note that I have not used glMultiDraw* in any real situation yet, so I may perhaps be misunderstanding its usage.


    I'm leaning towards reimplementing everything with the last method as it would seem intuitively a better choice, but I would like to get some insight on the actual performance difference between these design patterns.

    Yes, I understand that it will all depend on what else my application does, so I'm not asking for hard numbers. If you can share your experience with this I'd be glad to hear it!

    Thank you!

  2. #2
    Junior Member Regular Contributor
    Join Date
    Nov 2012
    Location
    Bremen, Germany
    Posts
    149
    Hmm - I used to think of VAOs more like a for-convenience thing than anything else, so I'd guess changing particular attributes should be no problem performance-wise.

    Before bothering with implementing a more efficient way to emit the draw-commands I'd check twice if a vast number of gl-Calls is slowing down things. It reads like you'd be doing one rebind to the node index-buffer and then doing a draw per node. That is unlikely to hit performance if you don't have a huge number of nodes in my experience.
    Last edited by hlewin; 07-27-2013 at 08:40 PM.

  3. #3
    Junior Member Regular Contributor
    Join Date
    Nov 2012
    Location
    Bremen, Germany
    Posts
    149
    Reading the WIKI here makes me wonder though. I didn't think that the GL_ELEMENT_ARRAY_BUFFER​ is part of a VAOs state to start with and being unable to bind a buffer to that target without a VAO is something that would be completely new to me although I've implemented and used those without problems...

  4. #4
    Senior Member OpenGL Guru
    Join Date
    May 2009
    Posts
    4,948
    The wiki, by and large, describes only the behavior of the core profile. If you're using the compatibility profile, you won't get that behavior. Or if you're using NVIDIA drivers from a year or two back.

    As to the main thrust of the OP, the performance characteristics of VAOs are generally unknown. There have been, to my knowledge, no recent, detailed performance analyses of the use of VAOs against non-VAO rendering across multiple hardware vendors. Valve did some tests, saying that VAOs weren't helping them, but it's not clear what their specific rendering circumstances were. And of course, the (relatively) new ARB_vertex_attrib_binding extension could have effects on top of VAOs or without them.

    At the end of the day, if performance really matters to you, you're going to have to profile it yourself.

  5. #5
    Junior Member Regular Contributor
    Join Date
    Nov 2012
    Location
    Bremen, Germany
    Posts
    149
    This is something I'd find noteworthy. I'll have to spend a thought or two how this will effect the behaviour from the things I've implemented so far when switching profiles.

  6. #6
    Junior Member Regular Contributor
    Join Date
    Nov 2012
    Location
    Bremen, Germany
    Posts
    149
    Quick-reading the VAO-spec I cannot find anywhere where element arrays are mentioned.

  7. #7
    Senior Member OpenGL Guru
    Join Date
    May 2009
    Posts
    4,948
    I don't see where it mentions that it stores glVertexPointer's data either; that doesn't mean it's not there.

    The specific text in question is:

    The resulting vertex array object is a new state vector, comprising all the state values listed in tables 6.6 (except for the CLIENT_ACTIVE_TEXTURE selector state), 6.7, and 6.8 (except for the ARRAY_BUFFER_BINDING state).
    If you check the 2.1 specification and track down table 6.8, sure enough, you'll see ELEMENT_ARRAY_BUFFER_BINDING there.

  8. #8
    Junior Member Regular Contributor
    Join Date
    Nov 2012
    Location
    Bremen, Germany
    Posts
    149
    From the VAO-spec linked above:
    Queries for VERTEX_ARRAY_POINTER, NORMAL_ARRAY_POINTER, COLOR_ARRAY_POINTER, SECONDARY_COLOR_ARRAY_POINTER, INDEX_ARRAY_POINTER, TEXTURE_COORD_ARRAY_POINTER, FOG_COORD_ARRAY_POINTER, or EDGE_FLAG_ARRAY_POINTER return the value stored in the currently bound
    vertex array object.
    I'll have a look at the whole GL-spec though. Semantically I understood the wiki-paragraph about VAOs as to contain the array-settings enumerated above as well as the generic vertex-attributes which would seem fitting as these contain the data about how vertices are specified whereas element-indices refer to the vertices defined as a whole.

  9. #9
    Junior Member Regular Contributor
    Join Date
    Nov 2012
    Location
    Bremen, Germany
    Posts
    149
    This really seems contradictory, but I couldn't spot that the element-index-pointer (dunno the GLenum out of my head) is part of the vao. It's likely that only the buffer-bindings for pointers contained in the vao get actually stored. The vao spec:
    All state related to the definition of data used by the vertex processor is encapsulated in a vertex array object.
    The sentence you cited is either confusing by not making clear that "state values" means "such state values" or it is strange that the vao should contain data that cannot be queried for. I didn't test this yet, but maybe I'll come back to this.

  10. #10
    Senior Member OpenGL Guru
    Join Date
    May 2009
    Posts
    4,948
    The sentence you cited is either confusing by not making clear that "state values" means "such state values"
    I don't see how "such" would in any way affect the meaning of the sentence. Indeed, that would make the sentence less accurate. It's saying that all of the pieces of state in those tables, minus the specific pieces mentioned, are part of VAO state.

    It's not saying "stuff like what's listed in the table." It's saying "these things right here are exactly and only what makes up the VAO's state vector."

    or it is strange that the vao should contain data that cannot be queried for.
    Table 6.8 is a state table. In that state table is both the enumerator name for the piece of state and the function used to query it.

    The meaning is completely unambiguous.

    The only reason they mentioned those others in the glGetPointerv query section is because they were already listed there in 2.1 as being queries for glGetPointerv. So they had to specifically update the language to say that they came from the object. Note that glGetIntegerv (the function you use to query buffer bindings) doesn't have an equivalent list because that list would be too huge.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •