From ff62dbaa72305d5284a0d1c93113753912fd59f6 Mon Sep 17 00:00:00 2001 From: baldurk Date: Tue, 20 Sep 2016 12:02:55 +0200 Subject: [PATCH] During replay, make sure calls to exported GL functions work. Refs #366 * These functions are intended only for hooking via LD_PRELOAD, but they will also be picked up by any replay application calling into GL. We need to make sure then that the real function pointer is fetched in time to be able to call it. --- renderdoc/driver/gl/gl_hooks_linux.cpp | 57 ++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/renderdoc/driver/gl/gl_hooks_linux.cpp b/renderdoc/driver/gl/gl_hooks_linux.cpp index b831b49a2..f52b44f23 100644 --- a/renderdoc/driver/gl/gl_hooks_linux.cpp +++ b/renderdoc/driver/gl/gl_hooks_linux.cpp @@ -464,6 +464,15 @@ public: return GL; } + void SetupExportedFunctions() + { + // in the replay application we need to call SetupHooks to ensure that all of our exported + // functions like glXCreateContext etc have the 'real' pointers to call into, otherwise even the + // replay app will resolve to our hooks first before the real libGL and call in. + if(RenderDoc::Inst().IsReplayApp()) + SetupHooks(GL); + } + void MakeContextCurrent(GLWindowingData data) { if(glXMakeCurrent_real) @@ -869,6 +878,9 @@ DefineUnsupportedDummies(); __attribute__((visibility("default"))) GLXContext glXCreateContext(Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct) { + if(OpenGLHook::glhooks.glXCreateContext_real == NULL) + OpenGLHook::glhooks.SetupExportedFunctions(); + GLXContext ret = OpenGLHook::glhooks.glXCreateContext_real(dpy, vis, shareList, direct); // don't continue if context creation failed @@ -909,6 +921,9 @@ __attribute__((visibility("default"))) GLXContext glXCreateContext(Display *dpy, __attribute__((visibility("default"))) void glXDestroyContext(Display *dpy, GLXContext ctx) { + if(OpenGLHook::glhooks.glXDestroyContext_real == NULL) + OpenGLHook::glhooks.SetupExportedFunctions(); + OpenGLHook::glhooks.GetDriver()->DeleteContext(ctx); OpenGLHook::glhooks.glXDestroyContext_real(dpy, ctx); @@ -974,6 +989,9 @@ __attribute__((visibility("default"))) GLXContext glXCreateContextAttribsARB( a += 2; } + if(OpenGLHook::glhooks.glXCreateContextAttribsARB_real == NULL) + OpenGLHook::glhooks.SetupExportedFunctions(); + GLXContext ret = OpenGLHook::glhooks.glXCreateContextAttribsARB_real(dpy, config, shareList, direct, attribs); @@ -1020,6 +1038,9 @@ __attribute__((visibility("default"))) GLXContext glXCreateContextAttribsARB( __attribute__((visibility("default"))) Bool glXMakeCurrent(Display *dpy, GLXDrawable drawable, GLXContext ctx) { + if(OpenGLHook::glhooks.glXMakeCurrent_real == NULL) + OpenGLHook::glhooks.SetupExportedFunctions(); + Bool ret = OpenGLHook::glhooks.glXMakeCurrent_real(dpy, drawable, ctx); if(ctx && OpenGLHook::glhooks.m_Contexts.find(ctx) == OpenGLHook::glhooks.m_Contexts.end()) @@ -1041,6 +1062,9 @@ __attribute__((visibility("default"))) Bool glXMakeCurrent(Display *dpy, GLXDraw __attribute__((visibility("default"))) void glXSwapBuffers(Display *dpy, GLXDrawable drawable) { + if(OpenGLHook::glhooks.glXSwapBuffers_real == NULL) + OpenGLHook::glhooks.SetupExportedFunctions(); + // if we use the GLXDrawable in XGetGeometry and it's a GLXWindow, then we get // a BadDrawable error and things go south. Instead we track GLXWindows created // in glXCreateWindow/glXDestroyWindow and look up the source window it was @@ -1111,6 +1135,9 @@ bool OpenGLHook::SetupHooks(GLHookSet &GL) __attribute__((visibility("default"))) __GLXextFuncPtr glXGetProcAddress(const GLubyte *f) { + if(OpenGLHook::glhooks.glXGetProcAddress_real == NULL) + OpenGLHook::glhooks.SetupExportedFunctions(); + __GLXextFuncPtr realFunc = OpenGLHook::glhooks.glXGetProcAddress_real(f); const char *func = (const char *)f; @@ -1174,6 +1201,9 @@ __attribute__((visibility("default"))) __GLXextFuncPtr glXGetProcAddressARB(cons __attribute__((visibility("default"))) GLXWindow glXCreateWindow(Display *dpy, GLXFBConfig config, Window win, const int *attribList) { + if(OpenGLHook::glhooks.glXCreateWindow_real == NULL) + OpenGLHook::glhooks.SetupExportedFunctions(); + GLXWindow ret = OpenGLHook::glhooks.glXCreateWindow_real(dpy, config, win, attribList); OpenGLHook::glhooks.AddGLXWindow(ret, win); @@ -1183,6 +1213,9 @@ __attribute__((visibility("default"))) GLXWindow glXCreateWindow(Display *dpy, G __attribute__((visibility("default"))) void glXDestroyWindow(Display *dpy, GLXWindow window) { + if(OpenGLHook::glhooks.glXDestroyWindow_real == NULL) + OpenGLHook::glhooks.SetupExportedFunctions(); + OpenGLHook::glhooks.RemoveGLXWindow(window); return OpenGLHook::glhooks.glXDestroyWindow_real(dpy, window); @@ -1195,45 +1228,69 @@ __attribute__((visibility("default"))) void glXDestroyWindow(Display *dpy, GLXWi __attribute__((visibility("default"))) Bool glXQueryExtension(Display *dpy, int *errorBase, int *eventBase) { + if(OpenGLHook::glhooks.glXQueryExtension_real == NULL) + OpenGLHook::glhooks.SetupExportedFunctions(); + return OpenGLHook::glhooks.glXQueryExtension_real(dpy, errorBase, eventBase); } __attribute__((visibility("default"))) GLXFBConfig *glXGetFBConfigs(Display *dpy, int screen, int *nelements) { + if(OpenGLHook::glhooks.glXGetFBConfigs_real == NULL) + OpenGLHook::glhooks.SetupExportedFunctions(); + return OpenGLHook::glhooks.glXGetFBConfigs_real(dpy, screen, nelements); } __attribute__((visibility("default"))) int glXGetFBConfigAttrib(Display *dpy, GLXFBConfig config, int attribute, int *value) { + if(OpenGLHook::glhooks.glXGetFBConfigAttrib_real == NULL) + OpenGLHook::glhooks.SetupExportedFunctions(); + return OpenGLHook::glhooks.glXGetFBConfigAttrib_real(dpy, config, attribute, value); } __attribute__((visibility("default"))) const char *glXGetClientString(Display *dpy, int name) { + if(OpenGLHook::glhooks.glXGetClientString_real == NULL) + OpenGLHook::glhooks.SetupExportedFunctions(); + return OpenGLHook::glhooks.glXGetClientString_real(dpy, name); } __attribute__((visibility("default"))) Bool glXQueryVersion(Display *dpy, int *maj, int *min) { + if(OpenGLHook::glhooks.glXQueryVersion_real == NULL) + OpenGLHook::glhooks.SetupExportedFunctions(); + return OpenGLHook::glhooks.glXQueryVersion_real(dpy, maj, min); } __attribute__((visibility("default"))) const char *glXQueryExtensionsString(Display *dpy, int screen) { + if(OpenGLHook::glhooks.glXQueryExtensionsString_real == NULL) + OpenGLHook::glhooks.SetupExportedFunctions(); + return OpenGLHook::glhooks.glXQueryExtensionsString_real(dpy, screen); } __attribute__((visibility("default"))) GLXContext glXCreateNewContext( Display *dpy, GLXFBConfig config, int renderType, GLXContext shareList, Bool direct) { + if(OpenGLHook::glhooks.glXCreateNewContext_real == NULL) + OpenGLHook::glhooks.SetupExportedFunctions(); + return OpenGLHook::glhooks.glXCreateNewContext_real(dpy, config, renderType, shareList, direct); } __attribute__((visibility("default"))) XVisualInfo *glXGetVisualFromFBConfig(Display *dpy, GLXFBConfig config) { + if(OpenGLHook::glhooks.glXGetVisualFromFBConfig_real == NULL) + OpenGLHook::glhooks.SetupExportedFunctions(); + return OpenGLHook::glhooks.glXGetVisualFromFBConfig_real(dpy, config); }