Merge pull request #262 from DanielGibson/fix-win-msaa-crash

Fix crash on Windows if MSAA is set to a value the driver doesn't support
This commit is contained in:
Yamagi 2017-12-02 16:38:26 +01:00 committed by GitHub
commit 44da2aca3b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 76 additions and 20 deletions

View file

@ -185,11 +185,18 @@ VID_CheckChanges(void)
cls.disable_screen = true;
// Proceed to reboot the refresher
if(!VID_LoadRefresh() && (strcmp(vid_renderer->string, "gl1") != 0))
if(!VID_LoadRefresh())
{
Com_Printf("\n ... trying again with standard OpenGL1.x renderer ... \n\n");
Cvar_Set("vid_renderer", "gl1");
VID_LoadRefresh();
if (strcmp(vid_renderer->string, "gl1") != 0)
{
Com_Printf("\n ... trying again with standard OpenGL1.x renderer ... \n\n");
Cvar_Set("vid_renderer", "gl1");
VID_LoadRefresh();
}
else
{
Com_Error(ERR_FATAL, "Couldn't load a rendering backend!\n");
}
}
cls.disable_screen = false;
}

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)