Problem - D3DRenderSystem.RestoreLostDevice()


Topic related to current development efforts on the core engine and demos

User avatar

Regular

Posts: 18

Joined: Thu Aug 13, 2009 5:31 am

Location: Istanbul Turkey

Post Fri Jan 15, 2010 4:00 am

Problem - D3DRenderSystem.RestoreLostDevice()

Hello again.

We have been developing an axiom application, and recently I started to get the error below during runtime. I use windows xp, and my friend uses windows 7. However he does not get this message although we develop the project together using svn. Error occurs when i compile and try to run the program from VS2008. lets say every time I compile and run; %50 - %60 percent of my tryouts fail due to this error (I dont alter the code during tryouts of course). Sometimes i also get the same error if I switch to task manager, or resize my application window (c# form). Do you have any clues what's going on ?

Collection was modified; enumeration operation may not execute.
at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
at System.Collections.Generic.List`1.Enumerator.MoveNextRare()
at System.Collections.Generic.List`1.Enumerator.MoveNext()
at Axiom.RenderSystems.DirectX9.D3DHardwareBufferManager.RecreateDefaultPoolResources() in D:\source\Sis3D v2.0\Axiom\Projects\Axiom\Source\RenderSystems\DirectX9\D3DHardwareBufferManager.cs:line 137
at Axiom.RenderSystems.DirectX9.D3DRenderSystem.RestoreLostDevice() in D:\source\Sis3D v2.0\Axiom\Projects\Axiom\Source\RenderSystems\DirectX9\D3DRenderSystem.cs:line 2654
at Axiom.RenderSystems.DirectX9.D3DRenderWindow.Update(Boolean swapBuffers) in D:\source\Sis3D v2.0\Axiom\Projects\Axiom\Source\RenderSystems\DirectX9\D3DRenderWindow.cs:line 1123
at Axiom.Graphics.RenderWindow.Update() in D:\source\Sis3D v2.0\Axiom\Projects\Axiom\Source\Engine\Graphics\RenderWindow.cs:line 269
at Axiom.Graphics.RenderSystem.UpdateAllRenderTargets() in D:\source\Sis3D v2.0\Axiom\Projects\Axiom\Source\Engine\Graphics\RenderSystem.cs:line 739
at Axiom.Core.Root.UpdateAllRenderTargets() in D:\source\Sis3D v2.0\Axiom\Projects\Axiom\Source\Engine\Core\Root.cs:line 1026
at Axiom.Core.Root.RenderOneFrame() in D:\source\Sis3D v2.0\Axiom\Projects\Axiom\Source\Engine\Core\Root.cs:line 904
at Axiom.Core.Root.StartRendering() in D:\source\Sis3D v2.0\Axiom\Projects\Axiom\Source\Engine\Core\Root.cs:line 957
at Sampas.Sis3D.Core.Render.RenderManager.Start(Tessellator t, Loader l) in D:\source\Sis3D v2.0\Sampas\Sis3D\Core\Render\RenderManager.cs:line 484


PS : Note that i also get errors like this during coding, but if I press F5 to run the code they simply disappear :

Error 1 The call is ambiguous between the following methods or properties: 'Microsoft.DirectX.Vector4.Vector4()' and 'Microsoft.DirectX.Vector4.Vector4()' D:\source\Sis3D v2.0\Axiom\Projects\Axiom\Source\RenderSystems\DirectX9\D3DRenderSystem.cs 146 32 Axiom.RenderSystems.DirectX9

Error 2 The call is ambiguous between the following methods or properties: 'Microsoft.DirectX.Direct3D.Viewport.Viewport()' and 'Microsoft.DirectX.Direct3D.Viewport.Viewport()' D:\source\Sis3D v2.0\Axiom\Projects\Axiom\Source\RenderSystems\DirectX9\D3DRenderSystem.cs 831 26 Axiom.RenderSystems.DirectX9

Error 3 The call is ambiguous between the following methods or properties: 'Microsoft.DirectX.Matrix.Matrix()' and 'Microsoft.DirectX.Matrix.Matrix()' D:\source\Sis3D v2.0\Axiom\Projects\Axiom\Source\RenderSystems\DirectX9\D3DRenderSystem.cs 1722 22 Axiom.RenderSystems.DirectX9

Error 4 The call is ambiguous between the following methods or properties: 'Microsoft.DirectX.Direct3D.Material.Material()' and
'Microsoft.DirectX.Direct3D.Material.Material()' D:\source\Sis3D v2.0\Axiom\Projects\Axiom\Source\RenderSystems\DirectX9\D3DRenderSystem.cs 1832 23 Axiom.RenderSystems.DirectX9

Do you think the two problems related ? I have once installed Slim Direct X sdk (to use in OGRE). Is there any possibility that it may cause the problem ?
I have reinstalled dx sdks and my graphics driver. but nothing worked. Problem persists.

Thanks in advance.

Veteran

Posts: 788

Joined: Wed Mar 22, 2006 8:06 pm

Post Tue Jan 19, 2010 3:23 pm

Re: Problem - D3DRenderSystem.RestoreLostDevice()

Njord wrote:Collection was modified; enumeration operation may not execute.
at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
at System.Collections.Generic.List`1.Enumerator.MoveNextRare()
at System.Collections.Generic.List`1.Enumerator.MoveNext()
at Axiom.RenderSystems.DirectX9.D3DHardwareBufferManager.RecreateDefaultPoolResources() in D:\source\Sis3D v2.0\Axiom\Projects\Axiom\Source\RenderSystems\DirectX9\D3DHardwareBufferManager.cs:line 137
at Axiom.RenderSystems.DirectX9.D3DRenderSystem.RestoreLostDevice() in D:\source\Sis3D v2.0\Axiom\Projects\Axiom\Source\RenderSystems\DirectX9\D3DRenderSystem.cs:line 2654
at Axiom.RenderSystems.DirectX9.D3DRenderWindow.Update(Boolean swapBuffers) in D:\source\Sis3D v2.0\Axiom\Projects\Axiom\Source\RenderSystems\DirectX9\D3DRenderWindow.cs:line 1123
at Axiom.Graphics.RenderWindow.Update() in D:\source\Sis3D v2.0\Axiom\Projects\Axiom\Source\Engine\Graphics\RenderWindow.cs:line 269
at Axiom.Graphics.RenderSystem.UpdateAllRenderTargets() in D:\source\Sis3D v2.0\Axiom\Projects\Axiom\Source\Engine\Graphics\RenderSystem.cs:line 739
at Axiom.Core.Root.UpdateAllRenderTargets() in D:\source\Sis3D v2.0\Axiom\Projects\Axiom\Source\Engine\Core\Root.cs:line 1026
at Axiom.Core.Root.RenderOneFrame() in D:\source\Sis3D v2.0\Axiom\Projects\Axiom\Source\Engine\Core\Root.cs:line 904
at Axiom.Core.Root.StartRendering() in D:\source\Sis3D v2.0\Axiom\Projects\Axiom\Source\Engine\Core\Root.cs:line 957
at Sampas.Sis3D.Core.Render.RenderManager.Start(Tessellator t, Loader l) in D:\source\Sis3D v2.0\Sampas\Sis3D\Core\Render\RenderManager.cs:line 484

It's this foreach
  Code:
            foreach ( D3DHardwareVertexBuffer buffer in vertexBuffers )
            {
                if ( buffer.RecreateIfDefaultPool( device ) )
                    vCount++;
            }

but the RecreateIfDefaultPool() doesn't do anything that would break the enumeration. Maybe there's threading involved in your application? What about filesystem watchers that would be dynamically loading a mesh resource, the mesh serializer creates vertex buffers which would modify the HardwareVertexBuffer.vertexBuffers collection
Error 1 The call is ambiguous between the following methods or properties: 'Microsoft.DirectX.Vector4.Vector4()' and 'Microsoft.DirectX.Vector4.Vector4()' D:\source\Sis3D v2.0\Axiom\Projects\Axiom\Source\RenderSystems\DirectX9\D3DRenderSystem.cs 146 32 Axiom.RenderSystems.DirectX9
...

Would try to readd the SlimDX reference for each project in your solution, maybe some version conflict
User avatar

Veteran

Posts: 198

Joined: Mon Jan 19, 2009 10:39 am

Location: Istanbul, TURKIYE

Post Wed Jan 20, 2010 11:02 am

Re: Problem - D3DRenderSystem.RestoreLostDevice()

Hi,

Me and Njord working on the same project.
I solved the responsible code block...

Here:

  Code:
private void createViewport()
        {
            Debug.Assert(window != null, "Attempting to use a null RenderWindow.");
            // create a new viewport and set it's background color
            viewport = window.AddViewport(camera, 0, 0, 1.0f, 1.0f, 100);
            viewport.BackgroundColor = ColorEx.Black;
            window.WindowMovedOrResized();
            Camera.Viewport.UpdateDimensions();
        }


  Code:
public bool onFrameEnded(Object source, FrameEventArgs e)
        {
            if (isResized)
            {
                window.WindowMovedOrResized();
                Camera.Viewport.UpdateDimensions();
                isResized = false;
            }
            return true;
        }


As you see i used this code block on these both:
window.WindowMovedOrResized();
Camera.Viewport.UpdateDimensions();

But it is still unclear why this code make the problem happen?
Comment this code blocks solves the problem but i used them to refresh resolution due to window size

Any ideas?
Too far from imagination, too far from reality...
Image
User avatar

Site Admin

Posts: 1272

Joined: Thu Mar 02, 2006 11:29 pm

Location: Boston, MA, USA

Post Wed Jan 20, 2010 11:53 am

Re: Problem - D3DRenderSystem.RestoreLostDevice()

Can you put together a minimal sample that exhibits the same behavior? I'll take a look.
Borrillis
The Steward of Axiom

Veteran

Posts: 788

Joined: Wed Mar 22, 2006 8:06 pm

Post Wed Jan 20, 2010 3:26 pm

Re: Problem - D3DRenderSystem.RestoreLostDevice()

Sandman wrote:As you see i used this code block on these both:
window.WindowMovedOrResized();
Camera.Viewport.UpdateDimensions();
Strange that you need the WindowMovedOrResized(), you can use the WindowEventMonitor, which calls that upon Move and Size window messages and a window is registered automatically in WindowEventMonitor if you're using the default Axiom window, see D3DRenderwindow.Create(). Also the Camera.Viewport.UpdateDimensions() - that is done in WindowMovedOrResized().

As to why that causes troubles when called explicitly, I don't have an idea

Veteran

Posts: 788

Joined: Wed Mar 22, 2006 8:06 pm

Post Fri Jan 22, 2010 3:42 pm

Re: Problem - D3DRenderSystem.RestoreLostDevice()

andris11 wrote:It's this foreach
  Code:
            foreach ( D3DHardwareVertexBuffer buffer in vertexBuffers )
            {
                if ( buffer.RecreateIfDefaultPool( device ) )
                    vCount++;
            }


Can't think of anything that would break the enumeration unless an asynchronous operation in your application, any idea?
User avatar

Veteran

Posts: 198

Joined: Mon Jan 19, 2009 10:39 am

Location: Istanbul, TURKIYE

Post Wed Feb 10, 2010 10:20 am

Re: Problem - D3DRenderSystem.RestoreLostDevice()

andris11 wrote:
Sandman wrote:As you see i used this code block on these both:
window.WindowMovedOrResized();
Camera.Viewport.UpdateDimensions();
Strange that you need the WindowMovedOrResized()...


We need these because AutoAspectRatio = true does not effect the render output while we render axiom in a resizable picturebox on our own applications Form.

So when i put the above lines on both createViewport and onFrameEnded methods, it start to effect true resizing... But on our tests we declared that these lines works on Windows 7 it is 99% stable (on Windows 7 also give same error but ultra rarely...), but on Windows XP it is approx. 15% stable(Windows XP configurations give us the problem very frequently)

andris11 wrote:...you can use the WindowEventMonitor, which calls that upon Move and Size window messages and a window is registered automatically in WindowEventMonitor if you're using the default Axiom window, see D3DRenderwindow.Create()...

We don't use default Axiom window... On our own Windows.Forms.PictureBox.Resized event we change our custom boolean isResized, so our Render classes call (second responsible code block i mentioned on first post) window.WindowMovedOrResized() method on Frame end, and rechange isResized to false.

Is there any other approch to do that?

andris11 wrote:...Also the Camera.Viewport.UpdateDimensions() - that is done in WindowMovedOrResized().
As to why that causes troubles when called explicitly, I don't have an idea


Yes you are right only window.WindowMovedOrResized(); is enough but problem doest changed.
Too far from imagination, too far from reality...
Image
User avatar

Site Admin

Posts: 1272

Joined: Thu Mar 02, 2006 11:29 pm

Location: Boston, MA, USA

Post Wed Feb 10, 2010 10:36 pm

Re: Problem - D3DRenderSystem.RestoreLostDevice()

Sandman wrote:Yes you are right only window.WindowMovedOrResized(); is enough but problem doest changed.

Use WindowEventManager.RegisterWindow() and pass in your external window's handle to allow the WindowEventHandler to handle the resize events the same way it does for Autocreated windows.
Borrillis
The Steward of Axiom
User avatar

Veteran

Posts: 198

Joined: Mon Jan 19, 2009 10:39 am

Location: Istanbul, TURKIYE

Post Mon Feb 15, 2010 9:48 am

Re: Problem - D3DRenderSystem.RestoreLostDevice()

Really thanks. It solved the problem... I miss understood the solution of andris11 but i read the whole class and understood now.

on my setup method i added this:

  Code:
WindowEventMonitor.Instance.RegisterWindow(window);


and i changed my onFrameEnded method like this :

  Code:
public bool onFrameEnded(Object source, FrameEventArgs e)
        {
            if (isResized)
            {
                WindowEventMonitor.Instance.WindowResized(window);
                isResized = false;
            }
            return true;
        }


and it works on WindowsXP same like windows7 now.

But same problem still continues very rarely...Even it is 99.9% stable, it sometimes give the same error. Why could that happen?
Too far from imagination, too far from reality...
Image

Veteran

Posts: 788

Joined: Wed Mar 22, 2006 8:06 pm

Post Mon Feb 15, 2010 2:37 pm

Re: Problem - D3DRenderSystem.RestoreLostDevice()

Aha! I'm afraid the Win32MessageHandling.WndProc() is not invoked for custom windows, unless you override Control.WndProc() and do the call there, see Axiom.RenderSystems.DirectX9.DefaultForm.WndProc() for an example. Then, from that Win32MessageHandling.WndProc() you get the WindowEventMonitor notification and the appropriate call to the registered window, so don't need to be calling the RenderWindow.WindowMovedOrResized() in frame event.

But, no clues to your "collection modified while enumerating" problem.

Return to Engine Development

Who is online

Users browsing this forum: No registered users and 1 guest

cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.