persistent D3DERR_DEVICELOST problem [SOLVED]

Started by
4 comments, last by greenpig83 11 years, 1 month ago
*edit*: see 4th reply for update on cause of problem... may be useful to know for others Okay, I'm at a loss... no pun intended ;) In switching from windowed to full screen mode, I get a 'lost device' scenario, which I'm handling in the manner specified by MS... which is to say I call IDirect3DDevice9::TestCooperativeLevel() and check for D3DERR_DEVICELOST or D3DERR_DEVICENOTRESET return values. When I receive the former I put the application to sleep for a short period and then call TestCooperativeLevel again. As I understand it, there are only two things you can do when you get a D3DERR_DEVICELOST error, call TestCooperativeLevel or attempt to reset the device. I'm unable to reset the device (this fails with an unhandled exception in d3d9.dll, which after running WinDbg I can confirm is caused by an attempt to reset a lost device). If, on the other hand, I put the application to sleep for a short period and call TestCooperativeLevel again, I get another D3DERR_DEVICELOST error. If I don't intercede, this will repeat indefinitely (i.e., the device never transitions to D3DERR_DEVICENOTRESET state ready for a reset). Can anyone shed any light on what might be causing this failure of my device to transition from 'lost' to 'not reset'. Is there a way to force this transition? I should add that I used "Chad's Tutorial" (here) as the basis for my test project... and it turns out that his code has this same problem. Cheers, Timkin [ FOLLOWUP ] More information... When I call my ToggleFullScreen method from a windowed state, this is what I get... Direct3D9: :Subclassing window 001e0754 Direct3D9: :StartExclusiveMode Direct3D9: (INFO) :Failed to create driver indexbuffer Direct3D9: :Window 00010114 is on top of us!! Direct3D9: :WM_ACTIVATEAPP: BEGIN Deactivating app pid=000011a4, tid=00001148 Direct3D9: :DoneExclusiveMode Direct3D9: :INACTIVE: 000011a4: Restoring original mode (1280x800x22x60) at adapter index 0 Direct3D9: :*** Active state changing Direct3D9: :WM_ACTIVATEAPP: DONE Deactivating app pid=000011a4, tid=00001148 Direct3D9: (WARN) :Window does not have focus. TestCooperativeLevel fails Direct3D9: :WM_ACTIVATEAPP: setting wParam to 0, not realy active Direct3D9: :WM_ACTIVATEAPP: BEGIN Deactivating app pid=000011a4, tid=00001148 Direct3D9: :*** Already deactivated Direct3D9: :WM_ACTIVATEAPP: DONE Deactivating app pid=000011a4, tid=00001148 Direct3D9: (WARN) :Window does not have focus. TestCooperativeLevel fails and then a continuous repeat of this last line as I alternate sleep and TestCooperativeLevel calls. Here's the calling method...

void AppFramework::ToggleFullScreen()
{
	if (m_pGraphics == NULL || !m_bActive)
		return;

	m_pGraphics->ToggleWindowMode();

	if (m_pGraphics->isWindowed())
		SetWindowLongPtr(m_hWnd, GWL_STYLE, WS_OVERLAPPEDWINDOW);
	else
        {
		ZeroMemory(&m_sWP,sizeof(WINDOWPLACEMENT));
		m_sWP.length = sizeof(WINDOWPLACEMENT);
		GetWindowPlacement(m_hWnd,&m_sWP);

		SetWindowLongPtr(m_hWnd,GWL_STYLE,WS_EX_TOPMOST);
		ShowWindow(m_hWnd, SW_HIDE);
	}

	if (!m_pGraphics->CheckDevice())
        {
		OnLostDevice();
		if (SUCCEEDED(m_pGraphics->Reset()))
			OnResetDevice();
	}

	if (m_pGraphics->isWindowed())
		SetWindowPlacement(m_hWnd, &m_sWP);

	if (!IsWindowVisible(m_hWnd))
		ShowWindow(m_hWnd, SW_SHOW);

}
HRESULT D3DGraphics::Reset()
{
	if (m_pD3DDevice )
        {
		if ( BuildPresentParameters() )
			return m_pD3DDevice->Reset( &m_sD3Dparams );
	}
	return E_FAIL;
}


As I indicated this code is based on "Chad's Tutorial"... so don't blame me if you think it's bad! ;) Im a little concerned about the pointer conversions as they throw warnings about size mismatch... but as far as I can tell the WINDOWPLACEMENT structure is in tact before the call to m_pGraphics->Reset(). The 'Window does not have focus' seems at odds with a call to SetWindowLongPtr(m_hWnd,GWL_style,WS_EX_TOPMOST). Thoughts? [Edited by - Timkin on June 14, 2007 11:34:56 PM]
Advertisement
Sounds a bit odd to me and I can't see anything obviously wrong with the code nor your logic.

It's been a long time since it happened to me, but I have had some drivers misbehave in these scenarios. The exact details are a bit of a mystery, but upgrading those drivers solved the problem (or it could be identified as a bad driver due to the same app working on lots of different GPU's/drivers). Have you explored this possibility?

The only other thing to suggest is looking into DXUT as it's the standard and official way of getting D3D to correctly and safely interact with the OS. Ideally we should all do it the way it does it [smile]

The code can be difficult to navigate, so try using the D3DPERF_BeginEvent() and D3DPERF_EndEvent() in conjunction with PIX to try and isolate the D3D calls that occur when you click the toggle button.

hth
Jack

<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

This is what I get when I try and teach myself something new... you find out there's an easier way of doing things after spending a week learning one way... as it stands I still cant work out why it's doing what it is... I've tried updating the driver (although the only one I can get is a year old... bloody Dell... ). I'm going to try switching over to my desktop (rather than my dev laptop) to see if it works therein. Other than that I'll redo things with DXUT.

On that issue though, I cannot find any useful tutorials online for DXUT and DX9. Can someone point me in the right direction please?

Thanks,

Timkin
Quote:Original post by Timkin
On that issue though, I cannot find any useful tutorials online for DXUT and DX9. Can someone point me in the right direction please?
There isn't much documentation outside of the SDK. The parts in DXUT\Core\ are officially supported and documented and quite heavily used throughout the SDK samples. For the most part all you need to do is write the WinMain and set up your callbacks and it does everything else for you. DXUT\Optional\ is a free-for-all and isn't properly documented or supported - use and abuse as you see fit, but for the most part you're on your own...

Pull up the sample browser and then do an "Install Project" on the 'EmptyProject9' or 'SimpleSample' (or similar names - I forget exactly). Those will get you up and running very quickly [smile]

hth
Jack

<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

Thanks for the info on DXUT jj... I've started playing around with it and may end up switching to it for this project...

However, I'm a stubborn/persistent bugger when it comes to problems and I hate to admit defeat, so I kept up my investigations of this one... and finally found the problem. The tutorial code I used as a basis (linked in first post) has the same bug, so beware to any that use it.

The problem arises from the WM_SIZE message handler, which failed to check whether the WM_SIZE message was being kicked off from a switch to fullscreen mode - by a call to "SetWindowLongPtr(m_hWnd,GWL_style,WS_EX_TOPMOST)" - (in which case the message should be ignored) and I believe this was taking focus away from the newly created fullscreen, so that a subsequent call to Reset() within the remainder fullscreen toggle method was failing and throwing a device lost exception that wasn't being handled. There are two obvious solutions to this: (1) add a simple check in the WM_SIZE handler to check for windowed mode before continuing; or, (2) catch exceptions in the toggle method and deal with them. While I agree with adding exception handling in principle, one should not knowingly allow them to be generated during 'normal' operations. Hence, I went with the simple check in my WM_SIZE handler.

I also have problem like this. But it happen when I'm in fullscreen. Then alt-tab!

TestCooperativeLevel keep giving lostdevice, not (notreset). and Warning lost window focus !

Finally the main reason is that I create D3Ddevice in main, not in Winproc. Init it in main Proc solved the problems!

Waste 1 day searching and tweaking, almost give up to change to dxut :(

Hope no more ppl like me !

This topic is closed to new replies.

Advertisement