sjoerd222's picture

Using WGL_ARB_create_context... A first chance exception of type 'System.AccessViolationException' occurred in OpenTK.dll

Hello

I'm using Visual Studio 2010, Windows 7-64bit, OpenTK 1.0, Nvidia GeForce GTS 240, Driver 8.17.12.7061.

I wrote a custom GLControl while extending the one provided by OpenTK. The Control works but on some computers for example this one, it fails when using it together with DevExpress.
I'm trying to figure out what happens. In a normal windows form everything works well, but within a DevExpress Form it hangs.

private void MyControl_Load(object sender, EventArgs e)
        {
            if (!DesignMode)
            {
                try
                {
                    MakeCurrent();
                    engine.Init();
                    finishedLoading = true;
                }
                catch(Exception ex)
                {
                    throw new ApplicationException(ex.Message);
                }
            }
        }

In this code part it enters the Method MakeCurrent(). There ValidateState(). The Context variable is sometimes null, sometimes Visual Studio fails retrieving it's value. In ValidateState it calls RecreateHandle(). I cannot step into this method, but catch track again with a breakpoint in WinGLContext.cs Line 93.
Debug.Write("Using WGL_ARB_create_context... ");
Then on Line 113

Handle = new ContextHandle(
                            Wgl.Arb.CreateContextAttribs(
                                window.DeviceContext,
                                sharedContext != null ? (sharedContext as IGraphicsContextInternal).Context.Handle : IntPtr.Zero,
                                attributes.ToArray()));

The cursor continues to Wgl.cs Line 545.

            IntPtr CreateContextAttribs(IntPtr hDC, IntPtr hShareContext, int[] attribList)
            {
                unsafe
                {
                    fixed (int* attribList_ptr = attribList)
                    {
                        return Delegates.wglCreateContextAttribsARB((IntPtr)hDC, (IntPtr)hShareContext, (int*)attribList_ptr);
                    }
                }
            }

The call return Delegates.wglCreateContextAttribsARB((IntPtr)hDC, (IntPtr)hShareContext, (int*)attribList_ptr); then throws the exception I cannot further resolv.

Does somebody have an idea how I could further investigate this case or are there some things I did wrong when calling MakeCurrent() ? I also tried the "Tread Optimization" Option in the Nvidia driver with no success. (Because this was a workaround for a nvidia 260.99 Bug. Just in case it was related)

Kind regards,
Sjoerd222


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
the Fiddler's picture

Are you nesting the GLControl inside another control? The WinForms designer has an issue with that: #2506: GLControl inside a user control crashes during design time

SVN trunk now contains a potential fix.

sjoerd222's picture

if (!DesignMode) prevents this problems. But this would actually only cause problem in Design view, while it still runs when compiled.

So this may not be the source of the problem I have, as the error happens at runtime. The other error is only related to design-time.

sjoerd222's picture

I tried something new in WinGLContext.cs (Starting Line 90)

                    if (Wgl.Delegates.wglCreateContextAttribsARB != null)
                    {
                        try
                        {
                            Debug.Write("Using WGL_ARB_create_context... ");
 
                            List<int> attributes = new List<int>();
                            attributes.Add((int) ArbCreateContext.MajorVersion);
                            attributes.Add(major);
                            attributes.Add((int) ArbCreateContext.MinorVersion);
                            attributes.Add(minor);
                            if (flags != 0)
                            {
                                attributes.Add((int) ArbCreateContext.Flags);
#warning "This is not entirely correct: Embedded is not a valid flag! We need to add a GetARBContextFlags(GraphicsContextFlags) method."
                                attributes.Add((int) flags);
                            }
                            // According to the docs, " <attribList> specifies a list of attributes for the context.
                            // The list consists of a sequence of <name,value> pairs terminated by the
                            // value 0. [...]"
                            // Is this a single 0, or a <0, 0> pair? (Defensive coding: add two zeroes just in case).
                            attributes.Add(0);
                            attributes.Add(0);
 
                            Handle = new ContextHandle(
                                Wgl.Arb.CreateContextAttribs(
                                    window.DeviceContext,
                                    sharedContext != null
                                        ? (sharedContext as IGraphicsContextInternal).Context.Handle
                                        : IntPtr.Zero,
                                    attributes.ToArray()));
                            if (Handle == ContextHandle.Zero)
                                Debug.Print("failed. (Error: {0})", Marshal.GetLastWin32Error());
                            else
                                Debug.Print("success!");
                        }
                        catch (EntryPointNotFoundException e)
                        {
                            Debug.Print(e.ToString());
                        }
                        catch (NullReferenceException e)
                        {
                            Debug.Print(e.ToString());
                        }
//new code:
                        catch (Exception e)
                        {
                            Console.Write(e.Message);
                        }
                    }

But strangly I'm not able to catch the exception. OpenTK does test if the call was succesfull with:

if (Handle == ContextHandle.Zero)
                                Debug.Print("failed. (Error: {0})", Marshal.GetLastWin32Error());
                            else
                                Debug.Print("success!");

(This code is part of the WinGLContext.cs code extract above)
But with debbuging I could never reach that part of the code. And also the previous mentioned catches do catch nothing. Something goes wrong here!

sjoerd222's picture

So, I made some further investigations. In my application I used a Control that I derived from GLControl. Instead of doing this, I started to use a normal GLControl that I put into a UserControl. After doing the software worked again. I have a small testing form and a big appilcation both using my OpenGL Control. But then on the very next day, the big application didn't work any more and lost itself in the loop I described above. Strangly my testing form still worked. I made sure I wasn't using old dll's. Then I realised that the big application works when build in Release mode. So I thought it would be a timing issue. A lock(this) in GLControl.cs OnHandleCreated didn't help anything. But I found something that did something:

In WinGLContext.cs on Line 89 I set the if to false:
if (false)//Wgl.Delegates.wglCreateContextAttribsARB != null)
Then the result was, that the checks in OpenTK are reached (As described above, they are not normaly), and then this part of the code is run: (line 131)

  if (Handle == ContextHandle.Zero)
                {
                    // Failed to create GL3-level context, fall back to GL2.
                    Debug.Write("Falling back to GL2... ");
                    Handle = new ContextHandle(Wgl.Imports.CreateContext(window.DeviceContext));
                    if (Handle == ContextHandle.Zero)
                        Handle = new ContextHandle(Wgl.Imports.CreateContext(window.DeviceContext));
                    if (Handle == ContextHandle.Zero)
                        throw new GraphicsContextException(
                            String.Format("Context creation failed. Wgl.CreateContext() error: {0}.",
                                Marshal.GetLastWin32Error()));
                }

This results in the proper creation of a working context.

Anybody having an idea? Or some inputs how to continue with further investigations (I'm running out of ideas). Could this be an OpenTK issue. Or what things (that went wrong before) could result in such a behaviour.

sjoerd222's picture

Anyway, with SVN trunk 3069 everything works as expected.