Sign in to follow this  

Trouble with hardware vertex processing

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have been doing a little game with dynamic terrain. When I create my directX device using software vertex processing, I can change the positions of the vertex in my vertex buffer and the changes are reflected correctly when I render. But when I set my device to hardware vertex processing, the rendering stays unchanged. The terrain will stay exactly as it was when the vertex buffer was originally created even though I modified it many times. Does anyone thinks of a solution ?

Share this post


Link to post
Share on other sites
Yeah, I lock, modify, unlock.

As I said, It works perfectly in Software Vertex Processing. The terrain is modified perfectly.

It also renders in Hardware letting me believe that everything worked OK. But when I render in Hardware, the terrain is unchanged even though the vertex buffer is modified.

Share this post


Link to post
Share on other sites
It might be an issue with your lock flags (DISCARD, etc). In SW processing mode, since your vbufs/ibufs live in system memory, it probably wouldn't matter if the lock flags were wrong. From the syptoms, it sounds (just a guess) like your doing a NOOVERWRITE lock on the entire buffer?

joe
image space

Share this post


Link to post
Share on other sites
Since I never read from the buffer, the only flag I knowingly set when I create the buffer is "D3DUSAGE_WRITEONLY". Also, I create the vertex buffer in the default d3d pool (so I don't have to care when the device is lost).

Where would you think a "NOOVERWRITE" flag be located (or changed) ?

Share this post


Link to post
Share on other sites
The NOOVERWRITE flags is a parameter to the Lock method, but wouldn't matter since it seems you are creating a static, default pool vbuf. What does your lock call look like?

Note:
You should create your vbuf with D3DUSAGE_DYNAMIC if you're going to be locking more than once per frame. Also, creating in DEFAULT pool will not relieve the responsibility of restoring after device loss. For that, you should use the MANAGED pool.

joe
image space

Share this post


Link to post
Share on other sites
You are right about the "MANAGED" buffer. That's what I meant and should have written.

For the lock, I currently do not have my source code. Could you give me an example of the "correct" way to do the lock knowing what I intend to do with it?

P.S: Give me an example for if I intend to write only once per frame vs if I intend to write multiple times per frame.

Thanks

Share this post


Link to post
Share on other sites
default pool means you DO have to worry about lost devices.
managed pool means you DON'T have to worry about lost devices.
Dynamic VBs cannot be in the managed pool (you haven't said what type of VB you're using (do you specify DYNAMIC as a flag on Create?))

You really should be using a dynamic VB if your mesh is contantly changing, and using correct NOOVERWRITE/DISCARD flags on lock. Dynamic VBs aren't really meant to hold meshes for long periods of time. They hold the data long enough for you to render it. Their typical use is as follows:

nOffset = 0
bFirstInFrame = true
while (stuff to draw)
{
if (nOffset + nMeshSize > VBSize || bFirstInFrame)
{
flags = discard
bFirstInFrame = false
nOffset = 0;
}
else
{
flags = nooverwrite
}
Lock(noffset,size,flags,buffer)
memcpy to buffer (pointer should be offset already because of offset in lock)
Unlock()
nOffset += size;
}




In other words... when the VB is full, or it's the first draw of the frame, throw away the contents of the VB (discard). Otherwise, append data to the remaining space in the VB (nooverwrite).

If your data only changes rarely, this will create an unnessary strain on your graphics card (mesh data needs transferring for each render). However, changing the mesh ever will create a stall when you lock the buffer... one solution is to cycle between 3 or 4 static buffers. This lets the graphics card finish dealing with the old buffer before you attempt to reuse it. You could try using only 2 buffers, but if two changes occur in rapid succession, you'll be forced to stall... which may be acceptable to you.

Another solution would be to use a single static buffer, but when you need to modify the data, use a dynamic buffer for a few frames (allowing the queued draw calls on the static buffer to finish), then copy the new data into the static buffer. This has the advantage of only putting the extra strain on the graphics card for a few frames whenever a change in needed, and should take less GPU memory than cycling between 3-4 buffers.

There is no ideal DX or OpenGL buffer for dealing with occasionally dynamic data such as changes to landscape, leaving you to come up with your own hackish solutions like those above.

Share this post


Link to post
Share on other sites
That makes a lot of sense. I will try that.

Also, thanks for the advices about the multiple buffer-switching. I didn't knew about the stalling. But it is logical knowing that the CPU and GPU are working in parallel. One cannot access the other memory simultaneously without slowing it/himself down.

Share this post


Link to post
Share on other sites
Kinda an edit, but here to be more visible. When I say "However, changing the mesh ever will create a stall when you lock the buffer", I meant

"However, if you use a static buffer, changing the mesh ever will create a stall when you lock the buffer", this puts you in the situation of choosing between a) Dynamic buffer, and sending lots of data to the card each frame and b) Static buffer, and stalling on changes... then I present methods to overcome those limits.

Share this post


Link to post
Share on other sites

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

If you intended to correct an error in the post then please contact us.

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