!@#$ Threads not restoring surfaces right

Started by
8 comments, last by JJXtra 22 years, 2 months ago
Hello all, Im able to recover just fine from ALT-TABS when I''m not using a different thread for my game process, but when I change my main game function to a thread, the display does not restore. Does anyone have experience with threads and what has to be done differently to restore surfaces? Thanks. - Jeff Johnson "He who questions training, only trains himself at asking questions" - Sphynx
- Jeff Johnson"He who questions training, only trains himself at asking questions" - Sphynx
Advertisement
DirectX objects can be accessed only from your main thread (the thread that owns your main window and created the objects in the first place).


--
Eric
-- Eric
Well, you at least need to take a critical section in the pump thread and in the render thread (one per render), then take the critical section before you twiddle any D3D objects that are accessed by the render thread.

You also need to call CoinitializeEx and tell it COINIT_MULTITHREADED in _both_ threads. You need to #define _WIN32_WINNT 0x0500 prior to including windows.h to use CoInitializeEx. You may also need to tell Direct3D you''re using it in a multithreaded app, depending on the version you''re using (IIRC 8 has a flag you set, not sure about other versions).

i.e. You can''t just have the render thread spin attempting to render, then twiddle the device/surface from the pump thread and expect it to work. You need to move the render thread into a non-rendering state first, or block it with a syncronization object (the former would need to use a 32bit volatile int, and technically would still be a syncronization object, the technique if called atomic syncronization).

If this is a window''ed application, you should take the same critical section if you resize or move the form.
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
quote:Original post by ekenslow
DirectX objects can be accessed only from your main thread (the thread that owns your main window and created the objects in the first place).

This is not strictly true. DirectX objects ought to be created and destroyed on the same thread, but you can twiddle surfaces, device, and other such things from mutliple threads. It's important that you call CoinitializeEx with the multithreaded flag on each thread that accesses any COM objects, inlcuding the DirectX ones. That function may not be available on Win95 or NT4, but it can be done on 98/2k+.

Installing the debug build of the DirectX SDK can help track down your problems. There's a couple of logging levels, that progressively dump more stuff to the output window of the debugger.



Edited by - Magmai Kai Holmlor on February 16, 2002 12:23:40 AM
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
From the (8.0a) docs:

Direct3D is designed so that the methods Reset, CreateDevice, TestCoorperativeLevel, or the final Release of IDirect3DDevice8 can only be called from the same thread that handles window messages.

... apparently other functions are indeed OK in alternate threads. Just make sure the calls listed above are called from the thread containing your window procedure.

--
Eric

[edit] RTFM'd


Edited by - ekenslow on February 17, 2002 3:30:32 PM
-- Eric
If I got rid of D3D and just stuck with directdraw would that make it any easier?
- Jeff Johnson"He who questions training, only trains himself at asking questions" - Sphynx
No.

I think the answer is right here. The methods that ekenslow quoted should only be used from your main thread. Anything else is fair game. As with any multithreaded app, make sure you synchronize your resources between your threads. A critical section should be just fine, provided you don''t forget that they need initialization and deinitialization, and that you must use literally the same object for all threads wanting access to the same resource you''re guarding with the critical section.
Hi, I wanted to make my game a multithreaded app for a while but I don''t know how, did you make a class to handle the threads or you''re just using it with the win32 api functions? how could I manage the threads whitin my app?
thnx.
Magmai, could you explain what exactly the CoinitializeEx calls are for? I''ve recently made my program is multithreaded. The Direct3D docs say you need to pass the multithreading flag when creating the device I think it is, but don''t mention the calls to CoinitializeEx. Are they really necessary?

Also, my app seemed to take a pretty big performance hit (on a single processor machine) when I changed to multithreading. I think it dropped from about 190 fps to 140 or something like that. Is this to be expected? Maybe my threads are badly organized. I currently use 3; the main thread for the message pump, which also sets up the Direct3D device. Then an input thread which loops, polling DInput and storing input data, then sleeps for a short time, and finally an Update/Render thread. This one does all the work for the game. It reads the data stored by the input thread to update the player, updates other game objects, then does all the rendering too. Does this seem like an OK way to do it?

Sorry for all the questions, but you seem to know what you''re talking about so I thought I''d ask.

cheers
Cameron
Lesta3D-

I am using Borland CBuilder5 for my game, so I can use forms and also I just like it better, although I use VC++ too. I have a class that I made that is a thread, and it handles all game processes in a loop. If Im right, then all threads have a MAIN or EXECUTE function that is always going. Here is my Execute function:

void __fastcall Execute( )
{
...while(1)
...{
......switch(GAME_STATE)
......{
.........case INTRO: doIntro( ); break;
.........case PLAYING: gameMain( ); break;
.........etc. etc.
......}
...}
}

does that make any sense? If you need help getting a thread class set up let me know. I still haven''t got the bloody ALT-TAB to work, so I made my main part of my normal thread, now everything works. Thanks for the help everyone, maybe when I am done with the game, Ill try and make it a thread again.

- Jeff Johnson

"He who questions training, only trains himself at asking questions" - Sphynx
- Jeff Johnson"He who questions training, only trains himself at asking questions" - Sphynx

This topic is closed to new replies.

Advertisement