If renderer init fails and MSAA is on, disable it and try again

For some fucking reason, if you set an unsupported
SDL_GL_MULTISAMPLESAMPLES value on Windows (at least Win10 with Intel GPU
drivers, there 16 is unsupported), creating the Window and OpenGL context
will succeed, but you'll get Microsofts stupid GDI OpenGL software
implementation that only supports OpenGL 1.1.
Before these fixes, the GL3 renderer would just crash and the GL1 renderer
would fail to load, which caused the game to run in the background:
No Window, no Input, but sound was playing..

Now this problem should be handled properly and if initialization fails,
the rendering backend will be considered not working, and it will
try the gl1 backend next, and if that also fails it'll give up and exit
the game.
This commit is contained in:
Daniel Gibson 2017-09-04 00:21:10 +02:00
parent 36ef1e6bb8
commit 0051c6b8d2
5 changed files with 65 additions and 16 deletions

View file

@ -232,6 +232,7 @@ static qboolean GetWindowSize(int* w, int* h)
return true;
}
static qboolean initSuccessful = false;
/*
* Initializes the OpenGL window
@ -257,7 +258,9 @@ GLimp_InitGraphics(int fullscreen, int *pwidth, int *pheight)
}
#endif
if (GetWindowSize(&curWidth, &curHeight) && (curWidth == width) && (curHeight == height))
// only do this if we already have a working window and fully initialized rendering backend
// (GLimp_InitGraphics() is also called when recovering if creating GL context fails or the one we got is unusable)
if (initSuccessful && GetWindowSize(&curWidth, &curHeight) && (curWidth == width) && (curHeight == height))
{
/* If we want fullscreen, but aren't */
if (fullscreen != IsFullscreen())
@ -319,20 +322,17 @@ GLimp_InitGraphics(int fullscreen, int *pwidth, int *pheight)
{
if (!CreateSDLWindow(flags, width, height))
{
if (flags & SDL_OPENGL)
if((flags & SDL_OPENGL) && gl_msaa_samples->value)
{
if (gl_msaa_samples->value)
{
Com_Printf("SDL SetVideoMode failed: %s\n", SDL_GetError());
Com_Printf("Reverting to %s gl_mode %i (%ix%i) without MSAA.\n",
(flags & fs_flag) ? "fullscreen" : "windowed",
(int) Cvar_VariableValue("gl_mode"), width, height);
Com_Printf("SDL SetVideoMode failed: %s\n", SDL_GetError());
Com_Printf("Reverting to %s gl_mode %i (%ix%i) without MSAA.\n",
(flags & fs_flag) ? "fullscreen" : "windowed",
(int) Cvar_VariableValue("gl_mode"), width, height);
/* Try to recover */
Cvar_SetValue("gl_msaa_samples", 0);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
}
/* Try to recover */
Cvar_SetValue("gl_msaa_samples", 0);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
}
else if (width != 640 || height != 480 || (flags & fs_flag))
{
@ -374,6 +374,8 @@ GLimp_InitGraphics(int fullscreen, int *pwidth, int *pheight)
/* No cursor */
SDL_ShowCursor(0);
initSuccessful = true;
return true;
}
@ -453,6 +455,8 @@ VID_ShutdownWindow(void)
// make sure that after vid_restart the refreshrate will be queried from SDL2 again.
glimp_refreshRate = -1;
initSuccessful = false; // not initialized anymore
if (SDL_WasInit(SDL_INIT_EVERYTHING) == SDL_INIT_VIDEO)
{
SDL_Quit();

View file

@ -1344,6 +1344,17 @@ R_SetMode(void)
else if (err == rserr_invalid_mode)
{
R_Printf(PRINT_ALL, "ref_gl::R_SetMode() - invalid mode\n");
if (gl_msaa_samples->value != 0.0f)
{
R_Printf(PRINT_ALL, "gl_msaa_samples was %d - will try again with gl_msaa_samples = 0\n", (int)gl_msaa_samples->value);
ri.Cvar_SetValue("gl_msaa_samples", 0.0f);
gl_msaa_samples->modified = false;
if ((err = SetMode_impl(&vid.width, &vid.height, gl_mode->value, 0)) == rserr_ok)
{
return true;
}
}
if(gl_mode->value == gl_state.prev_mode)
{
// trying again would result in a crash anyway, give up already

View file

@ -360,6 +360,11 @@ int RI_PrepareForWindow(void)
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
}
}
else
{
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
}
/* Initiate the flags */
#if SDL_VERSION_ATLEAST(2, 0, 0)
@ -410,6 +415,14 @@ int RI_InitContext(void* win)
#endif
const char* glver = (char *)glGetString(GL_VERSION);
sscanf(glver, "%d.%d", &gl_config.major_version, &gl_config.minor_version);
if (gl_config.major_version < 1 || (gl_config.major_version == 1 && gl_config.minor_version < 4))
{
R_Printf(PRINT_ALL, "R_InitContext(): Got an OpenGL version %d.%d context - need (at least) 1.4!\n", gl_config.major_version, gl_config.minor_version);
return false;
}
if (gl_msaa_samples->value)
{
if (SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &msaa_samples) == 0)

View file

@ -406,6 +406,17 @@ GL3_SetMode(void)
{
R_Printf(PRINT_ALL, "ref_gl3::GL3_SetMode() - invalid mode\n");
if (gl_msaa_samples->value != 0.0f)
{
R_Printf(PRINT_ALL, "gl_msaa_samples was %d - will try again with gl_msaa_samples = 0\n", (int)gl_msaa_samples->value);
ri.Cvar_SetValue("gl_msaa_samples", 0.0f);
gl_msaa_samples->modified = false;
if ((err = SetMode_impl(&vid.width, &vid.height, gl_mode->value, 0)) == rserr_ok)
{
return true;
}
}
if(gl_mode->value == gl3state.prev_mode)
{
// trying again would result in a crash anyway, give up already

View file

@ -113,6 +113,11 @@ int GL3_PrepareForWindow(void)
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
}
}
else
{
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
}
/* Initiate the flags */
#if SDL_VERSION_ATLEAST(2, 0, 0)
@ -131,7 +136,7 @@ enum {
QGL_DEBUG_SEVERITY_NOTIFICATION = 0x826B
};
static void
static void APIENTRY
DebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length,
const GLchar *message, const void *userParam)
{
@ -230,12 +235,17 @@ int GL3_InitContext(void* win)
if(!gladLoadGLLoader(SDL_GL_GetProcAddress))
{
R_Printf(PRINT_ALL, "R_InitContext(): loading OpenGL function pointers failed!\n");
R_Printf(PRINT_ALL, "GL3_InitContext(): ERROR: loading OpenGL function pointers failed!\n");
return false;
}
else if (GLVersion.major < 3 || (GLVersion.major == 3 && GLVersion.minor < 2))
{
R_Printf(PRINT_ALL, "GL3_InitContext(): ERROR: glad only got GL version %d.%d!\n", GLVersion.major, GLVersion.minor);
return false;
}
else
{
R_Printf(PRINT_ALL, "Successfully loaded OpenGL function pointers using glad!\n");
R_Printf(PRINT_ALL, "Successfully loaded OpenGL function pointers using glad, got version %d.%d!\n", GLVersion.major, GLVersion.minor);
}
#if SDL_VERSION_ATLEAST(2, 0, 0)