mirror of
https://github.com/Ryujinx/Opentk.git
synced 2025-05-02 05:16:28 +00:00
[X11] Fixed GLX extension loading
GLX is now using the new extension loading mechanism, and the entry point names now much the available slots.
This commit is contained in:
parent
cd7342b688
commit
88905cb6aa
|
@ -259,32 +259,75 @@ namespace OpenTK.Platform.X11
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Provides access to GLX functions.
|
/// Provides access to GLX functions.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
class Glx
|
class Glx : Graphics.GraphicsBindingsBase
|
||||||
{
|
{
|
||||||
const string Library = "libGL.so.1";
|
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",
|
// glXCreateContextAttribsARB
|
||||||
"glXSwapIntervalEXT",
|
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,
|
||||||
"glXGetSwapIntervalEXT",
|
// glXSwapIntervalEXT
|
||||||
"glXSwapIntervalMESA",
|
0x67, 0x6c, 0x58, 0x53, 0x77, 0x61, 0x70, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x45, 0x58, 0x54, 0,
|
||||||
"glXGetSwapIntervalMESA",
|
// glXGetSwapIntervalEXT
|
||||||
"glXSwapIntervalOML",
|
0x67, 0x6c, 0x58, 0x47, 0x65, 0x74, 0x53, 0x77, 0x61, 0x70, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x45, 0x58, 0x54, 0,
|
||||||
"glXGetSwapIntervalOML",
|
// glXSwapIntervalMESA
|
||||||
"glXSwapIntervalSGI",
|
0x67, 0x6c, 0x58, 0x53, 0x77, 0x61, 0x70, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x4d, 0x45, 0x53, 0x41, 0,
|
||||||
"glXGetSwapIntervalSGI",
|
// 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,
|
||||||
|
// glXGetSwapIntervalSGI
|
||||||
|
0x67, 0x6c, 0x58, 0x47, 0x65, 0x74, 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[7];
|
||||||
|
static IntPtr[] EntryPoints = new IntPtr[7];
|
||||||
|
|
||||||
static Glx()
|
internal Glx()
|
||||||
{
|
{
|
||||||
// GLX entry points are not bound to a context.
|
// GLX entry points are not bound to a context.
|
||||||
// This means we can load them without creating
|
// This means we can load them without creating
|
||||||
// a context first! (unlike WGL)
|
// 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++)
|
||||||
|
{
|
||||||
|
System.Diagnostics.Debug.WriteLine(Marshal.PtrToStringAnsi(
|
||||||
|
new IntPtr(name + _EntryPointNameOffsetsInstance[i])));
|
||||||
|
_EntryPointsInstance[i] = Arb.GetProcAddress(
|
||||||
|
new IntPtr(name + _EntryPointNameOffsetsInstance[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -409,6 +452,9 @@ namespace OpenTK.Platform.X11
|
||||||
[DllImport(Library, EntryPoint = "glXGetProcAddressARB")]
|
[DllImport(Library, EntryPoint = "glXGetProcAddressARB")]
|
||||||
public static extern IntPtr GetProcAddress([MarshalAs(UnmanagedType.LPTStr)] string procName);
|
public static extern IntPtr GetProcAddress([MarshalAs(UnmanagedType.LPTStr)] string procName);
|
||||||
|
|
||||||
|
[DllImport(Library, EntryPoint = "glXGetProcAddressARB")]
|
||||||
|
public static extern IntPtr GetProcAddress(IntPtr procName);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -458,25 +504,25 @@ namespace OpenTK.Platform.X11
|
||||||
}
|
}
|
||||||
|
|
||||||
[Slot(0)]
|
[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);
|
internal unsafe static extern IntPtr glXCreateContextAttribsARB(IntPtr display, IntPtr fbconfig, IntPtr share_context, bool direct, int* attribs);
|
||||||
[Slot(1)]
|
[Slot(1)]
|
||||||
[DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
|
[DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||||
internal static extern ErrorCode glXSwapIntervalEXT(int interval);
|
internal static extern ErrorCode glXSwapIntervalEXT(int interval);
|
||||||
[Slot(2)]
|
[Slot(2)]
|
||||||
[DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
|
[DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||||
internal static extern int glXGetSwapIntervalEXT();
|
internal static extern int glXGetSwapIntervalEXT();
|
||||||
[Slot(3)]
|
[Slot(3)]
|
||||||
[DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
|
[DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||||
internal static extern ErrorCode glXSwapIntervalMESA(int interval);
|
internal static extern ErrorCode glXSwapIntervalMESA(int interval);
|
||||||
[Slot(4)]
|
[Slot(4)]
|
||||||
[DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
|
[DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||||
internal static extern int glXGetSwapIntervalMESA();
|
internal static extern int glXGetSwapIntervalMESA();
|
||||||
[Slot(5)]
|
[Slot(5)]
|
||||||
[DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
|
[DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||||
internal static extern ErrorCode glXSwapIntervalSGI(int interval);
|
internal static extern ErrorCode glXSwapIntervalSGI(int interval);
|
||||||
[Slot(6)]
|
[Slot(6)]
|
||||||
[DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
|
[DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||||
internal static extern int glXGetSwapIntervalSGI();
|
internal static extern int glXGetSwapIntervalSGI();
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
|
@ -41,6 +41,11 @@ namespace OpenTK.Platform.X11
|
||||||
|
|
||||||
#region --- Constructors ---
|
#region --- Constructors ---
|
||||||
|
|
||||||
|
static X11GLContext()
|
||||||
|
{
|
||||||
|
new Glx().LoadEntryPoints();
|
||||||
|
}
|
||||||
|
|
||||||
public X11GLContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shared, bool direct,
|
public X11GLContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shared, bool direct,
|
||||||
int major, int minor, GraphicsContextFlags flags)
|
int major, int minor, GraphicsContextFlags flags)
|
||||||
{
|
{
|
||||||
|
@ -258,8 +263,7 @@ namespace OpenTK.Platform.X11
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
SupportsExtension(display, window, "GLX_ARB_create_context") &&
|
SupportsExtension(display, window, "GLX_ARB_create_context") &&
|
||||||
SupportsExtension(display, window, "GLX_ARB_create_context_profile") &&
|
SupportsExtension(display, window, "GLX_ARB_create_context_profile");
|
||||||
Glx.SupportsFunction("glXCreateContextAttribsARB");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -402,23 +406,24 @@ namespace OpenTK.Platform.X11
|
||||||
|
|
||||||
public override void LoadAll()
|
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 =
|
vsync_ext_supported =
|
||||||
SupportsExtension(display, currentWindow, "GLX_EXT_swap_control") &&
|
SupportsExtension(display, currentWindow, "GLX_EXT_swap_control");
|
||||||
Glx.SupportsFunction("glXSwapIntervalEXT") &&
|
|
||||||
Glx.SupportsFunction("glXGetSwapIntervalEXT");
|
|
||||||
vsync_mesa_supported =
|
vsync_mesa_supported =
|
||||||
SupportsExtension(display, currentWindow, "GLX_MESA_swap_control") &&
|
SupportsExtension(display, currentWindow, "GLX_MESA_swap_control");
|
||||||
Glx.SupportsFunction("glXSwapIntervalMESA") &&
|
|
||||||
Glx.SupportsFunction("glXGetSwapIntervalMESA");
|
|
||||||
vsync_sgi_supported =
|
vsync_sgi_supported =
|
||||||
SupportsExtension(display, currentWindow, "GLX_SGI_swap_control") &&
|
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);
|
|
||||||
|
|
||||||
vsync_tear_supported =
|
vsync_tear_supported =
|
||||||
SupportsExtension(display, currentWindow, "GLX_EXT_swap_control_tear");
|
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();
|
base.LoadAll();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue