From 7e82eb215c41820506ced8a4a6f7f5e2b5e5a873 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 9 Oct 2015 23:44:01 +0200 Subject: [PATCH] Platform: finally properly create core contexts in Sdl2Application. Mesa needs at least GL 3.1 to create core contexts and it creates context with highest possible version. Great. Requesting that on binary NV drivers will force the version to 3.1, which is, to say it mildly, useless. Thus, when binary NV drivers are detected, the core context is destroyed and we're starting over, requesting compatibility 2.1 context, which properly returns GL 4.5. Uhh. --- src/Magnum/Platform/Sdl2Application.cpp | 30 ++++++++++++++++++------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/Magnum/Platform/Sdl2Application.cpp b/src/Magnum/Platform/Sdl2Application.cpp index 9a5bfee57..e894682f7 100644 --- a/src/Magnum/Platform/Sdl2Application.cpp +++ b/src/Magnum/Platform/Sdl2Application.cpp @@ -25,6 +25,7 @@ #include "Sdl2Application.h" +#include #ifndef CORRADE_TARGET_EMSCRIPTEN #include #else @@ -135,16 +136,15 @@ bool Sdl2Application::tryCreateContext(const Configuration& configuration) { /* First try to create core context. This is needed mainly on OS X and Mesa, as support for recent OpenGL versions isn't implemented in compatibility contexts (which are the default). At least GL 3.2 is - needed on OSX, at least GL 3.0 is needed on Mesa. Bite the bullet - and try 3.0 also elsewhere. */ + needed on OSX, at least GL 3.1 is needed on Mesa. Bite the bullet + and try 3.1 also elsewhere. */ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); #ifdef CORRADE_TARGET_APPLE SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); #else - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); #endif SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); - #else /* For ES the major context version is compile-time constant */ #ifdef MAGNUM_TARGET_GLES3 @@ -173,10 +173,24 @@ bool Sdl2Application::tryCreateContext(const Configuration& configuration) { _glContext = SDL_GL_CreateContext(_window); #ifndef MAGNUM_TARGET_GLES - /* Fall back to (forward compatible) GL 2.1, if core context creation fails - and if version is not user-specified */ - if(configuration.version() == Version::None && !_glContext) { - Warning() << "Platform::Sdl2Application::tryCreateContext(): cannot create core context:" << SDL_GetError() << "(falling back to compatibility context)"; + /* Fall back to (forward compatible) GL 2.1, if version is not + user-specified and either core context creation fails or we are on + binary NVidia drivers on Linux/Windows. NVidia, instead of creating + forward-compatible context with highest available version, forces the + version to the one specified, which is completely useless behavior. */ + constexpr static const char nvidiaVendorString[] = "NVIDIA Corporation"; + if(configuration.version() == Version::None && (!_glContext + #ifndef CORRADE_TARGET_APPLE + || std::strncmp(reinterpret_cast(glGetString(GL_VENDOR)), nvidiaVendorString, sizeof(nvidiaVendorString)) == 0 + #endif + )) { + /* Don't print any warning when doing the NV workaround, because the + bug will be there probably forever */ + if(!_glContext) Warning() + << "Platform::Sdl2Application::tryCreateContext(): cannot create core context:" + << SDL_GetError() << "(falling back to compatibility context)"; + else SDL_GL_DeleteContext(_glContext); + SDL_DestroyWindow(_window); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);