From 8d5bc9537a0faaa4f3c5768d024a5d9d4ff07299 Mon Sep 17 00:00:00 2001 From: Patryk Obara Date: Fri, 13 Mar 2020 19:36:25 +0100 Subject: [PATCH] Prevent a crash in Windows AMD drivers Usually, when window is being created without SDL_WINDOW_OPENGL flag, SDL2 internally re-creates it to support OpenGL during SDL_CreateRenderer if needed. This leads to crash in AMD OpenGL drivers (Windows only), which happens for drivers: "opengl", "opengles", "opengles2". When the window is created with correct flag from the get-go, the crash does not happen. On Linux, the code does not crash either way (at least not when using Mesa and AMDGPU open source driver), so there's no point in propagating the hack. Also, remove a comment that is no longer relevant to the code below. --- include/support.h | 5 +++++ src/gui/sdlmain.cpp | 19 +++++++++++-------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/include/support.h b/include/support.h index cadd6a41..3b109f5f 100644 --- a/include/support.h +++ b/include/support.h @@ -122,4 +122,9 @@ void upcase(std::string &str); void lowcase(std::string &str); void strip_punctuation(std::string &str); +template +bool starts_with(const char (& pfx)[N], const std::string &str) noexcept { + return (strncmp(pfx, str.c_str(), N) == 0); +} + #endif diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 42c69295..d92df23a 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -546,13 +546,16 @@ static SDL_Window * GFX_SetSDLWindowMode(Bit16u width, Bit16u height, bool fulls SDL_DestroyWindow(sdl.window); } - /* Don't create a fullscreen immediately. Reasons: - * 1. This theoretically allows us to set window resolution and - * then let SDL2 remember it for later (even if not actually done). - * 2. It's a bit less glitchy to set a custom display mode for a - * full screen, albeit it's still not perfect (at least on X11). - */ - const uint32_t flags = (screenType == SCREEN_OPENGL) ? SDL_WINDOW_OPENGL : 0; + uint32_t flags = 0; + if (screenType == SCREEN_OPENGL) + flags |= SDL_WINDOW_OPENGL; +#if defined (WIN32) + // This is a hack for Windows 10 to prevent a crash in AMD OpenGL + // driver when window is being re-created by SDL2 internally to + // support OpenGL. + else if (screenType == SCREEN_TEXTURE && starts_with("opengl", sdl.render_driver)) + flags |= SDL_WINDOW_OPENGL; +#endif // Using undefined position will take care of placing and restoring the // window by WM. @@ -1915,6 +1918,7 @@ static void GUI_StartUp(Section * sec) { sdl.texture.texture = 0; sdl.texture.pixelFormat = 0; sdl.render_driver = section->Get_string("texture_renderer"); + lowcase(sdl.render_driver); #if C_OPENGL if (sdl.desktop.want_type == SCREEN_OPENGL) { /* OPENGL is requested */ @@ -1983,7 +1987,6 @@ static void GUI_StartUp(Section * sec) { LOG_MSG("OpenGL extension: pixel_bufer_object %d",sdl.opengl.pixel_buffer_object); } } /* OPENGL is requested end */ - #endif //OPENGL if (!SetDefaultWindowMode())