load and render at the same time
My program render .x animation in a thread called render.
at the same time, another thread called loader is loading other .x files in the background.
when the loader thread finished, the render thread crashes.
I went through the debug information, and I think the reason is as follows:
My x file loading engine uses effects to create textures. So if the loader thread creates new effects on the device when the render thread is processing effect passes to draw a subset, the render thread will crash. The reason is that these 2 threads share the same device and all effects are bound to this device.
An obvious solution is to create and use another device for the loader thread. My question is that is there any solution, which can make these two threads both work well with only one shared device.
Did you create your device with D3DCREATE_MULTITHREADED? That could be the cause of the problem if you didn't.
Crashes caused by D3DX functions that are called from another thread are a common problem. Microsoft is working on this but AFAIK there is no real solution available yet.
Calling functions that don’t use the device seems to be safe.
Calling functions that don’t use the device seems to be safe.
Poor Microsoft. In OpenGL, this can be solved simply. But directx makes it really a mess. It seems that I have to go with multiple devices.
Quote:Original post by hegel
Poor Microsoft. In OpenGL, this can be solved simply. But directx makes it really a mess. It seems that I have to go with multiple devices.
These will not necessary help you as you can’t use resources create from one device with another one. The common multi thread praxis for Direct3D is to load and parse/compile on one thread but create on the main thread. And don’t use D3DCREATE_MULTITHREADED. It has a bad Performance behavior.
Direct3D 9 was never really build for multi threading as usual system at this time have one CPU with one Core. Direct3D 10 will behave better as the D3DX functions are already have build in multi threading loading. Maybe we will see this in the D3DX version for D3D9, too.
I had a similar problem in my MFC app. I would be applying some editing modification to the mesh (changing the vertex and index buffers) when windows would send another call to OnPaint(), and it would attempt to render the mesh I was in the middle of modifying. So, I just added a flag that would stop rendering that mesh until I was done with it.
I can't see MS ever fixing all possible multithreading issues. So, as a programmer it is a good idea to understand them. There are various ways to keep threads from banging into each other. For example, you could make sure that the rendering thread does not see the mesh until the loader thread is done with it. Flags can be dangerous, because you have to be sure to handle them correctly in all possible error paths, or you may end up leaving a flag ON that locks out another thread.
And to top it off, multi-threading also creates new problems with multi-processors, since the processors can have their own cache.
I can't see MS ever fixing all possible multithreading issues. So, as a programmer it is a good idea to understand them. There are various ways to keep threads from banging into each other. For example, you could make sure that the rendering thread does not see the mesh until the loader thread is done with it. Flags can be dangerous, because you have to be sure to handle them correctly in all possible error paths, or you may end up leaving a flag ON that locks out another thread.
And to top it off, multi-threading also creates new problems with multi-processors, since the processors can have their own cache.
Quote:Original post by DXnut
I can't see MS ever fixing all possible multithreading issues.
This is being worked on for D3D10. There will be new and improved multithreaded D3DX function calls. For example, you will be able to pass a function like D3DXCreateTextureFromFile() an array of filenames, and it will go out, create a bunch of threads, and automatically load all of the textures in a multithreaded manner. So that is pretty nice.
However, the D3D device itself should still be single-threaded, at least until new features in the hardware come along. All flagging the device creation with D3DCREATE_MULTITHREADED does is force it into a bazillion critical sections, so that is why there are massive performance hits.
As far as loading & rendering goes, you can adopt a few strategies:
(a) Render your stuff in-between loading resources. So it would go like this:
- Render loading screen - Load resource (1) - Render loading screen - Load resource (2) ...
(b) Load the files into memory in a separate thread. Then use the D3DX*InMemory() functions (from within your graphics thread) that will load a resource from a buffer already placed in memory. Tthis easy to multithread and will save a lot of time.
There should be some strategy for a single device to seperate resources created from multiple threads. If the device can't do this smoothly, its multithread creation flag is misleading in a sense.
I uses two devices now to solve this problem, and the loading thread didn't interrupt the rendering thread. I think I'd better go with this solution.
If microsoft wanna occupy 3d engine market, this multithread problem should be solved in the first hand. Expecting directx 10.
I uses two devices now to solve this problem, and the loading thread didn't interrupt the rendering thread. I think I'd better go with this solution.
If microsoft wanna occupy 3d engine market, this multithread problem should be solved in the first hand. Expecting directx 10.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement