Sign in to follow this  

multithreaded graphics engine

This topic is 4486 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 was thinking the other day about a multithreaded graphics engine, my idea was to have a separate rendering thread that just do the render-loop and the main thread goes through the scene-graph to find the visible objects.. But as allways there is a problem with this... the main issue is that 2 threads can't access the same thing at the same time and this will probibly happen more then once, the solution is mutex/critical sections (I havn't done much threading so I need some more reading) but then the other thread will stop which will not improve performance, or will it? I was thinking that the scene-graph sorting thread would create a hardware vertex-buffer that is independent of the scene-graph and push that one to the render-thread this way the scene-graph thread can do anything with the object becouse the render-thred is unaware about it, But what about the material/textures? so my main question is it worth the effort to create a multi-threaded engine? I would like to try if it isn't to hard, just becouse I wan't to use my dualcore AMD 4400+ :D

Share this post


Link to post
Share on other sites
Multithreading is not easy - you get hard-to-find bugs (eg you can't
reproduce when a thread will switch, it might run for days and then
suddenly crash because the switch was at an uncomfortable moment).

The trick is to put the mutexes like that that
- they block as short as possible (on the other hand if you have
a loop, then locking every iteration might not be great either)
- It's unlikely the other thread needs the same resource (eg
have as little as possible stall because of this.

For things like streaming in data (loading textures) it's great
however. Also for music & network threads work fine.

I'm not an expert - just my 2 ct :)

/R

Share this post


Link to post
Share on other sites
If you are worried about stalling you can always use non-blocking mutexes. That way one of your threads could go do something else while it waits for a lock to be released. This is probably easier to do for the game thread rather than the renderer thread though. boost has non blocking mutexes in its thread library if you are interrested. I haven't tried it myself though, so I'm not sure it would be a performance boost. It would depend on how long the other thread is locking the resource.

Share this post


Link to post
Share on other sites
Some things:


  • Do all your actual calls to the rendering API from a single thread. They like it that way. The only possible exception is the creation of new resources (textures etc) but I've never tried doing it.
  • Use lock-free data structures and synchronisation objects, as demonstrated by rollo.
  • Double-buffer your data if you need to, and then interpolate in the renderer to do a 'best guess' for the current time.

Share this post


Link to post
Share on other sites
Haven't read the whole of it, but this thread may be of interest.

Alternatively, depending on how important the performance boost is, you may be able to achieve a degree of parallelism simply by carefully batching commands for the GPU (see here).

Share this post


Link to post
Share on other sites
The other threads was really good, altough I don't understand it all yet..

I'm going to have all the rendering in one thread but how to put the stuff over to the other thread?

I need to have some kind of queue that stores everything that is going to be drawn on screen and also different viewports(e.g. different lights shadowmaps, mirrors etc.) with an object queue for each of them.

One problem though, where to store the depthmaps/shadowmaps and render-to-texture targets? if I queue a pointer to a light that will need a depthmap and then the render-thread will render the depthmap and update that lights depthmap, I guess that will not work becouse then the main thread could access the light at the same time doing something with it in the scenegraph, so then how/where to store the depthmap of a light?

I can't really figure out how to keep the threads separated, in the thread by Etnu he said that the Render-threads only reads and the main threads only writes, but I don't understand how it can be so, doesn't the renderthread need to write when it updates a depthmap? or does it only write to some critical when it is first created, like the texture ID that can be re-used?

maybe I should just go the singlethread aproach after all

Share this post


Link to post
Share on other sites
You could try to handle different conceptual portions of your game with various threads. Don't know if that made sense, but I was planning to use sperate threads for things like rendering, AI, sound & music and various capture things.

Basically I think you will want to keep your renderloop singlethreaded and whenever possible read-only, especially in regard to non-visual game data. This way you could have your render thread render a Mesh (or other object) while another thread (AI or physics for example) takes care of how the Mesh behaves. This could for example be used for AI driven enemies or physically correct particle systems, with collisions etc (which is what I was trying to use this for).

The problem is though, that you want objects to be in a predictable state when they're rendered. When you're rendering, you won't want your enemy tank moving only every 10th frame, just because the AI thread doesn't update the tank's position fast enough to keep up with the render thread. Likewise you're inviting the same kind of trouble with the particle system driven from a seperate physics thread.

Maybe it's best to impose some stricter seperation requirements on the concepts. When using an AI thread, it may for example tell game objects where to go etc, but not update their positions, at least not while they are on-screen. This way you could have the render thread interpolate between the current and target position to determine the correct current position in the common pre-render update, which eliminates the 'thread dependancy'. This approach however also eliminates much of the benefits of using multiple threads...

Ideally your render thread should really ony handle the objects within the view frustrum, while the other objects are handled by the other threads. In my tank example, you could have the AI thread interpolate the position of a tank that is off-screen, while any tank that is visible to the camera would be handled by the render thread. This would allow you to control a larger dynamic world from non-graphical threads, while the rendering thread can focus on displaying the small visible portion of the world as efficient as possible.

I still have to read the proposed forum threads on multithreading, so I don't know if this is just duplicate info or if it's actually helpful. Just thought I'd share my ramblings on this subject, though as you can see from my example it's probably heavily dependent on the type of game you're trying to make.

In any case, good luck :)

Share this post


Link to post
Share on other sites

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