Vertex Buffers Question

Started by
13 comments, last by WebsiteWill 20 years, 5 months ago
No worries, I wouldn''t be too worries about learning shaders just yet. I''m not, heheheh.
Advertisement
Ahhh the occassional beauties of MSDN.
It appears that performance wise, there is typically not much reason to use static buffers at all.
Assuming a large terrain where not nearly all of the polys can be stored in a buffer it appears that something like thsi could work.

Use a single dynamic buffer.
Each frame I figure out (using quad/octtree structure) exactly what terrain polygons are visible. I lock my buffer, pack these vertices into it (up to 1000 at a time?), unlock the buffer and then call renderPrimitive (actual call different). Then I lock the buffer again using DISCARD and put in the next set. Repeat until all terrain has been rendered.
Next I move on to objects and repeat the above steps except I''ll be calling renderPrimitive after so many objects, like
Add house polys to new buffer
Lock buffer with discard flag and append nextItemPolys to buffer.
Unlock and render primitive again.
Lock again. Rinse and repeat for all objects.

Alternatively I can simply pack on polygons until I have up to 1000 in the buffer then render primitive followed by getting a new buffer pointer where I will pack in the next 1000 polys. Similar to the terrain method above.

Is this pretty standard for how this would be accomplished?
I don''t see a need to even use static buffers like this and I would pretty much only need a single dynamic buffer for everything I want to do.

This is pretty exciting!
Smiling Webby

What''s it called when you have one of those moments where things all of a sudden start to make sense and you get that feeling of "Oh yeah!" Epitomy?
No, don''t get too enthusastic about using dynamic VBs and locking with DISCARD. Ideally you want to lock a dynamic VB for discard only once per frame, preferably the first lock per frame.

The reason is that D3DLOCK_DISCARD gives the driver permission to hand you a whole new chunk of memory, distinct from the one you were working on previously. Some drivers have a fixed limit for the number of times that they will do this buffer "renaming" (where logically it''s a single buffer but in fact multiple buffers are being filled and rendered from). And if you''re locking with DISCARD before the buffer is full, then you''re wasting memory and making the driver do more work than is necessary. In short, the best practice for dynamic VBs is to attempt to fill them from start to end. When you reach the end -- when there''s not enough room for the vertices you want to fill -- lock with DISCARD and start over from the beginning. At all other times, lock with NOOVERWRITE. And some drivers have bugs when the first lock per frame isn''t D3DLOCK_DISCARD.

Whenever possible, static buffers should be preferred over dynamic. This is because static buffers typically live in local video memory -- the RAM on the card -- which is fastest for reading by the GPU but rather slow to write by the CPU. This is obviously ideal for static vertices, where the idea is that they are written once by the CPU and read many many times by the GPU.

Dynamic vertices are written often by the CPU and so are typically placed in AGP memory. This makes them slower to read by the GPU but very fast to write by the CPU (potentially even faster than regular system memory). For vertices that change frequently this makes sense, but otherwise it is sub-optimal. Put ''em in a static VB so that the GPU doesn''t have to suck them across the AGP bus every frame.

To summarize: Vertices that never change belong in static vertex buffers. Vertices that change every frame belong in dynamic VBs. Vertices that are somewhere in between should probably be dynamic.
Donavon KeithleyNo, Inky Death Vole!
Sigh

Guess I''m not grasping what it means for a vertice to never change or to change.

Is a vertice that is being animated a changing vertice? Or is the vertice FIXED in the buffer when I is created and then moved around with matrices? I mean, I know I will use matrices to handle the changes but I''m now guessing that this leaves the original vertice in the buffer unchanged so that if I load all of the vertices of a model then those values in the buffer will never ever change.

So what then would constitute changing vertices? LOD systems where one moment this section might be 10000 verts and the next frame it may only be 9900 because of some optimization? Or other similar curcumstances like particle systems that are only in memory when they are present?

Please clarify
Webby
If the values stored in the vertex buffer change then it''s dynamic, so this doesn''t apply to matrix transforms or lighting calculations. These involve the GPU reading the source vertex from the VB and modifying the values as they pass through the pipeline. The next frame or the next instance of the mesh will use the same source vertex values but the results of transformation & lighting may be different due to differing render states.

If you''re modifying the vertices using the CPU outside of the rendering pipeline -- by locking and writing values to the VB -- then they''re dynamic and belong in a dynamic vertex buffer.

Particles are usually dynamic (animated by the CPU). LOD can use static or dynamic vertices, depending on how it''s done. Say the mesh has 500 vertices at the lowest LOD. At the middle LOD another 1000 vertices are added, and at the highest LOD another 2000 vertices are added. All of these vertices can be stored together in a static VB, it''s just a question of which ones you render. Even if the higher LODs don''t use all of the lower LOD vertices, it can still be static. You''d basically just have a pool of vertices and the index buffer selects which ones are part of the LOD mesh. Or of course each LOD might have its own set of vertices with no sharing.

But if you''re using the CPU to morph vertices between LODs, then those vertices belong in a dynamic VB.

Another way to think of it is that static vertices are relatively permanent whereas dynamic vertices are disposable. Like paper plates, you typically use them once and then throw them away.
Donavon KeithleyNo, Inky Death Vole!

This topic is closed to new replies.

Advertisement