mirror of
https://github.com/Ryujinx/Opentk.git
synced 2025-01-10 23:25:27 +00:00
Updated WGL init sequence
WinGraphicsMode no longer creates a temporary context in order to create the list of available modes. Instead, it requires to be passed an existing context in its constructor. WinGLContext now creates one temporary context in its static constructor and hands that to WinGraphicsMode. WinFactory no longer supports the CreateGraphicsMode API. This API will be removed in the future, because the link because contexts and modes cannot be separated in the general case.
This commit is contained in:
parent
0f01a6d128
commit
95316829ec
|
@ -89,7 +89,7 @@ namespace OpenTK.Platform.Windows
|
|||
|
||||
public virtual IGraphicsMode CreateGraphicsMode()
|
||||
{
|
||||
return new WinGraphicsMode();
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public virtual OpenTK.Input.IKeyboardDriver2 CreateKeyboardDriver()
|
||||
|
|
|
@ -36,11 +36,43 @@ namespace OpenTK.Platform.Windows
|
|||
|
||||
bool vsync_supported;
|
||||
|
||||
static readonly IGraphicsMode ModeSelector;
|
||||
|
||||
#region --- Contructors ---
|
||||
|
||||
static WinGLContext()
|
||||
{
|
||||
Init();
|
||||
// Dynamically load the OpenGL32.dll in order to use the extension loading capabilities of Wgl.
|
||||
if (opengl32Handle == IntPtr.Zero)
|
||||
{
|
||||
opengl32Handle = Functions.LoadLibrary(opengl32Name);
|
||||
if (opengl32Handle == IntPtr.Zero)
|
||||
throw new ApplicationException(String.Format("LoadLibrary(\"{0}\") call failed with code {1}",
|
||||
opengl32Name, Marshal.GetLastWin32Error()));
|
||||
Debug.WriteLine(String.Format("Loaded opengl32.dll: {0}", opengl32Handle));
|
||||
}
|
||||
|
||||
// We need to create a temp context in order to load
|
||||
// wgl extensions (e.g. for multisampling or GL3).
|
||||
// We cannot rely on OpenTK.Platform.Wgl until we
|
||||
// create the context and call Wgl.LoadAll().
|
||||
Debug.Print("Creating temporary context for wgl extensions.");
|
||||
using (INativeWindow native = new NativeWindow())
|
||||
{
|
||||
// Create temporary context and load WGL entry points
|
||||
WinWindowInfo window = native.WindowInfo as WinWindowInfo;
|
||||
ContextHandle temp_context = new ContextHandle(Wgl.Imports.CreateContext(window.DeviceContext));
|
||||
Wgl.Imports.MakeCurrent(window.DeviceContext, temp_context.Handle);
|
||||
Wgl.LoadAll();
|
||||
|
||||
// Query graphics modes
|
||||
ModeSelector = new WinGraphicsMode(temp_context, window.DeviceContext);
|
||||
|
||||
// Destroy temporary context
|
||||
Wgl.Imports.MakeCurrent(IntPtr.Zero, IntPtr.Zero);
|
||||
Wgl.Imports.DeleteContext(temp_context.Handle);
|
||||
wgl_loaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
public WinGLContext(GraphicsMode format, WinWindowInfo window, IGraphicsContext sharedContext,
|
||||
|
@ -56,11 +88,8 @@ namespace OpenTK.Platform.Windows
|
|||
if (window.Handle == IntPtr.Zero)
|
||||
throw new ArgumentException("window", "Must be a valid window.");
|
||||
|
||||
Mode = format;
|
||||
|
||||
Debug.Print("OpenGL will be bound to window:{0} on thread:{1}", window.Handle,
|
||||
System.Threading.Thread.CurrentThread.ManagedThreadId);
|
||||
SetGraphicsModePFD(format, (WinWindowInfo)window);
|
||||
|
||||
lock (LoadLock)
|
||||
{
|
||||
|
@ -71,18 +100,11 @@ namespace OpenTK.Platform.Windows
|
|||
// side-effects (i.e. the old contexts can still be handled
|
||||
// using the new entry points.)
|
||||
// Sigh...
|
||||
// if (!wgl_loaded)
|
||||
{
|
||||
// We need to create a temp context in order to load wgl extensions (e.g. for multisampling or GL3).
|
||||
// We cannot rely on OpenTK.Platform.Wgl until we create the context and call Wgl.LoadAll().
|
||||
Debug.Print("Creating temporary context for wgl extensions.");
|
||||
ContextHandle temp_context = new ContextHandle(Wgl.Imports.CreateContext(window.DeviceContext));
|
||||
Wgl.Imports.MakeCurrent(window.DeviceContext, temp_context.Handle);
|
||||
Wgl.LoadAll();
|
||||
Wgl.Imports.MakeCurrent(IntPtr.Zero, IntPtr.Zero);
|
||||
Wgl.Imports.DeleteContext(temp_context.Handle);
|
||||
wgl_loaded = true;
|
||||
}
|
||||
//if (!wgl_loaded)
|
||||
//{
|
||||
//}
|
||||
|
||||
Mode = SetGraphicsModePFD(format, (WinWindowInfo)window);
|
||||
|
||||
if (Wgl.Delegates.wglCreateContextAttribsARB != null)
|
||||
{
|
||||
|
@ -281,22 +303,35 @@ namespace OpenTK.Platform.Windows
|
|||
#region SetGraphicsModePFD
|
||||
|
||||
// Note: there is no relevant ARB function.
|
||||
internal static void SetGraphicsModePFD(GraphicsMode mode, WinWindowInfo window)
|
||||
internal static GraphicsMode SetGraphicsModePFD(GraphicsMode mode, WinWindowInfo window)
|
||||
{
|
||||
Debug.Write("Setting pixel format... ");
|
||||
if (window == null)
|
||||
throw new ArgumentNullException("window", "Must point to a valid window.");
|
||||
|
||||
if (!mode.Index.HasValue)
|
||||
throw new GraphicsModeException("Invalid or unsupported GraphicsMode.");
|
||||
|
||||
if (window == null) throw new ArgumentNullException("window", "Must point to a valid window.");
|
||||
{
|
||||
mode = ModeSelector.SelectGraphicsMode(
|
||||
mode.ColorFormat, mode.Depth, mode.Stencil,
|
||||
mode.Samples, mode.AccumulatorFormat,
|
||||
mode.Buffers, mode.Stereo);
|
||||
}
|
||||
|
||||
PixelFormatDescriptor pfd = new PixelFormatDescriptor();
|
||||
Functions.DescribePixelFormat(window.DeviceContext, (int)mode.Index.Value,
|
||||
Functions.DescribePixelFormat(
|
||||
window.DeviceContext, (int)mode.Index.Value,
|
||||
API.PixelFormatDescriptorSize, ref pfd);
|
||||
|
||||
Debug.WriteLine(mode.Index.ToString());
|
||||
|
||||
if (!Functions.SetPixelFormat(window.DeviceContext, (int)mode.Index.Value, ref pfd))
|
||||
{
|
||||
throw new GraphicsContextException(String.Format(
|
||||
"Requested GraphicsMode not available. SetPixelFormat error: {0}", Marshal.GetLastWin32Error()));
|
||||
"Requested GraphicsMode not available. SetPixelFormat error: {0}",
|
||||
Marshal.GetLastWin32Error()));
|
||||
}
|
||||
|
||||
return mode;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -314,22 +349,6 @@ namespace OpenTK.Platform.Windows
|
|||
|
||||
#endregion
|
||||
|
||||
static internal void Init()
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
// Dynamically load the OpenGL32.dll in order to use the extension loading capabilities of Wgl.
|
||||
if (opengl32Handle == IntPtr.Zero)
|
||||
{
|
||||
opengl32Handle = Functions.LoadLibrary(opengl32Name);
|
||||
if (opengl32Handle == IntPtr.Zero)
|
||||
throw new ApplicationException(String.Format("LoadLibrary(\"{0}\") call failed with code {1}",
|
||||
opengl32Name, Marshal.GetLastWin32Error()));
|
||||
Debug.WriteLine(String.Format("Loaded opengl32.dll: {0}", opengl32Handle));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Overrides
|
||||
|
|
|
@ -46,19 +46,16 @@ namespace OpenTK.Platform.Windows
|
|||
|
||||
#region Constructors
|
||||
|
||||
public WinGraphicsMode()
|
||||
public WinGraphicsMode(ContextHandle context, IntPtr device)
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
using (INativeWindow native = new NativeWindow())
|
||||
{
|
||||
modes.AddRange(GetModesARB(native));
|
||||
if (modes.Count == 0)
|
||||
modes.AddRange(GetModesPFD(native));
|
||||
if (modes.Count == 0)
|
||||
throw new GraphicsModeException(
|
||||
"No GraphicsMode available. This should never happen, please report a bug at http://www.opentk.com");
|
||||
}
|
||||
modes.AddRange(GetModesARB(context, device));
|
||||
if (modes.Count == 0)
|
||||
modes.AddRange(GetModesPFD(context, device));
|
||||
if (modes.Count == 0)
|
||||
throw new GraphicsModeException(
|
||||
"No GraphicsMode available. This should never happen, please report a bug at http://www.opentk.com");
|
||||
modes.Sort(new GraphicsModeComparer());
|
||||
}
|
||||
}
|
||||
|
@ -127,11 +124,9 @@ namespace OpenTK.Platform.Windows
|
|||
|
||||
#region GetModesPFD
|
||||
|
||||
IEnumerable<GraphicsMode> GetModesPFD(INativeWindow native)
|
||||
IEnumerable<GraphicsMode> GetModesPFD(ContextHandle context, IntPtr device)
|
||||
{
|
||||
WinWindowInfo window = native.WindowInfo as WinWindowInfo;
|
||||
IntPtr deviceContext = ((WinWindowInfo)window).DeviceContext;
|
||||
Debug.WriteLine(String.Format("Device context: {0}", deviceContext));
|
||||
Debug.WriteLine(String.Format("Device context: {0}", device));
|
||||
|
||||
Debug.WriteLine("Retrieving PFD pixel formats... ");
|
||||
PixelFormatDescriptor pfd = new PixelFormatDescriptor();
|
||||
|
@ -152,7 +147,7 @@ namespace OpenTK.Platform.Windows
|
|||
// Iterate through all accelerated formats first. Afterwards, iterate through non-accelerated formats.
|
||||
// This should fix issue #2224, which causes OpenTK to fail on VMs without hardware acceleration.
|
||||
int pixel = 0;
|
||||
while (DescribePixelFormat(deviceContext, ++pixel, API.PixelFormatDescriptorSize, ref pfd) != 0)
|
||||
while (DescribePixelFormat(device, ++pixel, API.PixelFormatDescriptorSize, ref pfd) != 0)
|
||||
{
|
||||
// Ignore non-accelerated formats.
|
||||
if (!generic_allowed && (pfd.Flags & PixelFormatDescriptorFlags.GENERIC_FORMAT) != 0)
|
||||
|
@ -176,90 +171,83 @@ namespace OpenTK.Platform.Windows
|
|||
|
||||
#region GetModesARB
|
||||
|
||||
IEnumerable<GraphicsMode> GetModesARB(INativeWindow native)
|
||||
IEnumerable<GraphicsMode> GetModesARB(ContextHandle context, IntPtr device)
|
||||
{
|
||||
using (IGraphicsContext context = new GraphicsContext(
|
||||
new GraphicsMode(new IntPtr(2), new ColorFormat(), 0, 0, 0, new ColorFormat(), 2, false),
|
||||
(WinWindowInfo)native.WindowInfo, 1, 0, GraphicsContextFlags.Default))
|
||||
// See http://www.opengl.org/registry/specs/ARB/wgl_pixel_format.txt
|
||||
// for more details
|
||||
Debug.Write("Retrieving ARB pixel formats.... ");
|
||||
if (Wgl.Delegates.wglChoosePixelFormatARB == null || Wgl.Delegates.wglGetPixelFormatAttribivARB == null)
|
||||
{
|
||||
WinWindowInfo window = (WinWindowInfo)native.WindowInfo;
|
||||
Debug.WriteLine("failed.");
|
||||
yield break;
|
||||
}
|
||||
|
||||
// See http://www.opengl.org/registry/specs/ARB/wgl_pixel_format.txt
|
||||
// for more details
|
||||
Debug.Write("Retrieving ARB pixel formats.... ");
|
||||
if (Wgl.Delegates.wglChoosePixelFormatARB == null || Wgl.Delegates.wglGetPixelFormatAttribivARB == null)
|
||||
{
|
||||
Debug.WriteLine("failed.");
|
||||
yield break;
|
||||
}
|
||||
int[] attribs = new int[]
|
||||
{
|
||||
(int)WGL_ARB_pixel_format.AccelerationArb,
|
||||
|
||||
int[] attribs = new int[]
|
||||
{
|
||||
(int)WGL_ARB_pixel_format.AccelerationArb,
|
||||
|
||||
(int)WGL_ARB_pixel_format.RedBitsArb,
|
||||
(int)WGL_ARB_pixel_format.GreenBitsArb,
|
||||
(int)WGL_ARB_pixel_format.BlueBitsArb,
|
||||
(int)WGL_ARB_pixel_format.AlphaBitsArb,
|
||||
(int)WGL_ARB_pixel_format.ColorBitsArb,
|
||||
(int)WGL_ARB_pixel_format.RedBitsArb,
|
||||
(int)WGL_ARB_pixel_format.GreenBitsArb,
|
||||
(int)WGL_ARB_pixel_format.BlueBitsArb,
|
||||
(int)WGL_ARB_pixel_format.AlphaBitsArb,
|
||||
(int)WGL_ARB_pixel_format.ColorBitsArb,
|
||||
|
||||
(int)WGL_ARB_pixel_format.DepthBitsArb,
|
||||
(int)WGL_ARB_pixel_format.StencilBitsArb,
|
||||
(int)WGL_ARB_pixel_format.DepthBitsArb,
|
||||
(int)WGL_ARB_pixel_format.StencilBitsArb,
|
||||
|
||||
(int)WGL_ARB_multisample.SampleBuffersArb,
|
||||
(int)WGL_ARB_multisample.SamplesArb,
|
||||
(int)WGL_ARB_multisample.SampleBuffersArb,
|
||||
(int)WGL_ARB_multisample.SamplesArb,
|
||||
|
||||
(int)WGL_ARB_pixel_format.AccumRedBitsArb,
|
||||
(int)WGL_ARB_pixel_format.AccumGreenBitsArb,
|
||||
(int)WGL_ARB_pixel_format.AccumBlueBitsArb,
|
||||
(int)WGL_ARB_pixel_format.AccumAlphaBitsArb,
|
||||
(int)WGL_ARB_pixel_format.AccumBitsArb,
|
||||
(int)WGL_ARB_pixel_format.AccumRedBitsArb,
|
||||
(int)WGL_ARB_pixel_format.AccumGreenBitsArb,
|
||||
(int)WGL_ARB_pixel_format.AccumBlueBitsArb,
|
||||
(int)WGL_ARB_pixel_format.AccumAlphaBitsArb,
|
||||
(int)WGL_ARB_pixel_format.AccumBitsArb,
|
||||
|
||||
(int)WGL_ARB_pixel_format.DoubleBufferArb,
|
||||
(int)WGL_ARB_pixel_format.StereoArb,
|
||||
0
|
||||
};
|
||||
(int)WGL_ARB_pixel_format.DoubleBufferArb,
|
||||
(int)WGL_ARB_pixel_format.StereoArb,
|
||||
0
|
||||
};
|
||||
|
||||
int[] values = new int[attribs.Length];
|
||||
int[] values = new int[attribs.Length];
|
||||
|
||||
int[] attribs_values = new int[]
|
||||
int[] attribs_values = new int[]
|
||||
{
|
||||
(int)WGL_ARB_pixel_format.AccelerationArb,
|
||||
(int)WGL_ARB_pixel_format.FullAccelerationArb,
|
||||
(int)WGL_ARB_pixel_format.SupportOpenglArb, 1,
|
||||
(int)WGL_ARB_pixel_format.DrawToWindowArb, 1,
|
||||
0, 0
|
||||
};
|
||||
|
||||
int[] num_formats = new int[1];
|
||||
// Get the number of available formats
|
||||
if (Wgl.Arb.ChoosePixelFormat(device, attribs_values, null, 0, null, num_formats))
|
||||
{
|
||||
// Create an array big enough to hold all available formats and get those formats
|
||||
int[] pixel = new int[num_formats[0]];
|
||||
|
||||
if (Wgl.Arb.ChoosePixelFormat(device, attribs_values, null, pixel.Length, pixel, num_formats))
|
||||
{
|
||||
(int)WGL_ARB_pixel_format.AccelerationArb,
|
||||
(int)WGL_ARB_pixel_format.FullAccelerationArb,
|
||||
(int)WGL_ARB_pixel_format.SupportOpenglArb, 1,
|
||||
(int)WGL_ARB_pixel_format.DrawToWindowArb, 1,
|
||||
0, 0
|
||||
};
|
||||
|
||||
int[] num_formats = new int[1];
|
||||
// Get the number of available formats
|
||||
if (Wgl.Arb.ChoosePixelFormat(window.DeviceContext, attribs_values, null, 0, null, num_formats))
|
||||
{
|
||||
// Create an array big enough to hold all available formats and get those formats
|
||||
int[] pixel = new int[num_formats[0]];
|
||||
|
||||
if (Wgl.Arb.ChoosePixelFormat(window.DeviceContext, attribs_values, null, pixel.Length, pixel, num_formats))
|
||||
foreach (int p in pixel)
|
||||
{
|
||||
foreach (int p in pixel)
|
||||
// Find out what we really got as a format:
|
||||
if (!Wgl.Arb.GetPixelFormatAttrib(device, p, 0, attribs.Length - 1, attribs, values))
|
||||
{
|
||||
// Find out what we really got as a format:
|
||||
if (!Wgl.Arb.GetPixelFormatAttrib(window.DeviceContext, p, 0, attribs.Length - 1, attribs, values))
|
||||
{
|
||||
Debug.Print("[Warning] Failed to detect attributes for PixelFormat:{0}.", p);
|
||||
continue;
|
||||
}
|
||||
|
||||
GraphicsMode mode = new GraphicsMode(new IntPtr(p),
|
||||
new ColorFormat(values[1], values[2], values[3], values[4]),
|
||||
values[6],
|
||||
values[7],
|
||||
values[8] != 0 ? values[9] : 0,
|
||||
new ColorFormat(values[10], values[11], values[12], values[13]),
|
||||
values[15] == 1 ? 2 : 1,
|
||||
values[16] == 1 ? true : false);
|
||||
|
||||
yield return mode;
|
||||
Debug.Print("[Warning] Failed to detect attributes for PixelFormat:{0}.", p);
|
||||
continue;
|
||||
}
|
||||
|
||||
GraphicsMode mode = new GraphicsMode(new IntPtr(p),
|
||||
new ColorFormat(values[1], values[2], values[3], values[4]),
|
||||
values[6],
|
||||
values[7],
|
||||
values[8] != 0 ? values[9] : 0,
|
||||
new ColorFormat(values[10], values[11], values[12], values[13]),
|
||||
values[15] == 1 ? 2 : 1,
|
||||
values[16] == 1 ? true : false);
|
||||
|
||||
yield return mode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue