Problem Description
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.
Observations
- I have carefully read nvidia's released notes but did not find any issue or remark related to that problem.
- I doubt that the pixel format initialized by the handle created by OpenTK suddenly became unsupported by nvidia's drivers. (I can provide details if needed)
- I have tried some sample C++ code using glfw and I can get a correct OpenGL context (version : 4.5.0, vendor : nvidia), thus it doesn't seem to be a low level driver problem but rather the way the context is created that is somehow broken.
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)
Questions
- Did anybody encounter a similar issue while creating an OpenGL context, and how did you address it ?
- What could possibly have changed between the 2 driver versions that would break this ?
Any help or clues are welcome. I can elaborate on some specific point if needed.
Update (26.1.2017)
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.