Recreate GL context on renderer swap

Restores renderer swapping to legacy GL
This commit is contained in:
Eidolon 2023-03-07 17:57:50 -06:00
parent 216e4064dc
commit 17c1e69ed5
3 changed files with 48 additions and 64 deletions

View file

@ -1468,6 +1468,11 @@ void VID_PrepareModeList(void)
static void init_imgui() static void init_imgui()
{ {
if (ImGui::GetCurrentContext() != NULL)
{
return;
}
ImGui::CreateContext(); ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io; ImGuiIO& io = ImGui::GetIO(); (void)io;
io.IniFilename = NULL; io.IniFilename = NULL;
@ -1488,22 +1493,27 @@ static SDL_bool Impl_CreateContext(void)
#ifdef HWRENDER #ifdef HWRENDER
if (rendermode == render_opengl) if (rendermode == render_opengl)
{ {
if (!sdlglcontext) if (!g_legacy_gl_context)
sdlglcontext = SDL_GL_CreateContext(window); {
if (sdlglcontext == NULL) SDL_GL_ResetAttributes();
g_legacy_gl_context = SDL_GL_CreateContext(window);
}
if (g_legacy_gl_context == NULL)
{ {
SDL_DestroyWindow(window); 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(); init_imgui();
SDL_GL_MakeCurrent(window, sdlglcontext); SDL_GL_MakeCurrent(window, g_legacy_gl_context);
return SDL_TRUE; return SDL_TRUE;
} }
#endif #endif
// RHI always uses OpenGL 3.2 Core (for now) // RHI always uses OpenGL 3.2 Core (for now)
if (!sdlglcontext) if (!sdlglcontext)
{ {
SDL_GL_ResetAttributes();
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); 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_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
@ -1512,15 +1522,18 @@ static SDL_bool Impl_CreateContext(void)
if (sdlglcontext == NULL) if (sdlglcontext == NULL)
{ {
SDL_DestroyWindow(window); 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(); init_imgui();
SDL_GL_MakeCurrent(window, sdlglcontext); SDL_GL_MakeCurrent(window, sdlglcontext);
std::unique_ptr<rhi::SdlGlCorePlatform> platform = std::make_unique<rhi::SdlGlCorePlatform>(); if (!g_rhi)
platform->window = window; {
g_rhi = std::make_unique<rhi::GlCoreRhi>(std::move(platform), reinterpret_cast<rhi::GlLoadFunc>(SDL_GL_GetProcAddress)); std::unique_ptr<rhi::SdlGlCorePlatform> platform = std::make_unique<rhi::SdlGlCorePlatform>();
g_rhi_generation += 1; platform->window = window;
g_rhi = std::make_unique<rhi::GlCoreRhi>(std::move(platform), reinterpret_cast<rhi::GlLoadFunc>(SDL_GL_GetProcAddress));
g_rhi_generation += 1;
}
return SDL_TRUE; return SDL_TRUE;
} }
@ -1528,29 +1541,11 @@ static SDL_bool Impl_CreateContext(void)
void VID_CheckGLLoaded(rendermode_t oldrender) void VID_CheckGLLoaded(rendermode_t oldrender)
{ {
(void)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 VID_CheckRenderer(void)
{ {
boolean rendererchanged = false; boolean rendererchanged = false;
boolean contextcreated = false;
#ifdef HWRENDER
rendermode_t oldrenderer = rendermode;
#endif
if (dedicated) if (dedicated)
return false; return false;
@ -1560,41 +1555,20 @@ boolean VID_CheckRenderer(void)
rendermode = static_cast<rendermode_t>(setrenderneeded); rendermode = static_cast<rendermode_t>(setrenderneeded);
rendererchanged = true; rendererchanged = true;
#ifdef HWRENDER if (rendererchanged)
if (rendermode == render_opengl)
{ {
VID_CheckGLLoaded(oldrenderer); Impl_CreateContext();
#ifdef HWRENDER
// Initialise OpenGL before calling SDLSetMode!!! if (rendermode == render_opengl)
// This is because SDLSetMode calls OglSdlSurface.
if (vid.glstate == VID_GL_LIBRARY_NOTLOADED)
{ {
VID_StartupOpenGL(); VID_StartupOpenGL();
if (vid.glstate != VID_GL_LIBRARY_LOADED)
// Loaded successfully!
if (vid.glstate == VID_GL_LIBRARY_LOADED)
{ {
// Destroy the current window, if it exists. rendererchanged = false;
if (window)
{
SDL_DestroyWindow(window);
window = NULL;
}
// Create a new window.
Impl_CreateWindow(static_cast<SDL_bool>(USE_FULLSCREEN));
// From there, the OpenGL context was already created.
contextcreated = true;
} }
} }
else if (vid.glstate == VID_GL_LIBRARY_ERROR)
rendererchanged = false;
}
#endif #endif
}
if (!contextcreated)
Impl_CreateContext();
setrenderneeded = 0; setrenderneeded = 0;
} }
@ -1874,16 +1848,17 @@ void VID_StartupOpenGL(void)
*(void**)&HWD.pfnSetShaderInfo = hwSym("SetShaderInfo",NULL); *(void**)&HWD.pfnSetShaderInfo = hwSym("SetShaderInfo",NULL);
*(void**)&HWD.pfnLoadCustomShader = hwSym("LoadCustomShader",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; 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 #endif
} }

View file

@ -73,6 +73,7 @@ PFNglGetString pglGetString;
INT32 oglflags = 0; INT32 oglflags = 0;
void *GLUhandle = NULL; void *GLUhandle = NULL;
SDL_GLContext sdlglcontext = 0; SDL_GLContext sdlglcontext = 0;
SDL_GLContext g_legacy_gl_context = 0;
void *GetGLFunc(const char *proc) void *GetGLFunc(const char *proc)
{ {
@ -89,9 +90,15 @@ void *GetGLFunc(const char *proc)
boolean LoadGL(void) boolean LoadGL(void)
{ {
#ifndef STATIC_OPENGL #ifndef STATIC_OPENGL
static boolean loaded_libraries = false;
const char *OGLLibname = NULL; const char *OGLLibname = NULL;
const char *GLULibname = NULL; const char *GLULibname = NULL;
if (loaded_libraries)
{
return SetupGLfunc();
}
if (M_CheckParm("-OGLlib") && M_IsNextParm()) if (M_CheckParm("-OGLlib") && M_IsNextParm())
OGLLibname = M_GetNextParm(); OGLLibname = M_GetNextParm();
@ -140,6 +147,7 @@ boolean LoadGL(void)
CONS_Alert(CONS_ERROR, "Could not load GLU Library\n"); 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");; CONS_Printf("If you know what is the GLU library's name, use -GLUlib\n");;
} }
loaded_libraries = true;
#endif #endif
return SetupGLfunc(); return SetupGLfunc();
} }

View file

@ -35,6 +35,7 @@ boolean OglSdlSurface(INT32 w, INT32 h);
void OglSdlFinishUpdate(boolean vidwait); void OglSdlFinishUpdate(boolean vidwait);
extern SDL_GLContext sdlglcontext; extern SDL_GLContext sdlglcontext;
extern SDL_GLContext g_legacy_gl_context;
extern Uint16 realwidth; extern Uint16 realwidth;
extern Uint16 realheight; extern Uint16 realheight;