VBO Size Questions

This topic is 4556 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

My research tells me that it's best to keep a VBO under 6-8 megs. However, none of my findings are very current, so I have no way to know if this figure is accurate or not. Can someone confirm this? When considering size, assuming 6-8 megs is optimal, does this mean that each individual buffer should be less than 6-8 megs? Or does it mean total sum of all buffers? For example: 1) verts[] + colors[] + texCoords[] <= 6-8 megs Vs. 2) verts[] <= 6-8 megs, colors[] <= 6-8 megs, etc. Assuming I need to render 20,000 quads, would it be better to break things up into smaller chunks? How costly is it to switch pointers and bind different buffers? I ask because I'm optimizing a sprite engine. Currently, I don't discriminate between the "types" of sprites being sent to the engine, and they all get sent to one gigantic VBO. I'd like to break things up into multiple VBOs based on certain logic, and I'm just trying to plan out what's feasible.

Share on other sites
It's best to have one VBO for your vertex, color and texcoord

Make a struct like

struct MyVertexFormat{   float x, y, z;   uint color;   float s, t;}

The order of vertex, color and tex don't matter (I'm told)
Also, it's best that your struct is multiple of 32 bytes so make that

struct MyVertexFormat{   float x, y, z;   uint color;   float s, t;   float padding[2];}

I think 1 to 8 MB sounds good. nVidia says not too small and not too big.

Share on other sites
The size of the struct shouldn't have any effect over the size of the VBO on the card. Or am I misunderstanding the reason behind making the struct a certain size?

Actually though, I'm using Java so I can't use structs. I hope I wasn't confusing anyone with my "array math" example. To put it another way, I was wondering if the size is important due to data transfer or data storage.

For example, when I use glVertexPointer(), should the pointer be 6-8 megs? If so, this would imply that it's better to transfer 6-8 megs to the card at a time.

If the whole VBO must be 6-8 megs (glVertexPointer, glTexCoordPointer, etc), then it tells me that the card prefers storing VBOs in chunks of 6-8 megs.

Share on other sites
"The size of the struct shouldn't have any effect over the size of the VBO on the card. Or am I misunderstanding the reason behind making the struct a certain size?"

That's correct. When I said it should be multiples of 32 bytes, it's for memory alignment on ATI cards and the GPU accesses VRAM moer quickly. The information comes from ATI, in some pdf, distributed at GDC or some event.

"Actually though, I'm using Java so I can't use structs. I hope I wasn't confusing anyone with my "array math" example. To put it another way, I was wondering if the size is important due to data transfer or data storage."

I don't know about Java, but without struct, maybe you can use class. They are essentially the same thing on C++.
Both reasons can apply.
The size is important for memory management. There might not be enough VRAM so the VBO goes into AGP memory or RAM. If VBO is too big, the driver will not work too well.
If you are using streaming VBO, it might work better for the driver to push the smaller VBO to VRAM, instead of a 100 MB VBO

Memory management is really a driver thing. The GPU doesn't care how big the VBO is. The GPU prefers data that is local (xyz, color, s, t all close together)

Share on other sites
I thought I would just point out that you can only bind one buffer at a time, which means that you always need to consider position+normal+texture as a whole.

Share on other sites
Quote:
 Original post by rick_appletonI thought I would just point out that you can only bind one buffer at a time, which means that you always need to consider position+normal+texture as a whole.

That doesn't matter beacuse you can set the pointers before the draw call [smile].
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);glVertexPointer(...);glBindBuffer(GL_ARRAY_BUFFER, normalBuffer);glNormalPointer(...);glBindBuffer(GL_ARRAY_BUFFER, texCoordBuffer);glTexCoordPointer(...);glDrawElements(...);

@OP: However, as everyone has pointed out, it's good practice interleave the data as you gain better cache behavior.

Share on other sites
Quote:
Original post by deavik
Quote:
 Original post by rick_appletonI thought I would just point out that you can only bind one buffer at a time, which means that you always need to consider position+normal+texture as a whole.

That doesn't matter beacuse you can set the pointers before the draw call [smile].
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);glVertexPointer(...);glBindBuffer(GL_ARRAY_BUFFER, normalBuffer);glNormalPointer(...);glBindBuffer(GL_ARRAY_BUFFER, texCoordBuffer);glTexCoordPointer(...);glDrawElements(...);

@OP: However, as everyone has pointed out, it's good practice interleave the data as you gain better cache behavior.

I thought you could only use a single buffer, so I checked the specs. Turns out you are correct (emphasis mine)!

Quote:
 specsIn the case of vertex arrays, this extension defines not merely one binding for all attributes, but a separate binding for each individual attribute. As a result, applications can source their attributes from multiple buffers. An application might, for example, have a model with constant texture coordinates and variable geometry. The texture coordinates might be retrieved from a buffer object with the usage mode "STATIC_DRAW", indicating to the GL that the application does not expect to update the contents of the buffer frequently or even at all, while the vertices might be retrieved from a buffer object with the usage mode "STREAM_DRAW", indicating that the vertices will be updated on a regular basis.

Share on other sites

Perhaps the bit about 32 byte vertices was gleaned from this? http://www.ati.com/developer/gdc/PerformanceTuning.pdf

I wonder though, if I have only 4 floats to store per vertex is it really worth doubling the size of my buffer with padding? If I have only 1 is it worth 8x'ing the size?

Thanks, ~SPH

Share on other sites
I think I saw a slightly different slide. If 32bytes is a whole multiple of your vertex size (so vertex size = 16byte or 8 byte), then you are fine also.

Share on other sites
You would have to benchmark. Typically, people use texcoord (st) and normal (xyz) and vertex(xyz) and perhaps color (rgba) so it comes close to 32 or just over 32.
The slide says this is not good.

It's only worthwhile to make the change if your app will benifit and high end games need it.

• What is your GameDev Story?

In 2019 we are celebrating 20 years of GameDev.net! Share your GameDev Story with us.

• 10
• 11
• 13
• 9
• 9
• Forum Statistics

• Total Topics
634084
• Total Posts
3015403
×