Fix support for 3.2+ contexts (issue 3111)

glXGetProcAddress may return a non-null value even if a function is not
supported by the server. We need to check the extension string using
any GLX extensions. Fixes issue http://www.opentk.com/node/3111 "GLX
extension support is not checked correctly".

Furthermore, mode selection is now performed explicitly by the
X11GLContext constructor.
This commit is contained in:
Stefanos A 2013-11-09 11:16:14 +01:00
parent 3c71634667
commit 2725b3cd08
3 changed files with 40 additions and 9 deletions

View file

@ -231,11 +231,14 @@ namespace OpenTK.Platform.X11
{
DebugBit = 0x0001,
ForwardCompatibleBit = 0x0002,
CoreProfileBit = 0x00000001,
CompatibilityProfileBit = 0x00000002,
MajorVersion = 0x2091,
MinorVersion = 0x2092,
LayerPlane = 0x2093,
Flags = 0x2094,
ErrorInvalidVersion = 0x2095,
ProfileMask = 0x9126
}
enum ErrorCode : int

View file

@ -77,7 +77,7 @@ namespace OpenTK.Platform.X11
public virtual IGraphicsMode CreateGraphicsMode()
{
return new X11GraphicsMode();
throw new NotSupportedException();
}
public virtual OpenTK.Input.IKeyboardDriver2 CreateKeyboardDriver()

View file

@ -33,6 +33,8 @@ namespace OpenTK.Platform.X11
int swap_interval = 1; // As defined in GLX_SGI_swap_control
bool glx_loaded;
readonly X11GraphicsMode ModeSelector = new X11GraphicsMode();
#endregion
#region --- Constructors ---
@ -45,7 +47,9 @@ namespace OpenTK.Platform.X11
if (window == null)
throw new ArgumentNullException("window");
Mode = mode;
Mode = ModeSelector.SelectGraphicsMode(
mode.ColorFormat, mode.Depth, mode.Stencil, mode.Samples,
mode.AccumulatorFormat, mode.Buffers, mode.Stereo);
// Do not move this lower, as almost everything requires the Display
// property to be correctly set.
@ -80,7 +84,7 @@ namespace OpenTK.Platform.X11
// HACK: It seems that Catalyst 9.1 - 9.4 on Linux have problems with contexts created through
// GLX_ARB_create_context, including hideous input lag, no vsync and other madness.
// Use legacy context creation if the user doesn't request a 3.0+ context.
if ((major * 10 + minor >= 30) && Glx.Delegates.glXCreateContextAttribsARB != null)
if ((major * 10 + minor >= 30) && SupportsCreateContextAttribs(Display, currentWindow))
{
Debug.Write("Using GLX_ARB_create_context... ");
@ -104,9 +108,10 @@ namespace OpenTK.Platform.X11
attributes.Add(minor);
if (flags != 0)
{
#warning "This is not entirely correct: Embedded is not a valid flag! We need to add a GetARBContextFlags(GraphicsContextFlags) method."
attributes.Add((int)ArbCreateContext.Flags);
attributes.Add((int)flags);
attributes.Add((int)GetARBContextFlags(flags));
attributes.Add((int)ArbCreateContext.ProfileMask);
attributes.Add((int)GetARBProfileFlags(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
@ -225,23 +230,46 @@ namespace OpenTK.Platform.X11
#endregion
bool SupportsExtension(X11WindowInfo window, string e)
ArbCreateContext GetARBContextFlags(GraphicsContextFlags flags)
{
ArbCreateContext result = 0;
result |= (flags & GraphicsContextFlags.Debug) != 0 ? ArbCreateContext.DebugBit : 0;
return result;
}
ArbCreateContext GetARBProfileFlags(GraphicsContextFlags flags)
{
ArbCreateContext result = 0;
result |= (flags & GraphicsContextFlags.ForwardCompatible) != 0 ?
ArbCreateContext.ForwardCompatibleBit : ArbCreateContext.CompatibilityProfileBit;
return result;
}
static bool SupportsExtension(IntPtr display, X11WindowInfo window, string e)
{
if (window == null)
throw new ArgumentNullException("window");
if (e == null)
throw new ArgumentNullException("e");
if (window.Display != Display)
if (window.Display != display)
throw new InvalidOperationException();
string extensions = null;
using (new XLock(Display))
using (new XLock(display))
{
extensions = Glx.QueryExtensionsString(Display, window.Screen);
extensions = Glx.QueryExtensionsString(display, window.Screen);
}
return !String.IsNullOrEmpty(extensions) && extensions.Contains(e);
}
static bool SupportsCreateContextAttribs(IntPtr display, X11WindowInfo window)
{
return
SupportsExtension(display, window, "GLX_ARB_create_context") &&
SupportsExtension(display, window, "GLX_ARB_create_context_profile") &&
Glx.Delegates.glXCreateContextAttribsARB != null;
}
#endregion
#region --- IGraphicsContext Members ---