Handle GL hooks called during replay from injected code. Refs #2752

This commit is contained in:
baldurk
2022-10-18 10:21:04 +01:00
parent d024f062c2
commit 101dbda8c3
3 changed files with 53 additions and 21 deletions
+8 -1
View File
@@ -447,9 +447,16 @@ HOOK_EXPORT EGLBoolean EGLAPIENTRY eglMakeCurrent_renderdoc_hooked(EGLDisplay di
{
if(RenderDoc::Inst().IsReplayApp())
{
if(!EGL.MakeCurrent)
if(!EGL.MakeCurrent || !EGL.GetProcAddress)
EGL.PopulateForReplay();
// populate GL function pointers now in case linked functions are called
if(EGL.GetProcAddress)
{
GL.PopulateWithCallback(
[](const char *funcName) -> void * { return (void *)EGL.GetProcAddress(funcName); });
}
return EGL.MakeCurrent(display, draw, read, ctx);
}
+27 -18
View File
@@ -124,7 +124,6 @@ void DisableGLHooks()
glhook.enabled = false;
}
#if ENABLED(RDOC_WIN32) || ENABLED(RDOC_APPLE) || ENABLED(RDOC_SWITCH)
template <typename ret_type>
ret_type default_ret()
{
@@ -136,25 +135,35 @@ void default_ret()
{
}
// if we were injected and aren't ready to capture, skip out and call the real function
#define UNINIT_CALL(function, ...) \
if(!glhook.enabled) \
{ \
if(GL.function == NULL) \
{ \
RDCERR("No function pointer for '%s' while uninitialised!", STRINGIZE(function)); \
return default_ret<decltype(GL.function(__VA_ARGS__))>(); \
} \
return GL.function(__VA_ARGS__); \
template <>
const char *default_ret()
{
return "";
}
template <>
const GLubyte *default_ret()
{
return (const GLubyte *)"";
}
// on windows we can be injected and not ready to capture when we intercept a GL call. If that
// happens we need to skip and call the real function
// on linux some systems inject external code into Qt which initialises GL behind our back. If this
// calls glXGetProcAddress it will get the real function pointers, but if it links against GL it
// will get routed here via our public exported symbols so we try to call the real function
#define UNINIT_CALL(function, ...) \
if(!glhook.enabled) \
{ \
if(GL.function == NULL) \
{ \
RDCERR("No function pointer for '%s' while doing replay fallback!", STRINGIZE(function)); \
return default_ret<decltype(GL.function(__VA_ARGS__))>(); \
} \
return GL.function(__VA_ARGS__); \
}
#else
// nothing to do - we always assume we are ready to capture
#define UNINIT_CALL(function, ...)
#endif
DefineSupportedHooks();
DefineUnsupportedHooks();
+18 -2
View File
@@ -353,9 +353,17 @@ HOOK_EXPORT Bool glXMakeCurrent_renderdoc_hooked(Display *dpy, GLXDrawable drawa
{
if(RenderDoc::Inst().IsReplayApp())
{
if(!GLX.glXMakeCurrent)
if(!GLX.glXMakeCurrent || !GLX.glXGetProcAddress)
GLX.PopulateForReplay();
// populate GL function pointers now in case linked functions are called
if(GLX.glXGetProcAddress)
{
GL.PopulateWithCallback([](const char *funcName) -> void * {
return (void *)GLX.glXGetProcAddress((const GLubyte *)funcName);
});
}
return GLX.glXMakeCurrent(dpy, drawable, ctx);
}
@@ -425,9 +433,17 @@ HOOK_EXPORT Bool glXMakeContextCurrent_renderdoc_hooked(Display *dpy, GLXDrawabl
{
if(RenderDoc::Inst().IsReplayApp())
{
if(!GLX.glXMakeContextCurrent)
if(!GLX.glXMakeContextCurrent || !GLX.glXGetProcAddress)
GLX.PopulateForReplay();
// populate GL function pointers now in case linked functions are called
if(GLX.glXGetProcAddress)
{
GL.PopulateWithCallback([](const char *funcName) -> void * {
return (void *)GLX.glXGetProcAddress((const GLubyte *)funcName);
});
}
return GLX.glXMakeContextCurrent(dpy, draw, read, ctx);
}