Sign in to follow this  
idreamlovey

multithreading loading problem

Recommended Posts

In my game i am using main thread to render loading progress and in the second thread i am loading mesh and texture data. Here is the code about how i have created the second thread.

// Run the secound Thread
					 m_ThrdHandle = CreateThread(NULL,		// no security attributes 
									 0,                 // use default stack size 
									 (LPTHREAD_START_ROUTINE) LoadGameObjects, 
									 this,				// param to thread func 
									 CREATE_SUSPENDED,  // creation flag 
								 NULL);       // 
					 ResumeThread(m_ThrdHandle);

and the loading function is here

UINT	LoadMenuObjects(LPVOID lpvoid)
{
	CMainApp *pMainApp = (CMainApp *)lpvoid;
	pMainApp ->ConstructTextureObjects();
	pMainApp ->ConstructMaterialObjects();
	pMainApp ->ConstructMeshObjects();
	pMainApp ->m_dwAppState = APPSTATE_GAME_ACTIVE;

	 return 0;
}
Now the problem i am facing right now is that sometimes loading some of the textures get skipped. There is one thing that i have noticed that whenever it happens i see a little flicker in loading progress bar that is running in my app's main thread. Anyone know what is that causing this? Its simple implementation as you can clearly see.

Share this post


Link to post
Share on other sites
Well, how do you communicate and synchronize with the main thread?
That is what insures that the game doesn't try to use resources before they are fully loaded, similarly have you made sure that the loading thread doesn't touch any memory which is being actively written by the main thread or vice versa?

Share this post


Link to post
Share on other sites
Hi,

There are a few things left unspecified as implicit told you.

Thread communication is important: the rendering thread must lock the resource when drawing the scene, the loading process must lock the resource when registering in your resource manager. In my own multithread programs I use a manager with a mutex: the mutex is locked by whichever thread needs the resource.
This manager also provides a default resource to avoid crashing when trying to render a resource not yet loaded (important if you have one thread that loads a model and another that loads textures and you try to render your model before all textures are loaded for example).
You also need a signaling system to tell your main thread your loading thread finished: it can be either by waiting for your loading thread to finish or by using a messenging system controlled by a thread synchronization object.

The underlying graphics library is also important: if your are using OpenGL, texture creation and rendering is in one thread only. This means you can't use an OpenGL render context in one thread and create/register textures in another loading thread: textures will be blank. My texture manager permits deferred loading in the main OpenGL thread: my 3D model manager registers in the loading thread the model and signals to the texture manager all the textures that need to be loaded and registered in the main thread.

Hope that helps.

Ghostly yours,
Red.

Share this post


Link to post
Share on other sites

I am using OpenGL with multithreading, and I do something like what Red mentions. Non-rendering threads can request that the main rendering threads call OpenGL APIs on their behalf.

OpenGL has a mechanism to share contexts between threads, but it's fairly complicated. Red's approach is simpler and probably as fast for most cases.

Share this post


Link to post
Share on other sites
Quote:
loading thread doesn't touch any memory which is being actively written by the main thread or vice versa


i am not rendering anything before the mesh fully loaded with textures. Actually i am rendering progressbar animation while the resource loading is in progress. And when everything gets loaded my app switches to the mode to render all mesh objects with the textures.

It happens sometimes that some of the texture get skipped loading fully.

Quote:

OpenGL has a mechanism to share contexts between threads, but it's fairly complicated. Red's approach is simpler and probably as fast for most cases.


i am using directx

In my Main thread, i am rendering progress bar that has been already created in the main thread. Ok and in the second thread that has been created as given in above example code and here i am loading all meshes with textures.
And in the above code u can clearly see that at the last point my app is being set to render all loaded objects. Before that there is no question of rendering them. Now it is so simple implementation and i am so confused that what could be possibly creating the problem. Note that i am not doing streaming of resources to be loaded dynamically while game on run. i am loading everything before they are set to render.

Share this post


Link to post
Share on other sites
Unless you're using Direct3D 11, you can only use your render device from the thread it was created on. It sounds like you're trying to upload textures from a different thread. You can load in the actual data into memory on whatever thread you want, but sending it to the graphics card using Direct3D must be done on the same thread as what your device was created on.

A simple way to do this would be, after loading the texture data from your resource thread, to push it onto a queue which the render thread checks periodically, and uploading whatever is in there to the graphics card. Obviously you will need to make sure that there are appropriate locks (if needed) on this queue to avoid memory issues but that should be pretty straightforward.

Share this post


Link to post
Share on other sites
Quote:
Original post by idreamlovey
Damn the problem solved and the solution is that i havnt created my direc3d device with flag multithreaded on ...It really made me cry on myself..


Be careful with this, it will make the device enter a critical section every single time you make a D3D call. This can add a lot of overhead.

Share this post


Link to post
Share on other sites

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