Jump to content
  • Advertisement
Sign in to follow this  
jbb

D3D9 and multi threading

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

Using D3D9 I'm doing all my rendering on one thread but have a second which is used sometimes to create textures and alter vertex buffers. I'm getting the following message from the debug runtime repeated over and over. Direct3D9: (WARN) :Device that was created without D3DCREATE_MULTITHREADED is being used by a thread other than the creation thread. Yes I *am* doing this. But that's following the advice I've read elsewhere that basically says that it's an unnecessary overhead. To be clear I *AM* doing locking myself to ensure that the device is not used at the same time on both threads. Is there any way to suppress the warning message though? It's cluttering up my debug log to the point where any real warnings will be missed? Or would I be better abandoning attempts to use d3d9 in multiple threads and perhaps queue up requests to a single thread instead which could work, but I need to make a decision now before I write too much code :)

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by jbb
Using D3D9 I'm doing all my rendering on one thread but have a second which is used sometimes to create textures and alter vertex buffers. I'm getting the following message from the debug runtime repeated over and over.

Direct3D9: (WARN) :Device that was created without D3DCREATE_MULTITHREADED is being used by a thread other than the creation thread.

Yes I *am* doing this. But that's following the advice I've read elsewhere that basically says that it's an unnecessary overhead. To be clear I *AM* doing locking myself to ensure that the device is not used at the same time on both threads.

Is there any way to suppress the warning message though? It's cluttering up my debug log to the point where any real warnings will be missed?

Or would I be better abandoning attempts to use d3d9 in multiple threads and perhaps queue up requests to a single thread instead which could work, but I need to make a decision now before I write too much code :)
I'd definitely move to a single threaded approach. There's no way to suppress that warning other than decreasing the debug output level, which will mean you'll miss other warnings.

Share this post


Link to post
Share on other sites
I'm with Steve. If you want to do things like texture loads on another thread, you can do that by having your D3D9 thread create and lock the resources + having the other thread load/decompress the texture data into the right places.

Share this post


Link to post
Share on other sites
Thanks for the replies, the answers here and some more reading have convinced me that strictly doing all the 3d device access on one thread is by far the best idea.

My original design was to have one thread traversing my scene graph working out what to draw and pushing drawing comment objects onto a queue where each object had (vertex buffer, index buffer, render states). And then having a second thread popping commands off that queue and drawing them using d3d9. (Or D3D10/11 or opengl, my main doesn't need to know or care with this design)

My theory was that sending commands to the GPU via DX9 uses non-trivial cpu time so there was no need for my scene graph traversal to actually wait for that, and my scene graph traversal can use significant CPU time too and I didn't want my GPU to be sitting idle waiting for it to work out what to draw next - and as most people have 2 or more CPUs these days, separating the two into separate threads with a queue to communicate between them was a reasonable architecture to make some use of the dual core.

My question I guess then, is is this reasonable? Does it take significant time to call D3D9 functions?

The problem with this architecture is that things like particle systems require me to alter the vertex buffers each frame. Because this requires locks on the vertex buffer I need to do this in the rendering thread - but really it conceptually doesn't belong there, it belongs in the scene graph thread. I can neatly separate the two by having my renderer thread make a callback to the objects in the scene graph "object->preRender()" that is called in the context of the rendering thread, but then I've started sharing the work between the two threads slightly differently than my plan.

Ah well, I think I just have to build it now and measure how well it works :)
Thanks for the replies :)

Share this post


Link to post
Share on other sites
Quote:
Original post by jbb
Does it take significant time to call D3D9 functions?


Well it depends on what you're doing, but in general I would say the answer is "yes". If you make a lot of API calls (especially DrawPrim calls) you'll end up spending a non-trivial amount of CPU time switching between user-mode and kernel-mode so that the driver can submit commands to the GPU. This is why a lot of big engines have put a lot of effort into culling redundant state calls, and batching geometry into a single draw call.

But as with anything performance-related you'll always want to profile before making too many assumptions. Apps like PerfHUD can tell you exactly how much time is being spent in the driver.

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!