Rendering in a Separate Thread

Started by
6 comments, last by superpig 18 years, 11 months ago
Hello all, I ran into the problem of my frame rate dropping because I was using D3DPRESENT_INTERVAL_DEFAULT instead of D3DPRESENT_INTERVAL_IMMEDIATE. After getting some help from people here I also read the following in the forum FAQ regarding this issue: "...Though if you've decoupled your renderer from the rest of your game, 60 FPS should be more than enough for it..." So, I now understand that I have to move my renderer into a separate thread. Are there any examples out there that people can suggest I take a look at. I have no problem digging through code, so if there are open source engines that implement this type of multi-threading that would be great. Thanks Todd
Advertisement
When he says to "decouple" the renderer from the rest of the game, he doesn't mean to put the renderer in a separate thread. What it means is that the game logic should not block the renderer from running.

Here's an example of a loop that blocks:
while(!quit) {    update_game();        render();    sleep(interval);}


And one that doesn't
function timer_tick() {    do_update = true;}while(!quit){    if(do_update) {        update_game();        do_update = false;    }    render();}
Ok,

I think I am confused....

On my application it doesn't seem like the game is holding up the renderer but that the renderer is holding up the game.

Specifically, if I use D3DPRESENT_INTERVAL_ONE then the call to present() will wait until the screen is ready for a refresh, pausing the entire application. I was thinking that if the renderer were in a separate thread then the application could be doing something while the renderer is waiting for the screen.

Is my thinking completely messed up?

Thanks for the help.
Todd
Quote:Original post by smr
When he says to "decouple" the renderer from the rest of the game, he doesn't mean to put the renderer in a separate thread. What it means is that the game logic should not block the renderer from running.
True, but a seperate thread is a fairly effective way of achieving that - though granted it's not an easy task to undertake.

There was a really cool talk on how the game Perimeter did it at the 2004 EDF conference, given by a chap from Intel (the focus was hyperthreading, but that doesn't really matter). If you can dig up anything from that you'd probably be off to a good start...

Richard "Superpig" Fine - saving pigs from untimely fates - Microsoft DirectX MVP 2006/2007/2008/2009
"Shaders are not meant to do everything. Of course you can try to use it for everything, but it's like playing football using cabbage." - MickeyMouse

Quote:Original post by superpig
True, but a seperate thread is a fairly effective way of achieving that - though granted it's not an easy task to undertake.


It would certainly be cool, but you have to make sure that the thread is getting enough CPU time to keep an acceptable frame rate and you would also have resource sharing concerns. I think that it makes more sense if you conceptualize the game logic happening in a separate thread, whereas the main process is doing the rendering.

On a uniprocessor system I don't think that it makes much sense to separate the logic from the rendering. However, from the new hyperthreading processors could come substantial benefits from separating the game logic from the renderer.


check out D3DPRESENT_DONOTWAIT

Quote:
If dwFlags = D3DPRESENT_DONOTWAIT, and the hardware is busy processing or waiting for a vertical sync interval, the method will return D3DERR_WASSTILLDRAWING


so if Present()'ing the screen would block the CPU, just do something else in the meantime and check back later.
Chris PergrossiMy Realm | "Good Morning, Dave"
ctoan: That seems like a good, easy solution that gets us most of what we would get via threading.

superpig: Thanks for the reference, I will poke around for that.


It is definately an interesting topic though, given where the hardware seems to be going. I wouldn't be surprised if there is a forum on this site in a the next year or two dedicated to threading games.
Quote:Original post by smr
It would certainly be cool, but you have to make sure that the thread is getting enough CPU time to keep an acceptable frame rate and you would also have resource sharing concerns.
Right, you always want to try and keep seperate threads working with seperate areas of the system. A seperate renderer thread would have exclusive access to the GPU, which would help it, but syncronising data between the game thread and the renderer thread can be troublesome. I implemented this recently in a little demo project; basically I double-buffered all my object position/orientation type values, and let the renderer interpolate between values. That's the approach we were shown in the EDF talk.

Quote:I think that it makes more sense if you conceptualize the game logic happening in a separate thread, whereas the main process is doing the rendering.
It doesn't really make much difference, nowadays. A process is just a thread with an "I was started by the OS" flag set [smile]

Quote:On a uniprocessor system I don't think that it makes much sense to separate the logic from the rendering. However, from the new hyperthreading processors could come substantial benefits from separating the game logic from the renderer.
Well, all new P4s are going to benefit from that, plus the AMD dual cores; if you're working towards the next gen consoles, they would all seem to have multiple processors too. I wouldn't recommend trying to support both single-thread and multi-thread; consider that in single-thread mode you'd be writing your app to do some logic, and then some rendering, and then some logic, and then some rendering... and if you have them in seperate threads, that is what will be happening anyway [smile]

Richard "Superpig" Fine - saving pigs from untimely fates - Microsoft DirectX MVP 2006/2007/2008/2009
"Shaders are not meant to do everything. Of course you can try to use it for everything, but it's like playing football using cabbage." - MickeyMouse

This topic is closed to new replies.

Advertisement