Permalink
Browse files

Merge branch 'nvidiafix' into develop

  • Loading branch information...
2 parents 50b611e + 4e8786f commit c2bd8624b5a8c1656c6f72deef6bf46312adb10f @thefiddler thefiddler committed May 12, 2014
Showing with 118 additions and 60 deletions.
  1. +69 −42 Source/OpenTK/Platform/X11/Bindings/Glx.cs
  2. +49 −18 Source/OpenTK/Platform/X11/X11GLContext.cs
View
111 Source/OpenTK/Platform/X11/Bindings/Glx.cs
@@ -134,6 +134,8 @@ enum GLXAttribute : int
LEVEL = 3,
CONFIG_CAVEAT = 0x20,
RENDER_TYPE_SGIX = 0x8011,
+ SWAP_INTERVAL_EXT = 0x20F1,
+ MAX_SWAP_INTERVAL_EXT = 0x20F2,
}
enum GLXHyperpipeAttrib : int
@@ -259,32 +261,69 @@ enum ErrorCode : int
/// <summary>
/// Provides access to GLX functions.
/// </summary>
- class Glx
+ class Glx : Graphics.GraphicsBindingsBase
{
const string Library = "libGL.so.1";
+ static readonly object sync_root = new object();
- static string[] EntryPointNames = new string[]
+ static readonly byte[] EntryPointNames = new byte[]
{
- "glXCreateContextAttribs",
- "glXSwapIntervalEXT",
- "glXGetSwapIntervalEXT",
- "glXSwapIntervalMESA",
- "glXGetSwapIntervalMESA",
- "glXSwapIntervalOML",
- "glXGetSwapIntervalOML",
- "glXSwapIntervalSGI",
- "glXGetSwapIntervalSGI",
+ // glXCreateContextAttribsARB
+ 0x67, 0x6c, 0x58, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x73, 0x41, 0x52, 0x42, 0,
+ // glXSwapIntervalEXT
+ 0x67, 0x6c, 0x58, 0x53, 0x77, 0x61, 0x70, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x45, 0x58, 0x54, 0,
+ // glXSwapIntervalMESA
+ 0x67, 0x6c, 0x58, 0x53, 0x77, 0x61, 0x70, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x4d, 0x45, 0x53, 0x41, 0,
+ // glXGetSwapIntervalMESA
+ 0x67, 0x6c, 0x58, 0x47, 0x65, 0x74, 0x53, 0x77, 0x61, 0x70, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x4d, 0x45, 0x53, 0x41, 0,
+ // glXSwapIntervalSGI
+ 0x67, 0x6c, 0x58, 0x53, 0x77, 0x61, 0x70, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x53, 0x47, 0x49, 0,
};
- static IntPtr[] EntryPoints = new IntPtr[EntryPointNames.Length];
+ static readonly int[] EntryPointOffsets = new int[5];
+ static IntPtr[] EntryPoints = new IntPtr[5];
- static Glx()
+ internal Glx()
{
// GLX entry points are not bound to a context.
// This means we can load them without creating
// a context first! (unlike WGL)
- for (int i = 0; i < EntryPointNames.Length; i++)
+ _EntryPointsInstance = EntryPoints;
+ _EntryPointNamesInstance = EntryPointNames;
+ _EntryPointNameOffsetsInstance = EntryPointOffsets;
+
+ // Writing the entry point name offsets
+ // by hand is error prone. Do it in code
+ // instead:
+ int offset = 0;
+ for (int i = 0, j = 0; i < EntryPointNames.Length; i++)
{
- EntryPoints[i] = Arb.GetProcAddress(EntryPointNames[i]);
+ if (EntryPointNames[i] == 0)
+ {
+ EntryPointOffsets[j++] = offset;
+ offset = i + 1;
+ }
+ }
+ }
+
+ protected override object SyncRoot { get { return sync_root; } }
+
+ protected override IntPtr GetAddress(string funcname)
+ {
+ return Arb.GetProcAddress(funcname);
+ }
+
+ internal override void LoadEntryPoints()
+ {
+ unsafe
+ {
+ fixed (byte* name = _EntryPointNamesInstance)
+ {
+ for (int i = 0; i < _EntryPointsInstance.Length; i++)
+ {
+ _EntryPointsInstance[i] = Arb.GetProcAddress(
+ new IntPtr(name + _EntryPointNameOffsetsInstance[i]));
+ }
+ }
}
}
@@ -302,6 +341,9 @@ internal static bool SupportsFunction(string name)
[DllImport(Library, EntryPoint = "glXIsDirect")]
public static extern bool IsDirect(IntPtr dpy, IntPtr context);
+
+ [DllImport(Library, EntryPoint = "glXQueryDrawable")]
+ public static extern ErrorCode QueryDrawable(IntPtr dpy, IntPtr drawable, GLXAttribute attribute, out int value);
[DllImport(Library, EntryPoint = "glXQueryExtension")]
public static extern bool QueryExtension(IntPtr dpy, ref int errorBase, ref int eventBase);
@@ -409,19 +451,16 @@ public static IntPtr CreateContextAttribs(IntPtr display, IntPtr fbconfig, IntPt
[DllImport(Library, EntryPoint = "glXGetProcAddressARB")]
public static extern IntPtr GetProcAddress([MarshalAs(UnmanagedType.LPTStr)] string procName);
+ [DllImport(Library, EntryPoint = "glXGetProcAddressARB")]
+ public static extern IntPtr GetProcAddress(IntPtr procName);
+
#endregion
}
public partial class Ext
{
[AutoGenerated(EntryPoint = "glXSwapIntervalEXT")]
- public static ErrorCode SwapInterval(int interval)
- {
- throw new NotImplementedException();
- }
-
- [AutoGenerated(EntryPoint = "glXGetSwapIntervalEXT")]
- public static int GetSwapInterval()
+ public static ErrorCode SwapInterval(IntPtr display, IntPtr drawable, int interval)
{
throw new NotImplementedException();
}
@@ -449,35 +488,23 @@ public static ErrorCode SwapInterval(int interval)
{
throw new NotImplementedException();
}
-
- [AutoGenerated(EntryPoint = "glXGetSwapIntervalSGI")]
- public static int GetSwapInterval()
- {
- throw new NotImplementedException();
- }
}
[Slot(0)]
- [DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
+ [DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
internal unsafe static extern IntPtr glXCreateContextAttribsARB(IntPtr display, IntPtr fbconfig, IntPtr share_context, bool direct, int* attribs);
[Slot(1)]
- [DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
- internal static extern ErrorCode glXSwapIntervalEXT(int interval);
+ [DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern ErrorCode glXSwapIntervalEXT(IntPtr display, IntPtr drawable, int interval);
[Slot(2)]
- [DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
- internal static extern int glXGetSwapIntervalEXT();
- [Slot(3)]
- [DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
+ [DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
internal static extern ErrorCode glXSwapIntervalMESA(int interval);
- [Slot(4)]
- [DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
+ [Slot(3)]
+ [DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
internal static extern int glXGetSwapIntervalMESA();
- [Slot(5)]
- [DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
+ [Slot(4)]
+ [DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
internal static extern ErrorCode glXSwapIntervalSGI(int interval);
- [Slot(6)]
- [DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
- internal static extern int glXGetSwapIntervalSGI();
#endregion
}
View
67 Source/OpenTK/Platform/X11/X11GLContext.cs
@@ -41,6 +41,11 @@ internal sealed class X11GLContext : DesktopGraphicsContext
#region --- Constructors ---
+ static X11GLContext()
+ {
+ new Glx().LoadEntryPoints();
+ }
+
public X11GLContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shared, bool direct,
int major, int minor, GraphicsContextFlags flags)
{
@@ -258,8 +263,7 @@ bool SupportsCreateContextAttribs(IntPtr display, X11WindowInfo window)
{
return
SupportsExtension(display, window, "GLX_ARB_create_context") &&
- SupportsExtension(display, window, "GLX_ARB_create_context_profile") &&
- Glx.SupportsFunction("glXCreateContextAttribsARB");
+ SupportsExtension(display, window, "GLX_ARB_create_context_profile");
}
#endregion
@@ -359,20 +363,40 @@ public override int SwapInterval
{
get
{
+ if (currentWindow == null)
+ {
+ Debug.Print("Context must be current");
+ throw new InvalidOperationException();
+ }
+
using (new XLock(display))
{
if (vsync_ext_supported)
- return Glx.Ext.GetSwapInterval();
+ {
+ int value;
+ Glx.QueryDrawable(Display, currentWindow.Handle, GLXAttribute.SWAP_INTERVAL_EXT, out value);
+ return value;
+ }
else if (vsync_mesa_supported)
+ {
return Glx.Mesa.GetSwapInterval();
+ }
else if (vsync_sgi_supported)
+ {
return sgi_swap_interval;
- else
- return 0;
+ }
+
+ return 0;
}
}
set
{
+ if (currentWindow == null)
+ {
+ Debug.Print("Context must be current");
+ throw new InvalidOperationException();
+ }
+
if (value < 0 && !vsync_tear_supported)
{
value = 1;
@@ -382,11 +406,17 @@ public override int SwapInterval
using (new XLock(Display))
{
if (vsync_ext_supported)
- error_code = Glx.Ext.SwapInterval(value);
+ {
+ Glx.Ext.SwapInterval(Display, currentWindow.Handle, value);
+ }
else if (vsync_mesa_supported)
+ {
error_code = Glx.Mesa.SwapInterval(value);
+ }
else if (vsync_sgi_supported)
+ {
error_code = Glx.Sgi.SwapInterval(value);
+ }
}
if (error_code == X11.ErrorCode.NO_ERROR)
@@ -402,23 +432,24 @@ public override int SwapInterval
public override void LoadAll()
{
+ // Note: GLX entry points are always available, even
+ // for extensions that are not currently supported by
+ // the underlying driver. This means we can only check
+ // the extension strings for support, not the entry
+ // points themselves.
vsync_ext_supported =
- SupportsExtension(display, currentWindow, "GLX_EXT_swap_control") &&
- Glx.SupportsFunction("glXSwapIntervalEXT") &&
- Glx.SupportsFunction("glXGetSwapIntervalEXT");
+ SupportsExtension(display, currentWindow, "GLX_EXT_swap_control");
vsync_mesa_supported =
- SupportsExtension(display, currentWindow, "GLX_MESA_swap_control") &&
- Glx.SupportsFunction("glXSwapIntervalMESA") &&
- Glx.SupportsFunction("glXGetSwapIntervalMESA");
+ SupportsExtension(display, currentWindow, "GLX_MESA_swap_control");
vsync_sgi_supported =
- SupportsExtension(display, currentWindow, "GLX_SGI_swap_control") &&
- Glx.SupportsFunction("glXSwapIntervalSGI");
- Debug.Print("Context supports vsync: {0}.",
- vsync_ext_supported || vsync_mesa_supported || vsync_ext_supported);
-
+ SupportsExtension(display, currentWindow, "GLX_SGI_swap_control");
vsync_tear_supported =
SupportsExtension(display, currentWindow, "GLX_EXT_swap_control_tear");
- Debug.Print("Context supports vsync tear: {0}.", vsync_tear_supported);
+
+ Debug.Print("Context supports vsync: {0}.",
+ vsync_ext_supported || vsync_mesa_supported || vsync_sgi_supported);
+ Debug.Print("Context supports adaptive vsync: {0}.",
+ vsync_tear_supported);
base.LoadAll();
}

0 comments on commit c2bd862

Please sign in to comment.