Disposing of vertex and index buffers causing context switching exceptions with WindowsGL

I have been using DirectX for my project because of context switching exceptions thrown randomly when using OpenGL however i now am trying to fix these problems because i would rather use OpenGL to allow my game to also run on linux.

So basically all was working until i switch to OpenGL and then the terrain paging system will randomly cause the following exceptions to be thrown. The point in my game loop where the crash happens is never the same, some times its during the update method, and other times its during drawing. VS shows the last active thread was GC finalizer and as the stack trace shows either vertex or index buffer dispose methods, it seems that it is not disposing of buffers in a thread safe manor. I have double checked that my code is calling the vertex buffers dispose method on the same thread as the main game loop.

Failed to make context 131072 current. Error: 2004 at OpenTK.Platform.Windows.WinGLContext.MakeCurrent(IWindowInfo window) at OpenTK.Graphics.GraphicsContext.MakeCurrent(IWindowInfo window) at Microsoft.Xna.Framework.Threading.BlockOnUIThread(Action action) at Microsoft.Xna.Framework.Graphics.VertexBuffer.Dispose(Boolean disposing) at Microsoft.Xna.Framework.Graphics.GraphicsResource.Finalize()

and

Failed to make context 131072 current. Error: 0 at OpenTK.Platform.Windows.WinGLContext.MakeCurrent(IWindowInfo window) at OpenTK.Graphics.GraphicsContext.MakeCurrent(IWindowInfo window) at Microsoft.Xna.Framework.Threading.BlockOnUIThread(Action action) at Microsoft.Xna.Framework.Graphics.IndexBuffer.Dispose(Boolean disposing) at Microsoft.Xna.Framework.Graphics.GraphicsResource.Finalize()

The crash occurs in Microsoft.Xna.Framework.Threading.cs on line 198

I hope some one can either confirm this as a bug or suggest other things i should check my code for.

Thanks

Always explicitly dispose of GPU resources when you are finished with them. OpenGL is very bad at handling multiple threads, and the garbage collection always runs in a separate thread. You are seeing the finalizer in the callstack because the object is being garbage collected and did not have Dispose() called on it by your code.

That is not the case as the class containing the buffers is IDisposable and does call dispose on those buffers when it is destroyed by the paging system.

Interesting.

Well disposing a graphics resource should disable finalization on it:

So very curious that it is still running even if it was disposed already.

I would double check the cleanup in your terrain paging system to be certain nothing is getting leaked.

Hi, thanks for your input on this. We went back over the code and my partner has found the cause of the crash. When finished with a terrain chunk we called dispose correctly but had overlooked how the terrain seam stitching code was updating the buffers. It replaced them with a new reference and didn’t call dispose on the existing buffer before assigning a new one. This has been updated and there have been no further crashes.

Good to hear you found the issue.