kanato's picture

Failed to make context current

I have someone using AgateLib with OpenTK complaining about a "Failed to make context current" error when starting up on Linux (OpenSuse 11.1 64-bit with NVIDIA 8600GT). This is just an error on startup, with a very simple application that really does nothing. They have 3d drivers installed for their video card and can use desktop effects. I'm racking my brain to try to find out what else is but I am wondering if anyone here has any suggestions?


Comments

Comment viewing options

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

Could you try to add an error handler to see what is going on? Something like this should work:

using System;
using System.Text;
using System.Runtime.InteropServices;
 
class Test
{
	public struct XErrorEvent
	{
		public int type;
		public IntPtr display;     /* Display the event was read from */
		public IntPtr serial;      /* serial number of failed request */
		public byte error_code;    /* error code of failed request */
		public byte request_code;  /* Major op-code of failed request */
		public byte minor_code;    /* Minor op-code of failed request */
		public IntPtr resourceid;  /* resource id */
 
		public override string ToString()
		{
			StringBuilder sb = new StringBuilder(1024);
			XGetErrorText(display, error_code, sb, sb.Length);
			return String.Format("{{Error {0}: {1}}}", error_code.ToString(), sb.ToString());
		}
	}
 
	[DllImport("X11")]
	public extern static IntPtr XSetErrorHandler(XErrorHandler error_handler);
 
	[DllImport("X11")]
	public extern static IntPtr XGetErrorText(IntPtr display, byte code, StringBuilder buffer, int length);
 
	public delegate void XErrorHandler(IntPtr display, ref XErrorEvent error_event);
 
	public static void Main()
	{
		XSetErrorHandler((IntPtr display, ref XErrorEvent error) => Console.WriteLine("Error {0} on display {1}.", error.ToString(), display.ToString()));
	}
}

The error conditions from man glXMakeCurrent:

  • BadMatch is generated if drawable was not created with the same X screen and visual as ctx. It is also generated if drawable is None and ctx is not NULL.
  • BadAccess is generated if ctx was current to another thread at the time glXMakeCurrent was called.
  • GLXBadDrawable is generated if drawable is not a valid GLX drawable.
  • GLXBadContext is generated if ctx is not a valid GLX context.
  • GLXBadContextState is generated if glXMakeCurrent is executed between the execution of glBegin and the corresponding execution of glEnd.
  • GLXBadContextState is also generated if the rendering context current to the calling thread has GL renderer state GL_FEEDBACK or GL_SELECT.
  • GLXBadCurrentWindow is generated if there are pending GL commands for the previous context and the current drawable is a window that is no longer valid.
  • BadAlloc may be generated if the server has delayed allocation of ancillary buffers until glXMakeCurrent is called, only to find that it has insufficient resources to complete the allocation.
kanato's picture

Ok, it looks like X11 is giving a BadMatch. This is for code using a custom WinForms control as a render target instead of GameWindow, so maybe this is a bug with the Platform.Utilities code I wrote to create contexts for arbitrary controls. There are two values for Display that are printed out in the debug info, 17864192 and 15719072. Strangely, the same thing happens on my computer, but everything works fine. Maybe nVidia drivers care more about this sort of thing than intel drivers do.

    320x240x16@88Hz
    320x240x32@88Hz
Creating default GraphicsMode (24, 16, 0, 0, 0, 2, False).
Bits per pixel: 24
Depth: 16
Display: 17864192, Screen: 0, RootWindow: 315
Bits per pixel: 32
Depth: 24
Display: 17864192, Screen: 0, RootWindow: 315
Creating GraphicsContext.
    GraphicsMode: Index: 40, Color: 32 (8888), Depth: 24, Stencil: False, Samples: 0, Accum: 64 (16161616), Buffers: 2, Stereo: False
    IWindowInfo: X11.WindowInfo: Display 15719072, Screen 0, Handle 62914577, Parent: (null)
    Chose visual: id (40), screen (0), depth (24), class (TrueColor)
    Creating OpenGL context: direct, not shared... done! (id: 22016640)
Making context 22016640 current on thread 1 (Display: 15719072, Screen: 0, Window: 62914577)... X11 Error encountered:
  Error: BadMatch (invalid parameter attributes)
  Request:     143 (5)
  Resource ID: 0x3C00011
  Serial:      243
  Hwnd:        Hwnd, Mapped:True ClientWindow:0x3C00011, WholeWindow:0x3C00010, Zombie=False, Parent:[Hwnd, Mapped:True ClientWindow:0x3C0000F, WholeWindow:0x3C0000E, Zombie=False, Parent:[<null>]]
  Control:     AgateLib.WinForms.AgateRenderTarget, BorderStyle: None   at System.Environment.get_StackTrace() in /usr/src/packages/BUILD/mono-2.0.1/mcs/class/corlib/System/Environment.cs:line 206
the Fiddler's picture

BadMatch error... this rings a bell. I remember encountering this error when a Form had a different visual than the Context bound to it.

As a tangential issue, does a plain Form + GLControl work? Something like the following, maybe:

using System;
using System.Windows.Forms;
using OpenTK;
using OpenTK.Graphics;
 
class Test : Form
{
    public Test()
    {
        SuspendLayout();
        GLControl control = new GLControl();
        control.Dock = DockStyle.Fill;
        control.Paint += (object sender, PaintEventArgs e) => { GL.Clear(ClearBufferMask.ColorBufferBit); control.SwapBuffers(); };
        Controls.Add(control);
        ResumeLayout();
    }
 
    public static void Main()
    {
        Application.Run(new Test());
    }
}
Inertia's picture

The RGBA16 accumulation buffer looks wrong. Most cards do not support this.

kanato's picture

Well, I've corrected the value for the accumulator buffer.
Is there any possibility that the multiple display handles could be causing the BadMatch? This happens because there are two ways of getting the display handle; in Platform/X11/API.cs the static constructor calls XOpenDisplay. Platform/X11/X11GLControl.cs and Platform/Utilities.cs get the display handle via:

Type xplatui = Type.GetType("System.Windows.Forms.XplatUIX11, System.Windows.Forms");
display = (IntPtr)xplatui.GetField("DisplayHandle", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);

should these be consistent? This doesn't seem to be a problem on my systems but these are all ATI and Intel video cards; I don't have any nVidia cards to test with.

kanato's picture

Well, it looks like fixing the value for the accumulation buffer did the trick.

the Fiddler's picture

I still wonder why this failed. On my ati desktop, half of the visuals report a 64bit accumulation buffer, but I haven't checked if you can actually create such a context.

I'm also qurious about what glxinfo reports on nvidia cards.