Resetting my device crashes the program under specific conditions, can't work out why

Started by
1 comment, last by Dache 17 years, 2 months ago
Very odd one this. Whenever the window of my program is fiddled with (i.e. resized, maximised, etc), it goes through a typical message processor to do all of that. The problem I'm having is that when my program is running a certain part of the code, it crashes whenever I do anything to the window that requires the D3D device to be reset (specific crash details down below). The most irritating thing is that I can't work out what part of that section of the program causes this. The program won't crash if I fiddle with the window when it first starts up - at this point, all I'm doing is looping a draw function that draws text on the screen using the regular DirectX DrawText() function of the ID3DXFont type, nothing else. Once some controller setup is done, my program loops a different draw function that I'm working on now, drawing a single sprite onscreen using the Draw() function of the ID3DXSprite type, and that's all it's drawing. That's also the only difference in what code is being run between the point when resizing won't crash it and when it will. The same code to check and change the size of the window runs in either situation. Here's a snippet. It's only part of it (specifically, the part that deals with minimising or maximising the window):

LRESULT D3DApp::msgProc(UINT msg, WPARAM wParam, LPARAM lParam)
{
	// Is the application in a minimized or maximized state?
	static bool minOrMaxed = false;

	RECT clientRect = {0, 0, 0, 0};
	switch( msg )
	{
		// WM_SIZE is sent when the user resizes the window  
		case WM_SIZE:
			if( gd3dDevice )
			{
				md3dPP.BackBufferWidth  = LOWORD(lParam);
				md3dPP.BackBufferHeight = HIWORD(lParam);

				if( wParam == SIZE_MINIMIZED )
				{
					mAppPaused = true;
					minOrMaxed = true;
				}
				else if( wParam == SIZE_MAXIMIZED )
				{
					mAppPaused = false;
					minOrMaxed = true;
					onLostDevice();
					gd3dDevice->Reset(&md3dPP);
					onResetDevice();
					
				}




To be more specific, the exact line it crashes on is (where gd3dDevice is a global pointer to the device itself, and md3dPP is the pointer to the presentation parameters):
gd3dDevice->Reset(&md3dPP);


And it crashes out with:
Quote:File: Line: [whatever] Error Code: D3DERR_INVALIDCALL (0x08876086c) <-- could be important to note this doesn't change Calling: gd3dDevice->Reset(&md3dPP)
If I click No and make the program progess, it continues to stop in the same way at every single line where gd3dDevice is being called, with exactly the same error - and only those lines where gd3dDevice is being called. I don't know why, all of a sudden, trying to reset or indeed do anything else to the device at the point where I'm drawing sprites onscreen makes for an invalid call. This is pretty much my 'learning DirectX' project, and I haven't got a clue why it's doing this, so any help at all would be appreciated. This post is pretty long already, but I can post both the draw functions I mentioned above if anyone wants to see them, or indeed any other part of the code if it'll help. I'm not sure how much detail I need to give here.
Advertisement
Run with the DEBUG Direct3D runtime enabled (see the DirectX control panel), tun your application in the debugger and check out what D3D has to say in the output sent to the debugger.

Two things usually go wrong with calls to Reset():

1) some D3D resource in the DEFAULT pool hasn't been released due to not being released (either at all or due to there still being a reference to the object). Beware that calls like IDirect3DDevice9::GetBackBuffer() are documented to increment reference counts, you need to Release() those additional reference counts.

2) the D3DPRESENT_PARAMETERS structure you've passed is bad in some way. Either what you're asking for (screen mode, etc) isn't valid fot the device/graphics hardware, or the structure is corrupt in some way. Beware that calls like CreateDevice() can alter/trash values in the structure you pass in, so re-using the same block of memory (such as a class member) for CreateDevice() and Reset() can give you problems.


The debug runtime will tell you why D3D returned the error.

Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site

Quote:Original post by S1CA
1) some D3D resource in the DEFAULT pool hasn't been released due to not being released (either at all or due to there still being a reference to the object). Beware that calls like IDirect3DDevice9::GetBackBuffer() are documented to increment reference counts, you need to Release() those additional reference counts.


It was this. (Forgot to set OnLostDevice() on my sprite object!)

Thanks so much for that - I'd seen the debug runtime option in the DX control panel bit before, but didn't know exactly what it was for. Now I know, this'll be really useful later on. Thanks again!

This topic is closed to new replies.

Advertisement