diff --git a/renderdoc/driver/gl/gl_common.h b/renderdoc/driver/gl/gl_common.h index 66c906911..4e59af195 100644 --- a/renderdoc/driver/gl/gl_common.h +++ b/renderdoc/driver/gl/gl_common.h @@ -38,6 +38,7 @@ struct GLWindowingData { + void SetCtx(void *c) { ctx = (HGLRC)c; } HDC DC; HGLRC ctx; HWND wnd; @@ -53,6 +54,7 @@ struct GLWindowingData struct GLWindowingData { + void SetCtx(void *c) { ctx = (GLXContext)c; } Display *dpy; GLXContext ctx; GLXDrawable wnd; diff --git a/renderdoc/driver/gl/gl_driver.cpp b/renderdoc/driver/gl/gl_driver.cpp index 4cfc890ed..4bda5e218 100644 --- a/renderdoc/driver/gl/gl_driver.cpp +++ b/renderdoc/driver/gl/gl_driver.cpp @@ -636,7 +636,31 @@ WrappedOpenGL::~WrappedOpenGL() void *WrappedOpenGL::GetCtx() { - return m_ActiveContexts[Threading::GetCurrentID()]; + return (void *)m_ActiveContexts[Threading::GetCurrentID()].ctx; +} + +WrappedOpenGL::ContextData &WrappedOpenGL::GetCtxData() +{ + return m_ContextData[GetCtx()]; +} + +// defined in gl__hooks.cpp +void MakeContextCurrent(GLWindowingData data); + +void *WrappedOpenGL::SwitchToContext(void *ctx) +{ + GLWindowingData &data = m_ActiveContexts[Threading::GetCurrentID()]; + + void *oldctx = data.ctx; + + // we won't get a callback for this (on purpose, since this can happen mid-capture and + // we don't want to mix this up with a MakeCurrent call from the program). So we update + // the current thread context here. + data.SetCtx(ctx); + + MakeContextCurrent(data); + + return oldctx; } //////////////////////////////////////////////////////////////// @@ -664,19 +688,19 @@ void WrappedOpenGL::DeleteContext(void *contextHandle) m_ContextData.erase(contextHandle); } -void WrappedOpenGL::CreateContext(void *windowHandle, void *contextHandle, void *shareContext, GLInitParams initParams) +void WrappedOpenGL::CreateContext(GLWindowingData winData, void *shareContext, GLInitParams initParams) { // TODO: support multiple GL contexts more explicitly m_InitParams = initParams; } -void WrappedOpenGL::ActivateContext(void *windowHandle, void *contextHandle) +void WrappedOpenGL::ActivateContext(GLWindowingData winData) { - m_ActiveContexts[Threading::GetCurrentID()] = contextHandle; + m_ActiveContexts[Threading::GetCurrentID()] = winData; // TODO: support multiple GL contexts more explicitly - Keyboard::AddInputWindow(windowHandle); + Keyboard::AddInputWindow((void *)winData.wnd); - if(contextHandle) + if(winData.ctx) { // if we're capturing, we need to serialise out the changed state vector if(m_State == WRITING_CAPFRAME) @@ -686,7 +710,7 @@ void WrappedOpenGL::ActivateContext(void *windowHandle, void *contextHandle) m_ContextRecord->AddChunk(scope.Get()); } - ContextData &font = m_ContextData[contextHandle]; + ContextData &font = m_ContextData[winData.ctx]; if(!font.built) { diff --git a/renderdoc/driver/gl/gl_driver.h b/renderdoc/driver/gl/gl_driver.h index 0eb148f75..1d8a07260 100644 --- a/renderdoc/driver/gl/gl_driver.h +++ b/renderdoc/driver/gl/gl_driver.h @@ -120,7 +120,7 @@ class WrappedOpenGL GLInitParams m_InitParams; - map m_ActiveContexts; + map m_ActiveContexts; bool m_ActiveQueries[8][8]; // first index type, second index (for some, always 0) bool m_ActiveConditional; @@ -334,6 +334,7 @@ class WrappedOpenGL GLReplay *GetReplay() { return &m_Replay; } void *GetCtx(); + void *SwitchToContext(void *ctx); // replay interface void Initialise(GLInitParams ¶ms); @@ -346,9 +347,9 @@ class WrappedOpenGL vector &GetFrameRecord() { return m_FrameRecord; } FetchAPIEvent GetEvent(uint32_t eventID); - void CreateContext(void *windowHandle, void *contextHandle, void *shareContext, GLInitParams initParams); + void CreateContext(GLWindowingData winData, void *shareContext, GLInitParams initParams); void DeleteContext(void *contextHandle); - void ActivateContext(void *windowHandle, void *contextHandle); + void ActivateContext(GLWindowingData winData); void WindowSize(void *windowHandle, uint32_t w, uint32_t h); void Present(void *windowHandle); diff --git a/renderdoc/driver/gl/gl_replay_linux.cpp b/renderdoc/driver/gl/gl_replay_linux.cpp index dbff22047..2526a5f78 100644 --- a/renderdoc/driver/gl/gl_replay_linux.cpp +++ b/renderdoc/driver/gl/gl_replay_linux.cpp @@ -51,7 +51,7 @@ void GLReplay::MakeCurrentReplayContext(GLWindowingData *ctx) { prev = ctx; glXMakeContextCurrentProc(ctx->dpy, ctx->wnd, ctx->wnd, ctx->ctx); - m_pDriver->ActivateContext((void *)ctx->wnd, ctx->ctx); + m_pDriver->ActivateContext(*ctx); } } diff --git a/renderdoc/driver/gl/gl_replay_win32.cpp b/renderdoc/driver/gl/gl_replay_win32.cpp index b76dca879..80f2dd6db 100644 --- a/renderdoc/driver/gl/gl_replay_win32.cpp +++ b/renderdoc/driver/gl/gl_replay_win32.cpp @@ -48,7 +48,7 @@ void GLReplay::MakeCurrentReplayContext(GLWindowingData *ctx) { prev = ctx; wglMakeCurrentProc(ctx->DC, ctx->ctx); - m_pDriver->ActivateContext(ctx->wnd, ctx->ctx); + m_pDriver->ActivateContext(*ctx); } } diff --git a/renderdoc/driver/gl/wrappers/gl_shader_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_shader_funcs.cpp index 7f0099174..67f38a23b 100644 --- a/renderdoc/driver/gl/wrappers/gl_shader_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_shader_funcs.cpp @@ -978,11 +978,6 @@ void WrappedOpenGL::glActiveShaderProgram(GLuint pipeline, GLuint program) m_Real.glActiveShaderProgram(pipeline, program); } -WrappedOpenGL::ContextData &WrappedOpenGL::GetCtxData() -{ - return m_ContextData[GetCtx()]; -} - GLuint WrappedOpenGL::GetUniformProgram() { ContextData &cd = GetCtxData(); diff --git a/renderdoc/hooks/gl_linux_hooks.cpp b/renderdoc/hooks/gl_linux_hooks.cpp index d4afdda09..3dde8f0f7 100644 --- a/renderdoc/hooks/gl_linux_hooks.cpp +++ b/renderdoc/hooks/gl_linux_hooks.cpp @@ -293,6 +293,12 @@ class OpenGLHook : LibraryHook return GL; } + void MakeContextCurrent(GLWindowingData data) + { + if(glXMakeCurrent_real) + glXMakeCurrent_real(data.dpy, data.wnd, data.ctx); + } + WrappedOpenGL *GetDriver() { if(m_GLDriver == NULL) @@ -353,7 +359,12 @@ GLXContext glXCreateContext(Display *dpy, XVisualInfo *vis, GLXContext shareList value = 1; OpenGLHook::glhooks.glXGetConfig_real(dpy, vis, GLX_SAMPLES_ARB, &value); init.isSRGB = RDCMAX(1, value); - OpenGLHook::glhooks.GetDriver()->CreateContext(NULL, ret, shareList, init); + GLWindowingData data; + data.dpy = dpy; + data.wnd = (GLXDrawable)NULL; + data.ctx = ret; + + OpenGLHook::glhooks.GetDriver()->CreateContext(data, shareList, init); return ret; } @@ -432,7 +443,12 @@ GLXContext glXCreateContextAttribsARB(Display *dpy, GLXFBConfig config, GLXConte XFree(vis); - OpenGLHook::glhooks.GetDriver()->CreateContext(NULL, ret, shareList, init); + GLWindowingData data; + data.dpy = dpy; + data.wnd = (GLXDrawable)NULL; + data.ctx = ret; + + OpenGLHook::glhooks.GetDriver()->CreateContext(data, shareList, init); return ret; } @@ -448,8 +464,13 @@ Bool glXMakeCurrent(Display *dpy, GLXDrawable drawable, GLXContext ctx) OpenGLHook::glhooks.PopulateHooks(); } + + GLWindowingData data; + data.dpy = dpy; + data.wnd = drawable; + data.ctx = ctx; - OpenGLHook::glhooks.GetDriver()->ActivateContext((void *)drawable, ctx); + OpenGLHook::glhooks.GetDriver()->ActivateContext(data); return ret; } @@ -602,3 +623,8 @@ OpenGLHook OpenGLHook::glhooks; const GLHookSet &GetRealFunctions() { return OpenGLHook::glhooks.GetRealFunctions(); } +void MakeContextCurrent(GLWindowingData data) +{ + OpenGLHook::glhooks.MakeContextCurrent(data); +} + diff --git a/renderdoc/hooks/gl_win32_hooks.cpp b/renderdoc/hooks/gl_win32_hooks.cpp index a203c0f4b..bbc1d6f14 100644 --- a/renderdoc/hooks/gl_win32_hooks.cpp +++ b/renderdoc/hooks/gl_win32_hooks.cpp @@ -253,6 +253,12 @@ class OpenGLHook : LibraryHook return GL; } + void MakeContextCurrent(GLWindowingData data) + { + if(wglMakeCurrent_hook()) + wglMakeCurrent_hook()(data.DC, data.ctx); + } + private: WrappedOpenGL *GetDriver() { @@ -333,7 +339,12 @@ class OpenGLHook : LibraryHook { HGLRC ret = glhooks.wglCreateContext_hook()(dc); - glhooks.GetDriver()->CreateContext(WindowFromDC(dc), ret, NULL, GetInitParamsForDC(dc)); + GLWindowingData data; + data.DC = dc; + data.wnd = WindowFromDC(dc); + data.ctx = ret; + + glhooks.GetDriver()->CreateContext(data, NULL, GetInitParamsForDC(dc)); return ret; } @@ -349,7 +360,12 @@ class OpenGLHook : LibraryHook { HGLRC ret = glhooks.wglCreateLayerContext_hook()(dc, iLayerPlane); - glhooks.GetDriver()->CreateContext(WindowFromDC(dc), ret, NULL, GetInitParamsForDC(dc)); + GLWindowingData data; + data.DC = dc; + data.wnd = WindowFromDC(dc); + data.ctx = ret; + + glhooks.GetDriver()->CreateContext(data, NULL, GetInitParamsForDC(dc)); return ret; } @@ -398,7 +414,12 @@ class OpenGLHook : LibraryHook HGLRC ret = glhooks.wglCreateContextAttribsARB_realfunc(dc, hShareContext, attribs); - glhooks.GetDriver()->CreateContext(WindowFromDC(dc), ret, hShareContext, GetInitParamsForDC(dc)); + GLWindowingData data; + data.DC = dc; + data.wnd = WindowFromDC(dc); + data.ctx = ret; + + glhooks.GetDriver()->CreateContext(data, hShareContext, GetInitParamsForDC(dc)); return ret; } @@ -429,7 +450,12 @@ class OpenGLHook : LibraryHook glhooks.PopulateHooks(); } - glhooks.GetDriver()->ActivateContext(WindowFromDC(dc), rc); + GLWindowingData data; + data.DC = dc; + data.wnd = WindowFromDC(dc); + data.ctx = rc; + + glhooks.GetDriver()->ActivateContext(data); return ret; } @@ -619,3 +645,8 @@ class OpenGLHook : LibraryHook OpenGLHook OpenGLHook::glhooks; const GLHookSet &GetRealFunctions() { return OpenGLHook::glhooks.GetRealFunctions(); } + +void MakeContextCurrent(GLWindowingData data) +{ + OpenGLHook::glhooks.MakeContextCurrent(data); +}