'Invalid call' error/exception from Reset

Started by
7 comments, last by DrGUI 18 years, 3 months ago
Hi I was testing my game framework for robustness, doing nasty things like ctrl-alt-delete. It's a bit strange that 1st time a reset is required, 2nd time a recreate, 3rd time a reset, 4th time recreate etc. Can someone tell me why this is happening? If a reset fails, I recreate the device; I do ctrl-alt-delete once, GetCooperative level returns 'require reset' and the reset is successful. If I do ctrl-alt-delete again, once more the cooperative level is 'require reset', but this time I get an InvalidCallException/D3DERR_INVALIDCALL. Of course I checked my present parameters, they were the same all the way through the app's lifetime in this case, the ones I created the device with - so they were valid. I suppose I'm not doing too badly though, as most commercial games just disappear silently when you do ctrl-alt-delete. Cheers
Advertisement
Yea, that is definitely not normal behavior. If you app is doing this correctly, you shouldn't have to recreate a device. Have you checked the debug output? That will tell you exactly why you are getting an invalid call upon Reset().

Quote:Original post by DrGUI
I suppose I'm not doing too badly though, as most commercial games just disappear silently when you do ctrl-alt-delete.

hehe Personally, I think games are getting better at alt-tabs and the like...nothing more annoying than tabbing out, then coming back (and enduring a 30s wait), only to be greeted by corrupted textures...

There has been a recent push by Microsoft to raise the quality of the frontend of games - ie installation, loading, tabbing out, ect. I believe there is a page in the DXSDK on it.
Dustin Franklin ( circlesoft :: KBase :: Mystic GD :: ApolloNL )
Quote:Original post by circlesoft
There has been a recent push by Microsoft to raise the quality of the frontend of games - ie installation, loading, tabbing out, ect. I believe there is a page in the DXSDK on it.

Theres a whole page of such things [grin]

The slides from the various meltdown events always seem to cover this sort of stuff as well.

Jack

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

Hi, thanks for your replies!

I've had my January physics module now so I'm gonna relax and program/chat on MSN tonight [grin]

I've got DebugView to see DirectX's messages, but now it's got maximum validation on, I can't get my game to run!
And it's not actually my fault...
//Clear target to pink if DEBUG#if DEBUG//[2124] Direct3D9: (ERROR) :MultiSampleType between DepthStencil Buffer and RenderTarget must match.ResourceManager.Instance.Device.Clear(Direct3D.ClearFlags.Target, System.Drawing.Color.HotPink, 1, 0);#endif

This is in my image processing library, if debug I clear the render target to bright pink so you can easily see if something's not working.
In this situation I have just changed the render target to a texture, but now I get an invalid call exception because the multisample types don't match even though I'm just setting the target. I got past it by setting DepthStencilSurface to null but now I have to make other changes...

Debug runtime with maximum validation slows my game to 2 fps lol, I'm sure being on debug used to make only a negligible difference!
In debug mode, your speed greatly depends on what exactly you're doing, and how many errors/warnings you're getting.

I'd imagine doing complex things makes a bigger difference between debug and retail than the simpler ones.
Sirob Yes.» - status: Work-O-Rama.
It says on the debug output that 3 vertex buffers in the default pool have not been destroyed.
That's rather strange since the first reset succeeds without any such messages, but I'll have to look into that tommorrow.

EDIT: thanks sirob; I put the debug output down from full to 4/5 and now it's almost normal speed :)
I've got rid of those vertex buffer warnings now and the device does not need to be recreated, by changing one to managed and disabling the others (debug things like drawing the outline of a bounding box).

But I was destroying those buffers when the device was lost, I even set breakpoints which were hit both when the device was reset and when it was recreated. Also it's rather strange that DX only has a problem on the second reset.

Here, after getting rid of the warnings, I reenabled just my cuboid outline renderer and added a debug output after the vb is disposed. I got the following output:
[4044] CuboidOutlineRenderer: Vertex buffer disposed. [4044] D3D9Device: Resetting device. [4044] Direct3D9: (ERROR) :The following D3DPOOL_DEFAULT surfaces/buffers/textures still exist  oh no it doesn't


However, I can't just make this vertex buffer managed as it needs to be dynamic. It's fortunate that these are just debugging aids so I can disable them in the release version, but I can't have this happening if I make a particle system, which will obviously need to be dynamic and in the default pool!
I've reproduced the error in the sample tutorial on creating a device, so you can see for yourself now!

The procedure is to run, ctrl-alt-delete, cancel, ctrl-alt-delete, cancel, then you'll get the debugger breaking on Reset with an InvalidCallException. The debug output says that the vertex buffer has not been destroyed.

Thanks

//-----------------------------------------------------------------------------// File: CreateDevice.cs//// Desc: This is the first tutorial for using Direct3D. In this tutorial, all//       we are doing is creating a Direct3D device and using it to clear the//       window.//// Copyright (c) Microsoft Corporation. All rights reserved.//-----------------------------------------------------------------------------using System;using System.Drawing;using System.Windows.Forms;using Microsoft.DirectX;using Microsoft.DirectX.Direct3D;namespace DeviceTutorial{	public class CreateDevice : Form	{		// Our global variables for this project		Device device = null; // Our rendering device		PresentParameters m_PresentParameters;		VertexBuffer m_VB = null;		public CreateDevice()		{			// Set the initial size of our form			this.ClientSize = new System.Drawing.Size(400,300);			// And it's caption			this.Text = "D3D Tutorial 01: CreateDevice";		}				public bool InitializeGraphics()		{			try			{				// Now let's setup our D3D stuff				m_PresentParameters = new PresentParameters();				m_PresentParameters.Windowed = true;				m_PresentParameters.SwapEffect = SwapEffect.Discard;				device = new Device(0, DeviceType.Hardware, this, CreateFlags.HardwareVertexProcessing, m_PresentParameters);				device.DeviceReset += new EventHandler(device_DeviceReset);				device.DeviceLost += new EventHandler(device_DeviceLost);				device_DeviceReset(this, null);				return true;			}			catch (DirectXException)            {                 return false;             }		}		void device_DeviceReset(object sender, EventArgs e)		{			if (m_VB == null)				m_VB = new VertexBuffer(typeof(Vector3), 8, device,										Usage.Dynamic | Usage.WriteOnly,										VertexFormats.Position, Pool.Default);		}		void device_DeviceLost(object sender, EventArgs e)		{			if (m_VB != null)			{				m_VB.Dispose();				m_VB = null;			}		}		private void Render()		{			if (device == null) 				return;			//Clear the backbuffer to a blue color 			device.Clear(ClearFlags.Target, System.Drawing.Color.Blue, 1.0f, 0);			//Begin the scene			device.BeginScene();						// Rendering of scene objects can happen here			//Vector3[] points = new Vector3[8];			////Lock vb			//GraphicsStream data = m_VB.Lock(0, 0, LockFlags.Discard);			//data.Write(points);			////Unlock vb			//m_VB.Unlock();    			//End the scene			device.EndScene();			try			{				device.Present();			}			catch (DeviceLostException)			{				for (int i = 0; i < 100000; i++)				{					int result;					device.CheckCooperativeLevel(out result);					if (result == (int)ResultCode.DeviceNotReset)					{						device.Reset(m_PresentParameters);						break;					}					System.Threading.Thread.Sleep(200);				}			}		}		protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)		{			this.Render(); // Render on painting		}		protected override void OnKeyPress(System.Windows.Forms.KeyPressEventArgs e)		{			if ((int)(byte)e.KeyChar == (int)System.Windows.Forms.Keys.Escape)				this.Close(); // Esc was pressed		}		/// <summary>		/// The main entry point for the application.		/// </summary>		static void Main() 		{            using (CreateDevice frm = new CreateDevice())            {                if (!frm.InitializeGraphics()) // Initialize Direct3D                {                    MessageBox.Show("Could not initialize Direct3D.  This tutorial will exit.");                    return;                }                frm.Show();                // While the form is still valid, render and process messages                while(frm.Created)                {                    frm.Render();                    Application.DoEvents();                }            }		}	}}
Just to add, that code is .NET 2.0, MDX 1.1 December Update (though I'm not actually using D3DX there)

This topic is closed to new replies.

Advertisement