140 lines
5.5 KiB
Diff
140 lines
5.5 KiB
Diff
|
From 101dbda8c34888bf2051c3c257da3a1702705ef9 Mon Sep 17 00:00:00 2001
|
||
|
From: baldurk <baldurk@baldurk.org>
|
||
|
Date: Tue, 18 Oct 2022 10:21:04 +0100
|
||
|
Subject: [PATCH] Handle GL hooks called during replay from injected code. Refs
|
||
|
#2752
|
||
|
|
||
|
---
|
||
|
renderdoc/driver/gl/egl_hooks.cpp | 9 ++++++-
|
||
|
renderdoc/driver/gl/gl_hooks.cpp | 43 +++++++++++++++++++------------
|
||
|
renderdoc/driver/gl/glx_hooks.cpp | 20 ++++++++++++--
|
||
|
3 files changed, 52 insertions(+), 20 deletions(-)
|
||
|
|
||
|
diff --git a/renderdoc/driver/gl/egl_hooks.cpp b/renderdoc/driver/gl/egl_hooks.cpp
|
||
|
index a3aa0cfc2a..09e69c0079 100644
|
||
|
--- a/renderdoc/driver/gl/egl_hooks.cpp
|
||
|
+++ b/renderdoc/driver/gl/egl_hooks.cpp
|
||
|
@@ -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);
|
||
|
}
|
||
|
|
||
|
diff --git a/renderdoc/driver/gl/gl_hooks.cpp b/renderdoc/driver/gl/gl_hooks.cpp
|
||
|
index 369f924bea..7e5a0ac073 100644
|
||
|
--- a/renderdoc/driver/gl/gl_hooks.cpp
|
||
|
+++ b/renderdoc/driver/gl/gl_hooks.cpp
|
||
|
@@ -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,24 +135,34 @@ 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__); \
|
||
|
- }
|
||
|
-
|
||
|
-#else
|
||
|
+template <>
|
||
|
+const char *default_ret()
|
||
|
+{
|
||
|
+ return "";
|
||
|
+}
|
||
|
|
||
|
-// nothing to do - we always assume we are ready to capture
|
||
|
-#define UNINIT_CALL(function, ...)
|
||
|
+template <>
|
||
|
+const GLubyte *default_ret()
|
||
|
+{
|
||
|
+ return (const GLubyte *)"";
|
||
|
+}
|
||
|
|
||
|
-#endif
|
||
|
+// 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__); \
|
||
|
+ }
|
||
|
|
||
|
DefineSupportedHooks();
|
||
|
DefineUnsupportedHooks();
|
||
|
diff --git a/renderdoc/driver/gl/glx_hooks.cpp b/renderdoc/driver/gl/glx_hooks.cpp
|
||
|
index 5030fe8dfb..5bf2202eca 100644
|
||
|
--- a/renderdoc/driver/gl/glx_hooks.cpp
|
||
|
+++ b/renderdoc/driver/gl/glx_hooks.cpp
|
||
|
@@ -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);
|
||
|
}
|
||
|
|