Sign in to follow this  
Vertex333

What is the normal way to change large amounts of vertex data.

Recommended Posts

Imagine many objects that are very low poly. All objects are stored in one Vertex Buffer. Every object tells me how much space it needs, I create the VB and the objects fill it. What would be the best way if an object says, hey my data changed, I need a different amount of Vertices in the VB. 1. I could recreate the VB and recreate all Vertex data (that is odd). 2. Recreate the VB and have all Vertex data of the not changed objects in memory (which means vertex data is all in all twice). 3. Maybe create a new VB, copy the not changed stuff from the old VB to the new, add the new and release the old VB. (two VB for short duration and memcpy). 4. Create a larger VB and leave the old area in the VB and write into the new area in the VB for the changed object. (NOOVERWRITE flag) If no more data available recreate. 5. Using Index Buffer and doing something with that. 6. I don't know? Thx, Vertex

Share this post


Link to post
Share on other sites
Quote:
Original post by Vertex333
1. I could recreate the VB and recreate all Vertex data (that is odd).
2. Recreate the VB and have all Vertex data of the not changed objects in memory (which means vertex data is all in all twice).
3. Maybe create a new VB, copy the not changed stuff from the old VB to the new, add the new and release the old VB. (two VB for short duration and memcpy).
These get better as you go on, with #3 being at least reasonable. The problem you're likely to get is stalling of rendering during copies/changes. For low-poly you probably won't get large VB's but in theory you have to be careful because by double-buffering or ping-ponging can halve your available memory...

Quote:
Original post by Vertex333
4. Create a larger VB and leave the old area in the VB and write into the new area in the VB for the changed object. (NOOVERWRITE flag) If no more data available recreate.
I would imagine this is by far the best option if you must still use a single VB. This sort of approach is often used by databases - they'll pad out even individual elements (e.g. 10x 1mb objects will be allocated 20mb with a 1mb unused gap between each object) so that they can grow bigger before having to be moved to the end of the VB or before they cause a full-blown rebuild of the VB. Should you get short on VRAM you can implement a 'compact' operation that strips out unused space.

Quote:
Original post by Vertex333
5. Using Index Buffer and doing something with that.
I don't see how this would offer anything useful here.

Quote:
Original post by Vertex333
6. I don't know?
I would consider an extension on #4 myself and look into two related areas:

1. Multiple vertex buffers. I assume you've condensed the VB's so you can improve state management and/or reduce draw calls, but consider that there is still a sweet spot between reducing draw calls (READ ops) and reducing updates (WRITE ops). For 100 objects, have 4 buffers (for example) may still be a big win and you can distribute updates so that you can be rendering from 3 whilst waiting on 1 for writing...

2. Pooled-by-update vertex buffers. An enhancement on the above but to split the one large buffer based on frequency of updates. This is borrowed from the D3D10 constant buffer approach - group regularly changing constants together so that if 9/10 of your constants is, well, constant the 1 that isn't doesn't require the entire buffer of 10 to be locked/update/uploaded etc.. split them out so that regularly updated models are grouped together and likewise for mostly static ones. You could also split it based on frequency of updates and resizing - those that regularly change size fit into a padded buffer whereas those that don't can sit in a compacted buffer.


hth
Jack

Share this post


Link to post
Share on other sites
Quote:
Original post by jollyjeffers
Quote:
Original post by Vertex333
1. I could recreate the VB and recreate all Vertex data (that is odd).
2. Recreate the VB and have all Vertex data of the not changed objects in memory (which means vertex data is all in all twice).
3. Maybe create a new VB, copy the not changed stuff from the old VB to the new, add the new and release the old VB. (two VB for short duration and memcpy).
These get better as you go on, with #3 being at least reasonable. The problem you're likely to get is stalling of rendering during copies/changes. For low-poly you probably won't get large VB's but in theory you have to be careful because by double-buffering or ping-ponging can halve your available memory...

Quote:
Original post by Vertex333
4. Create a larger VB and leave the old area in the VB and write into the new area in the VB for the changed object. (NOOVERWRITE flag) If no more data available recreate.
I would imagine this is by far the best option if you must still use a single VB. This sort of approach is often used by databases - they'll pad out even individual elements (e.g. 10x 1mb objects will be allocated 20mb with a 1mb unused gap between each object) so that they can grow bigger before having to be moved to the end of the VB or before they cause a full-blown rebuild of the VB. Should you get short on VRAM you can implement a 'compact' operation that strips out unused space.

Quote:
Original post by Vertex333
5. Using Index Buffer and doing something with that.
I don't see how this would offer anything useful here.

Quote:
Original post by Vertex333
6. I don't know?
I would consider an extension on #4 myself and look into two related areas:

1. Multiple vertex buffers. I assume you've condensed the VB's so you can improve state management and/or reduce draw calls, but consider that there is still a sweet spot between reducing draw calls (READ ops) and reducing updates (WRITE ops). For 100 objects, have 4 buffers (for example) may still be a big win and you can distribute updates so that you can be rendering from 3 whilst waiting on 1 for writing...

2. Pooled-by-update vertex buffers. An enhancement on the above but to split the one large buffer based on frequency of updates. This is borrowed from the D3D10 constant buffer approach - group regularly changing constants together so that if 9/10 of your constants is, well, constant the 1 that isn't doesn't require the entire buffer of 10 to be locked/update/uploaded etc.. split them out so that regularly updated models are grouped together and likewise for mostly static ones. You could also split it based on frequency of updates and resizing - those that regularly change size fit into a padded buffer whereas those that don't can sit in a compacted buffer.


hth
Jack

Thx for you detailed post!

I don't know if splitting into multiple VB is that easy in my application. I will first implement #2 and then change it afterwards. #2 gives me the advantage if I have to recreate (e.g. lostdevice) the whole VB (dynamic VB, XP,...) it could also be done faster.

Vertex

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this