2
votes

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.

2
If they returned the latest version when you asked for 1.0 then the bug was previous and now has been corrected, you must request the correct major/minor versions, the one your application targets.Gusman
As mentioned, I tried to set major and minor to 4 and 5 respectively to get an OpenGL 4.5 context, but without result.Wasabi
Maybe if you add the code where you create or request the context it will be easier to see if there is a problem. Also, you're using the functiuons at OpenTK.Graphics.OpenGL4, yes?Gusman

2 Answers

2
votes

It looks like it just can't find the NVIDIA OpenGL context and is falling back to the ancient one that ships with Windows and hasn't been updated in over a decade.

The only thing I managed to find was this old issue on the OpenTK repo. It should be fixed in any recent version of OpenTK, but the problem could have surfaced again.

It looks like you've done a lot to isolate the problem and make it reproducible. It wouldn't be out of the question to open up a pull request with OpenTK for this. It's possible that OpenTK is scanning for and invoking wglCreateContextAttribsARB in a different way than GLFW.

If you can take a peek at and compare the GLFW and OpenTK context initialization, the problem may present itself there.

1
votes

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).

Bottom line

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.