-
Notifications
You must be signed in to change notification settings - Fork 162
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
OpenGL Functions Unloaded/Crash #200
Comments
Ok, so through more debugging I have narrowed this problem down to two issues. Calling GL Functions in Stack Destructor CrashesWe have several classes in our engine that handle cleaning up the OpenGL objects in their destructors. We may change this but regardless I want to document it for the libepoxy users. If you have a stack allocated object whose destructor is called when the program closes, then libepoxy will have already unloaded the OpenGL function pointers. This means if you call an OpenGL function in your destructor, you will be met with the same crash as me. ~SamplerState() {
glDeleteSamplers(1, &sampler_index);
} Following a Stack Overflow post, I was able to get a full stack trace which helped me figure this out.
Simply including <epoxy/wgl.h> crashes on closeI don't know if this header has anything stack allocated? Regardless, its presence in the source seems to result in a crash on
|
I want to add that I think it's possibly something to consider that libepoxy could maybe have a custom exit handler to allow calling OpenGL functions in destructors safely. The following VirtualBox mailing post pontificates on this. |
@anholt is perhaps the second wgl.h issue because there's no NULL checking in Line 76 in d536f78
void DisableDrawing(void*)
{
wglMakeCurrent(NULL, NULL);
wglDeleteContext(hRC);
ReleaseDC(enigma::hWnd, enigma::window_hDC);
} |
@ebassi might you have an idea about this crash? |
I've now discovered just the following will crash on the second line with the same crash log. wglMakeCurrent(enigma::window_hDC, LegacyRC);
wglMakeCurrent(NULL,NULL); |
I meet the similar problem when I was cross-compiling libepoxy testcases statically(!) using mingw-w64, and was able to detect and fix the problem to get the testcases running under a special case. The problem: libepoxy assumes shared-linking on Win32.The problem can be easily traced to (generated) void
gl_init_dispatch_table(void)
{
struct dispatch_table *dispatch_table = get_dispatch_table();
memcpy(dispatch_table, &resolver_table, sizeof(resolver_table));
} is The TLS is only initialized in BOOL WINAPI
DllMain(HINSTANCE dll, DWORD reason, LPVOID reserved)
{
void *data;
switch (reason) {
case DLL_PROCESS_ATTACH:
gl_tls_index = TlsAlloc();
if (gl_tls_index == TLS_OUT_OF_INDEXES)
return FALSE;
wgl_tls_index = TlsAlloc();
if (wgl_tls_index == TLS_OUT_OF_INDEXES)
return FALSE;
first_context_current = false;
/* FALLTHROUGH */
case DLL_THREAD_ATTACH:
data = LocalAlloc(LPTR, gl_tls_size);
TlsSetValue(gl_tls_index, data);
data = LocalAlloc(LPTR, wgl_tls_size);
TlsSetValue(wgl_tls_index, data);
break;
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
data = TlsGetValue(gl_tls_index);
LocalFree(data);
data = TlsGetValue(wgl_tls_index);
LocalFree(data);
if (reason == DLL_PROCESS_DETACH) {
TlsFree(gl_tls_index);
TlsFree(wgl_tls_index);
}
break;
}
return TRUE;
} However, the A patch, but on POSIX thread modelFortunately what the DllMain handles is simple: initializing TLS for every thread. I have not yet think of a method to patch it on Win32 thread model, but this is exactly what #ifdef WIN32_POSIX_PATCH
__thread struct dispatch_table gl_tls_table;
#else
uint32_t gl_tls_index;
uint32_t gl_tls_size = sizeof(struct dispatch_table);
#endif
static inline struct dispatch_table *
get_dispatch_table(void)
{
#ifdef WIN32_POSIX_PATCH
return &gl_tls_table;
#else
return TlsGetValue(gl_tls_index);
#endif After this patching as well as enabling the macro This patch is enough for my use since my project is right working on the POSIX thread model. Hopefully I will try to add more stuff (detecting POSIX thread model, for example, testing whether |
Not yet completely tested but there is a crash on Windows and it should be solved by this patch. Based on: anholt/libepoxy#200 anholt/libepoxy#265
Hello, our project, a game engine, is investigating switching our glew dependency to libepoxy so that we can simplify context creation and support OpenGL ES. We use a bridging system so the user can select from the GUI whether to use SDL or raw native Win32/XLIB for the window. I've had relatively great success switching our bridges over to using libepoxy instead of glew.
enigma-dev/enigma-dev#1602
Now, I've run into an issue with bridging Win32 or SDL with OpenGL 3.3 core. I am compiling with MSYS2 64 bit and I seem to be getting a crash in
wglMakeCurrent(NULL,NULL);
when I close the window (negative return code). I don't get it with the same setup with OpenGL1 and get a successful 0 exit code. My context deletion code is the same for GL1 and GL3 because the bridges are capable of sharing source code.In the case of SDL, all I do is call
SDL_GL_DeleteContext(context);
:https://github.com/enigma-dev/enigma-dev/blob/2cc99695e0929a2ca84becdac62acc36b18f6619/ENIGMAsystem/SHELL/Bridges/SDL-OpenGL/graphics_bridge.cpp#L47
In the case of Win32, I use the same context deletion as your tests:
https://github.com/enigma-dev/enigma-dev/blob/2cc99695e0929a2ca84becdac62acc36b18f6619/ENIGMAsystem/SHELL/Bridges/Win32-OpenGL/graphics_bridge.cpp#L35
Yet, alas, I get this stack trace when closing the window if my context is a core 3.3 context:
The text was updated successfully, but these errors were encountered: