I have been using OpenTK to create OpenGL contexts on various Windows configurations (7, 8, 8.1, 10) and hardware (various AMD, nvidia GPUs and intel's graphics chipsets) without problem for more than 2 years.
But since nvidia's 375.63 driver update and all subsequent driver updates (even the latest 378.49 released yesterday), when I try to create an OpenGL context using OpenTK, I end up with an OpenGL 1.1.0 context (vendor : Microsoft Corporation, renderer : GDI generic). That looks like a "fallback" OpenGL context which of course lacks most OpenGL functions I need.
Rolling back to 373.06 or older solves the problem but is not a long term viable solution.
I have started digging into the OpenTK code to narrow the problem. The context is created using a wrapper around
Delegates.wglCreateContextAttribsARB((IntPtr)hDC, (IntPtr)hShareContext, (int*)attribList_ptr);
This delegate is loaded using the GetProcAddress function :
[System.Runtime.InteropServices.DllImport(Wgl.Library, EntryPoint = "wglGetProcAddress", ExactSpelling = true, SetLastError = true)]
internal extern static IntPtr GetProcAddress(String lpszProc);
Where Wgl.Library is "OPENGL32.dll". The function is loaded correctly.
The attributes passed are just GL_MAJOR = 1 GL_MINOR = 0 which should (and always have) return the latest supported OpenGL context. I have also tried to force these values to 4 and 5 respectively without success.
The specs of wglCreateContextAttribsARB does not mention any "fall back" context. (Note : wglCreateContextAttribsARB is supported by my graphics card)
Any help or clues are welcome. I can elaborate on some specific point if needed.
It seems that the way to get pixel modes is the source of the problem. The initilization steps try to retrieve the ARB modes which uses the wglChoosePixelFormatARB
function, and gets 0 valid modes with the new drivers.
Here is the relevant part of the code chunk. (Wgl.Arb.ChoosePixelFormat
is wrapper around wglChoosePixelFormatARB
)
...
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.DepthBitsArb,
(int)WGL_ARB_pixel_format.StencilBitsArb,
(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.DoubleBufferArb,
(int)WGL_ARB_pixel_format.StereoArb,
0
};
int[] values = new int[attribs.Length];
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(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]];
//result differ here from one driver to the other :
//373.06 => num_formats[0] is 66
//378.49 => num_formats[0] is 0
if (Wgl.Arb.ChoosePixelFormat(window.DeviceContext, attribs_values, null, pixel.Length, pixel, num_formats))
{
//for loop to fetch all the modes
}
}
...
As you can see num_formats[0]
, returns 0 valid formats for the new driver version. From here I guess the most likely possibilities are either that the given flags are not correct anymore or that there is some bug in the wglChoosePixelFormatARB
function.
It turns out that the OpenTK code of the codebase I am working on is not up to date. And the code chunk I have posted above is outdated. It actually looks like the code comes from the mono/opentk repo (the exact code chunk is here). I have looked into ARB extensions loading functions of version 2.0-0 (tag), they change a lot (code here).
I tested with version 2.0-0 and that fixes the problem.
Thanks to Robert Rouhani for pointing out that this was an old issue.