Window mode error [updated]

Started by
22 comments, last by Halsafar 18 years, 10 months ago
Quote:but I just went through the code I wrote for Dx9 initialization and I am not setting the cooperative level either

Hehe, you sound like me. I knew what I was doing at one point, but it's too many small details to remember.

Well, the D3DFMT_UNKNOWN format is supposed to mimic the use of the GetAdapterDisplayMode() function. So you can assume the same thing is happening in my code.

Has anyone actually tried to do this? Initialize the device in full-screen, switch to window, then back again? I really can't make sense of the problem. I have a pretty robust engine at this point, so it's very difficult to narrow it down. Perhaps I need to do some more testing by doing pointless resets and allowing more things to go on between them each try. If I can find the exact reason that the next Reset() call fails, I would have my answers.

edit: Forgot to answer! Only sound and timers are processed in other threads.
Advertisement
Processing the timer in another thread? Then there is no way to get a grip on 'gametime' how considerably illogical.

Sound are understandable.

Switching from fullscreen to windowed?
Yes, I do that quite frequently, infact I made a multithreaded application to aid in that very purpose. Tthe main thread who inits Dx9 COM like the main thread HAS to. Then the other thread is simply the game loop. This allows for a VERY easy switch/reset method not to mention the gameLoop is free of the MessagePump. If you want more info on it your goona have to ask cause I don't feel like typing it up for nothing.


Edit: Oh, sorry, I don't have any answers for your precise problem... Except I've experienced it before back in the days of Dx7.
Quote:Original post by Halsafar
Processing the timer in another thread? Then there is no way to get a grip on 'gametime' how considerably illogical.

Get a grip? What are you talking about? It's a callback that updates a timer variable. The only code (of mine) that executes in this tread is timer++. It's completely necessary to use the timer routine. What is illogical?

I don't beleive I understand how a second thread would help with reseting the device. Or why the main thread needs to be free of the message pump, It sounds like an unnecessary mess.
Whats the purpose of a seperate thread handling your timer?
Quote:Original post by DrEvil
Whats the purpose of a seperate thread handling your timer?

I don't control the other thread. I just provide a callback function. Ask Microsoft.
Well the only timer to be used in games today should be QueryPerformanceCounter and it should be local to the thread your gameLoop is in.
Updating your timer in another thread if you understand me would mean that your gameLoop keeps going while your timer thread keeps updating...illogical as a thread dedicated to updating a timer would run so very fast as a gameLoop thread would run at its own slow pace.


Multithreading the gameLoop out of the messagePump provides not only a boost in FPS but allows for many of the old school gameLoop techniques to apply. Infact most all games on the PC on the market today run there gameLoop seperate of the MsgPump in a different thread. It took me awhile to grasp the concept and I was a little skeptical at starting the project but when it was done I was shocked at my amazing frame time (ms/frame) and how easy it became to manage ALL the release/restore/reset of my games.

If you are a curious a fellow programmer at VbForums has made a C++ tutorial for Dx9 Multithreaded.
Quote:Original post by Jiia
Quote:Original post by Illco
Did you check for TestCooperativeLevel()'s return value? It will first return DEVICELOST for a while, but only after it starts returning DEVICENOTRESET can you successfully reset the device.

My engine throws up a message box asking the user if they want to try to restore the display again. I can press yes until I'm blue in the face, it just won't succeed [smile]

edit:

I tried calling TestCooperativeLevel() before Reset() fails, and that function succeeds. Reset still fails of course. I'm getting more confused.


This might be me simply misunderstanding you, but I will post nonetheless as it is sometimes the smallest things that we all forget.

TestCooperativeLevel() always succeeds but returns either D3DERR_DEVICELOST or D3DERR_DEVICENOTRESET. While the former is returned, you must do nothing else (such as use or access resources). Only once D3DERR_DEVICENOTRESET is returned, should you proceed to reset the devices/resources and continue program execution.

If you attempt to reset the device while it is still lost, the behavoir you describe will usually occur.

- Oscar [smile]

Quote:Original post by Halsafar
Well the only timer to be used in games today should be QueryPerformanceCounter

Do you have a reason for this?

Quote:Updating your timer in another thread if you understand me would mean that your gameLoop keeps going while your timer thread keeps updating...illogical as a thread dedicated to updating a timer would run so very fast as a gameLoop thread would run at its own slow pace.

The same could be said about your messaging loop..?

Quote:Multithreading the gameLoop out of the messagePump provides not only a boost in FPS but allows for many of the old school gameLoop techniques to apply.

All of the old school game loop techniques apply anyway. It's just a simple matter of asking windows if it needs to tell you something every so often.

Quote:I was shocked at my amazing frame time (ms/frame) and how easy it became to manage ALL the release/restore/reset of my games.

Exactly what kind of increase in performance did you see? It would help me tremendusly if you could explain why your frame rate climbed such a dramatic amount or how resource management was made so much easier.
Quote:Original post by Croc
This might be me simply misunderstanding you, but I will post nonetheless as it is sometimes the smallest things that we all forget.

TestCooperativeLevel() always succeeds but returns either D3DERR_DEVICELOST or D3DERR_DEVICENOTRESET.

That's not true. The only way TestCooperativeLevel can succeed is by returning D3D_OK. Any other return values are considered failures. Which means the FAILED() macro should work fine.

I appreciate your time, though.
TestCooperativeLevel!! ah yes, I use that all the time in my reset routine, I got that confused with SetCooperativeLevel.


Jiia:

QueryPerformanceTimer is much more accurate than getTickcount especially on faster machines. QueryperformanceCounter is accurate down to e^9 i believe where getTickCount is good to e^6. Its the difference between picking up nanoseconds and milliseconds, naturally you want the closest representation of the time past's between frames, so QueryPerformanceCounter API was made as it reads cycles based on the cpu and bus, where as getTickCount is totally WinApi based I beleive.



Multithreading:
Okay seriously, think about it. Have you written a proper msgPump/gameLoop, your gameLogic is also updating the window and recieving and dealing with any incoming window messages, which means your game updates, then the window updates.

In my solution, I have the window simple pause on GetMessage like a regular WinApp does and my gameLoop is just constantly udpating and since a gameLoop is suppose to written to manage itself it all works out. Now not only is your gameLoop going to update faster, the window does not have to wait for the gameLoop if it needs to udpate for some reason.

So it boils down to your choice:
Thread1 = MessagePump+GameLoop
or
Thread1 = MessagePump
Thread2 = gameLoop



As for making resource management easier, well it requires a few small messaging tricks and adding a wait event having your game thread pause when necessary using WaitForMultipleObjects. For example, your game thread returns device lost on the PRESENT, send a message to the window, pause the thread. The msg pump will recieve the message and go "oh, time to reset" and it will enter a TestCooperativeLevel loop waiting for the window to recieve focus, once it does, reset, restore, unpause the thread by setting the event it is waiting on. You'd have to get a working model of the application to see how blissfully easy the Reset/Restore/ of resources becomes.


Performance increase, well the guy who tipped me into the project was Electroman from VbForums as he wrote a rather nice tutorial project to cover this. He claimed he was achieving with a blank gameLoop that simply cleared the device with a new color each frame around 5000fps but that would attribute to the mighty GPU he has I believe. When I ran it with my pathetic onboard card I got around 600fps. I wouldn't doubt that in most case's the performance increase is negligable but it is worth it since in many case's, especially on slower comps, the increase will be noticed, especially if you have a heavy WndProc.



Sorry I took so long to reply, I forgot about this thread.


This topic is closed to new replies.

Advertisement