Sign in to follow this  
Moe

Getting bad values returned from TestCooperativeLevel()...

Recommended Posts

Hey all, I seem to be having a bit of a problem. Recently, I decided it would be a good idea to make my program a bit more windows friendly (ie: being able to Alt-Tab in and out of the program). In doing so, I am calling D3DDevice->TestCooperativeLevel() every frame before rendering anything to make sure that things are still good (ie: the program hasn't been minimized just previous to drawing a frame but after I have already peeked at the windows messages). Things go fine when the window is in focus (fullscreen), but the minute that I Alt-Tab out, TestCooperativeLevel gives me some pretty ugly value back instead of something like D3DERR_DEVICELOST (I am getting very large negative numbers, so something is definitely wrong). Any ideas why this is happening? Is it possible that the D3DDevice is lost before I call TestCooperativeLevel?

Share this post


Link to post
Share on other sites
Hi, Moe

Try just performing what you do with a lost device. It could be a undocumented variant of D3DERR_DEVICELOST. I have run into MANY undocumented error values.

Hope this works,
ProgrammingNerd

Share this post


Link to post
Share on other sites
Quote:

Is it possible that the D3DDevice is lost before I call TestCooperativeLevel?


It's not just possible, it's very likely. The program execution could be anywhere when you alt-tab. So you could be about to call present, or you could have just finished a frame and be starting into the next one. You can lose the device at any point in your programs execution, so you'll have to be carefull of that.

-Sandra

Share this post


Link to post
Share on other sites
Quote:
Original post by ProgrammingNerd
Try just performing what you do with a lost device. It could be a undocumented variant of D3DERR_DEVICELOST.

The problem with this, I think, is that the D3DERR values are an enum, which to my understanding is a positive integer.

Sandra-24, how do you recommend handling the situation? Is it necessary to call TestCooperativeLevel() before doing any rendering (ie: call it multiple times per frame)?

Share this post


Link to post
Share on other sites
Hi,

They are, but when you convert unsigned to signed, numbers above 7fffffff, they become negative.

And no, you don't need to call it multiple times per frame. When you call IDirect3DDevice9::BeginScene, if it fails, the device is lost, as well as IDirect3DDevice9::Present, if it fails, the device lost.

This should explain some of your questions,
ProgrammingNerd

Share this post


Link to post
Share on other sites
D3DERR values (and HRESULT values in general) are not enumerators. When an HRESULT indicates failure, a specific bit is set to 1, which happens to be the sign bit. That's why all HRESULT error values are less than 0. (The FAILED macro actually checks whether the given value is less than 0 or not).

Share this post


Link to post
Share on other sites
Ah, wow! I guess that explains a lot. I think I will have to do a bit more playing around tonight to see if I can get it working. The other thing that I think might be the problem is part of my windows message handling. I was talking to cow_in_the_well about this, and this is what I have so far:


//the main message loop
while(notDone)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{

switch (msg.message)
{
case WM_QUIT:
notDone = false;
break;
case WM_ACTIVATE:
if(LOWORD(msg.wParam) == WA_INACTIVE)
{
//window is being deactivated
engine.HaltEngine();
} else {
//window is being activated
if(engine.ResumeEngine() != ENGINE_OK)
{
logfile.PrintLine("WinMain - failed to resume engine.");
//Note - might need to shut down the engine here....
}
}
break;
default:
logfile.outfile<<"Value of msg.message: "<<msg.message<<endl;
logfile.outfile.flush();
}

//translate any accelerator keys
TranslateMessage(&msg);
//send the message to the window proc
DispatchMessage(&msg);

} else {
//main loop of the program goes here
//Be sure to check return type to see if it should exit!
if(engine.MainLoop() == ENGINE_FAIL)
{
MessageBox(hWnd, "Error during engine.DisplayFrame() !", "Error!", MB_OK);
return(0);
}
}

//NOTE or TODO - remove the Sleep or change it to Sleep(0)???
Sleep(1);
} //end while




For some odd reason, when I Alt-Tab out of the program, the engine.HaltEngine() isn't called, as well as when I Alt-Tab back into the program (or maximize it, restore it, etc) the engine.ResumeEngine() isn't called. Am I missing something critical here?

Share this post


Link to post
Share on other sites
Ah, thanks Deathscythe! It seems to have had some effect (I think I still have a few bugs to work out, but I think that may have done it!). Thanks!

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