Jump to content
  • Advertisement
Sign in to follow this  
psykr

OpenGL Correct Vertex Buffer Usage

This topic is 3916 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

My questions are targeted at Direct3D 9, although notes an any differences with D3D 10/OpenGL VBOs are appreciated. I am trying to implement a vertex buffer memory allocation scheme based around Heap Layers, if that changes things somehow. Also, I haven't thought about instancing/index buffers so insights on integrating those features would be helpful as well. I'm planning to make I/O asynchronous and multithreaded and all that, so this is how I think vertex buffers will be used: 1) Lock a vertex buffer 2) Pass the mapped memory region to whoever needs it 3) After some amount of time, the memory is written to 4) The vertex buffer is unlocked (probably after the render thread dequeues the request) Now, the questions (correctness and performance info is appreciated): 1) Can I lock multiple vertex buffers at once? (Both static and dynamic VBs) 2) It's possible to lock only part of the VB. Can I lock the same VB multiple times? What if I limit the locks to non-overlapping regions?

Share this post


Link to post
Share on other sites
Advertisement
1) Sure. Lock as many as you'd like.

2) You can sort of lock part of the VB. If you specify an offset and length to lock, the pointer you receive back will point to that offset instead of the start of the buffer. But...
2a) If the buffer is a static buffer, it doesn't matter where you lock, the whole buffer is considered locked. This may stall the CPU to wait for the GPU even though the GPU and CPU are looking at different parts of the buffer.
2b) If the buffer is dynamic, locking with NOOVERWRITE will lock without stalling, regardless of the offset passed in. It's up to you to correctly offset your write to not interfere with the GPU, either by passing in an offset, or by writing to an address higher than the one returned. Locking with DISCARD will usually lock without stalling, and shouldn't be offset.
2c) Because of reasons I cannot share publically, I'd not recommend locking a subset, and just locking the entire buffer.
2d) I don't think you can lock the same buffer multiple times, as Unlock doesn't take a lock in as an argument... perhaps it does keep a lock count though.

Note your architecture doesn't handle dynamic VBs at all. Passing messages to the renderer with pointers to the data to render can fix that, as long as you can keep everything atomic (so a third thread doesn't interfere). Either by having a single message perform lock, write, unlock, setup, draw, or by having a way to pass multiple messages at once that will be executed in order, and added to your queue atomically.

Share this post


Link to post
Share on other sites
All the data caching is done at once, and then the shader setup/draw calls are done sequentially so I'm not too worried about race conditions.

If it doesn't impact performance to have lots of vertex buffers locked, I'll try to keep multiple buffers locked for as long as I can during the caching step. (Aside from not being able to render, will it have any other impact on performance?)

Rather than having the standard pointers to data for memcpy(), I have callbacks that will fill a given memory region with vertex data in a specified format.

I'm not sure about handling dynamic data, since the draw calls need to occur before they can be locked with DISCARD (if I'm using the buffers multiple times per frame).

Share this post


Link to post
Share on other sites
Quote:
Original post by Namethatnobodyelsetook
2c) Because of reasons I cannot share publically, I'd not recommend locking a subset, and just locking the entire buffer.

Though I think you're completely right, it's difficult for me to imagine any reason that lets you think that AND isn't suitable for being shared publicly.

I have attended a conference in Montreal where a guy DirectX/Microsoft guy explained that whether you locked partially or totally a dynamic vertex buffer wouldn't matter since internally the whole buffer is locked anyway. this is why in Direct3d 10, the new Lock function (renamed to Map()) does not have th offset/size parameters any more.

JA

Share this post


Link to post
Share on other sites
Quote:
Original post by janta
Quote:
Original post by Namethatnobodyelsetook
2c) Because of reasons I cannot share publically, I'd not recommend locking a subset, and just locking the entire buffer.

Though I think you're completely right, it's difficult for me to imagine any reason that lets you think that AND isn't suitable for being shared publicly.
Because it's not up to me to decide what my NDAs cover and don't cover. My particular reason is based upon something NDA. D3D10 compatability may be another good reason. Perhaps OpenGL doesn't support locking a subset, so that's potentially a third reason. I'd guess that my reason won't really affect 99.9% of the users here, but if I can drop a subtle hint to help out the 0.1% of people may help one day, then why not. It's not a big thing to work around anyway. Your engine can take an offset, lock the whole buffer, then offset the pointer D3D gives you before handing back to the app. The rest of your app can think it's still locking at an offset.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!