From 17c1e69ed5b9eee06d7f3945a63591feb8fa11fb Mon Sep 17 00:00:00 2001 From: Eidolon Date: Tue, 7 Mar 2023 17:57:50 -0600 Subject: [PATCH] Recreate GL context on renderer swap Restores renderer swapping to legacy GL --- src/sdl/i_video.cpp | 103 +++++++++++++++++--------------------------- src/sdl/ogl_sdl.c | 8 ++++ src/sdl/ogl_sdl.h | 1 + 3 files changed, 48 insertions(+), 64 deletions(-) diff --git a/src/sdl/i_video.cpp b/src/sdl/i_video.cpp index d86f4a4b4..e57e8cd22 100644 --- a/src/sdl/i_video.cpp +++ b/src/sdl/i_video.cpp @@ -1468,6 +1468,11 @@ void VID_PrepareModeList(void) static void init_imgui() { + if (ImGui::GetCurrentContext() != NULL) + { + return; + } + ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; io.IniFilename = NULL; @@ -1488,22 +1493,27 @@ static SDL_bool Impl_CreateContext(void) #ifdef HWRENDER if (rendermode == render_opengl) { - if (!sdlglcontext) - sdlglcontext = SDL_GL_CreateContext(window); - if (sdlglcontext == NULL) + if (!g_legacy_gl_context) + { + SDL_GL_ResetAttributes(); + g_legacy_gl_context = SDL_GL_CreateContext(window); + } + if (g_legacy_gl_context == NULL) { SDL_DestroyWindow(window); - I_Error("Failed to create a GL context: %s\n", SDL_GetError()); + I_Error("Failed to create a Legacy GL context: %s\n", SDL_GetError()); } init_imgui(); - SDL_GL_MakeCurrent(window, sdlglcontext); + SDL_GL_MakeCurrent(window, g_legacy_gl_context); return SDL_TRUE; } #endif // RHI always uses OpenGL 3.2 Core (for now) + if (!sdlglcontext) { + SDL_GL_ResetAttributes(); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); @@ -1512,15 +1522,18 @@ static SDL_bool Impl_CreateContext(void) if (sdlglcontext == NULL) { SDL_DestroyWindow(window); - I_Error("Failed to create a GL context: %s\n", SDL_GetError()); + I_Error("Failed to create an RHI GL context: %s\n", SDL_GetError()); } init_imgui(); SDL_GL_MakeCurrent(window, sdlglcontext); - std::unique_ptr platform = std::make_unique(); - platform->window = window; - g_rhi = std::make_unique(std::move(platform), reinterpret_cast(SDL_GL_GetProcAddress)); - g_rhi_generation += 1; + if (!g_rhi) + { + std::unique_ptr platform = std::make_unique(); + platform->window = window; + g_rhi = std::make_unique(std::move(platform), reinterpret_cast(SDL_GL_GetProcAddress)); + g_rhi_generation += 1; + } return SDL_TRUE; } @@ -1528,29 +1541,11 @@ static SDL_bool Impl_CreateContext(void) void VID_CheckGLLoaded(rendermode_t oldrender) { (void)oldrender; -#ifdef HWRENDER - if (vid.glstate == VID_GL_LIBRARY_ERROR) // Well, it didn't work the first time anyway. - { - CONS_Alert(CONS_ERROR, "OpenGL never loaded\n"); - rendermode = oldrender; - if (chosenrendermode == render_opengl) // fallback to software - rendermode = render_soft; - if (setrenderneeded) - { - CV_StealthSetValue(&cv_renderer, oldrender); - setrenderneeded = 0; - } - } -#endif } boolean VID_CheckRenderer(void) { boolean rendererchanged = false; - boolean contextcreated = false; -#ifdef HWRENDER - rendermode_t oldrenderer = rendermode; -#endif if (dedicated) return false; @@ -1560,41 +1555,20 @@ boolean VID_CheckRenderer(void) rendermode = static_cast(setrenderneeded); rendererchanged = true; -#ifdef HWRENDER - if (rendermode == render_opengl) + if (rendererchanged) { - VID_CheckGLLoaded(oldrenderer); - - // Initialise OpenGL before calling SDLSetMode!!! - // This is because SDLSetMode calls OglSdlSurface. - if (vid.glstate == VID_GL_LIBRARY_NOTLOADED) + Impl_CreateContext(); +#ifdef HWRENDER + if (rendermode == render_opengl) { VID_StartupOpenGL(); - - // Loaded successfully! - if (vid.glstate == VID_GL_LIBRARY_LOADED) + if (vid.glstate != VID_GL_LIBRARY_LOADED) { - // Destroy the current window, if it exists. - if (window) - { - SDL_DestroyWindow(window); - window = NULL; - } - - // Create a new window. - Impl_CreateWindow(static_cast(USE_FULLSCREEN)); - - // From there, the OpenGL context was already created. - contextcreated = true; + rendererchanged = false; } } - else if (vid.glstate == VID_GL_LIBRARY_ERROR) - rendererchanged = false; - } #endif - - if (!contextcreated) - Impl_CreateContext(); + } setrenderneeded = 0; } @@ -1874,16 +1848,17 @@ void VID_StartupOpenGL(void) *(void**)&HWD.pfnSetShaderInfo = hwSym("SetShaderInfo",NULL); *(void**)&HWD.pfnLoadCustomShader = hwSym("LoadCustomShader",NULL); - - vid.glstate = HWD.pfnInit() ? VID_GL_LIBRARY_LOADED : VID_GL_LIBRARY_ERROR; // let load the OpenGL library - - if (vid.glstate == VID_GL_LIBRARY_ERROR) - { - rendermode = render_soft; - setrenderneeded = 0; - } glstartup = true; } + + // For RHI-Legacy GL compatibility: Init always fetches GL functions, but only dlsym's libraries once. + vid.glstate = HWD.pfnInit() ? VID_GL_LIBRARY_LOADED : VID_GL_LIBRARY_ERROR; // let load the OpenGL library + + if (vid.glstate == VID_GL_LIBRARY_ERROR) + { + rendermode = render_soft; + setrenderneeded = 0; + } #endif } diff --git a/src/sdl/ogl_sdl.c b/src/sdl/ogl_sdl.c index f93dc11f8..9ea94682a 100644 --- a/src/sdl/ogl_sdl.c +++ b/src/sdl/ogl_sdl.c @@ -73,6 +73,7 @@ PFNglGetString pglGetString; INT32 oglflags = 0; void *GLUhandle = NULL; SDL_GLContext sdlglcontext = 0; +SDL_GLContext g_legacy_gl_context = 0; void *GetGLFunc(const char *proc) { @@ -89,9 +90,15 @@ void *GetGLFunc(const char *proc) boolean LoadGL(void) { #ifndef STATIC_OPENGL + static boolean loaded_libraries = false; const char *OGLLibname = NULL; const char *GLULibname = NULL; + if (loaded_libraries) + { + return SetupGLfunc(); + } + if (M_CheckParm("-OGLlib") && M_IsNextParm()) OGLLibname = M_GetNextParm(); @@ -140,6 +147,7 @@ boolean LoadGL(void) CONS_Alert(CONS_ERROR, "Could not load GLU Library\n"); CONS_Printf("If you know what is the GLU library's name, use -GLUlib\n");; } + loaded_libraries = true; #endif return SetupGLfunc(); } diff --git a/src/sdl/ogl_sdl.h b/src/sdl/ogl_sdl.h index 26cedf0ae..621ba51e9 100644 --- a/src/sdl/ogl_sdl.h +++ b/src/sdl/ogl_sdl.h @@ -35,6 +35,7 @@ boolean OglSdlSurface(INT32 w, INT32 h); void OglSdlFinishUpdate(boolean vidwait); extern SDL_GLContext sdlglcontext; +extern SDL_GLContext g_legacy_gl_context; extern Uint16 realwidth; extern Uint16 realheight;