From daed903b642503c46d5fdb9f9ddc559874647b4b Mon Sep 17 00:00:00 2001 From: baldurk Date: Thu, 3 Jan 2019 11:51:40 +0000 Subject: [PATCH] Add support for wglShareLists. Closes #1224 * We can't feasibly support calling wglShareLists after wglMakeCurrent because we must do work and create objects in wglMakeCurrent. If this situation happens we pretend that wglShareLists failed and print an error. --- renderdoc/driver/gl/gl_driver.cpp | 27 +++++++++++++++++++++--- renderdoc/driver/gl/gl_driver.h | 1 + renderdoc/driver/gl/wgl_dispatch_table.h | 2 ++ renderdoc/driver/gl/wgl_hooks.cpp | 18 ++++++++++++++++ 4 files changed, 45 insertions(+), 3 deletions(-) diff --git a/renderdoc/driver/gl/gl_driver.cpp b/renderdoc/driver/gl/gl_driver.cpp index d6cb05cea..f3b17cfc9 100644 --- a/renderdoc/driver/gl/gl_driver.cpp +++ b/renderdoc/driver/gl/gl_driver.cpp @@ -991,6 +991,24 @@ void WrappedOpenGL::CreateContext(GLWindowingData winData, void *shareContext, m_ScratchSerialiser.SetChunkMetadataRecording(flags); } +bool WrappedOpenGL::ForceSharedObjects(void *oldContext, void *newContext) +{ + ContextData &olddata = m_ContextData[oldContext]; + ContextData &newdata = m_ContextData[newContext]; + + RDCLOG("Forcibly sharing %p with %p", newContext, oldContext); + + if(newdata.built) + { + RDCERR("wglShareLists called after wglMakeCurrent - this is not supported and will break."); + return false; + } + + newdata.shareGroup = olddata.shareGroup; + + return true; +} + void WrappedOpenGL::RegisterReplayContext(GLWindowingData winData, void *shareContext, bool core, bool attribsCreate) { @@ -1656,9 +1674,12 @@ void WrappedOpenGL::SwapBuffers(void *windowHandle) ctxdata.AssociateWindow(this, windowHandle); } - // do this as late as possible to avoid creating objects on contexts - // that might be shared later (wglShareLists requires contexts to be - // pristine, so can't create this from wglMakeCurrent) + // we used to do this here so it was as late as possible to avoid creating objects on contexts + // that might be shared later. wglShareLists requires contexts to have no objects and can be + // called after wglMakeCurrent. However we also need other objects like client-memory buffers and + // vendor checks inside makecurrent that it is not feasible to defer until later, since there's no + // other sync point after wglMakeCurrent before we'll need the information. So we don't support + // calling wglShareLists after wglMakeCurrent. if(!ctxdata.ready) ctxdata.CreateDebugData(); diff --git a/renderdoc/driver/gl/gl_driver.h b/renderdoc/driver/gl/gl_driver.h index cf9c524b5..68d27bd12 100644 --- a/renderdoc/driver/gl/gl_driver.h +++ b/renderdoc/driver/gl/gl_driver.h @@ -541,6 +541,7 @@ public: return m_ContextData[winData.ctx].initParams; } void ActivateContext(GLWindowingData winData); + bool ForceSharedObjects(void *oldContext, void *newContext); void SwapBuffers(void *windowHandle); void HandleVRFrameMarkers(const GLchar *buf, GLsizei length); bool UsesVRFrameMarkers() { return m_UsesVRMarkers; } diff --git a/renderdoc/driver/gl/wgl_dispatch_table.h b/renderdoc/driver/gl/wgl_dispatch_table.h index 95f100aa1..a870baeeb 100644 --- a/renderdoc/driver/gl/wgl_dispatch_table.h +++ b/renderdoc/driver/gl/wgl_dispatch_table.h @@ -29,6 +29,7 @@ // exported wgl functions typedef HGLRC(WINAPI *PFN_wglCreateContext)(HDC); typedef BOOL(WINAPI *PFN_wglDeleteContext)(HGLRC); +typedef BOOL(WINAPI *PFN_wglShareLists)(HGLRC, HGLRC); typedef HGLRC(WINAPI *PFN_wglCreateLayerContext)(HDC, int); typedef BOOL(WINAPI *PFN_wglMakeCurrent)(HDC, HGLRC); typedef PROC(WINAPI *PFN_wglGetProcAddress)(const char *); @@ -70,6 +71,7 @@ typedef LONG(WINAPI *PFN_ChangeDisplaySettingsExW)(LPCWSTR, DEVMODEW *, HWND, DW FUNC("opengl32.dll", wglMakeCurrent); \ FUNC("opengl32.dll", wglGetProcAddress); \ FUNC("opengl32.dll", wglSwapBuffers); \ + FUNC("opengl32.dll", wglShareLists); \ FUNC("opengl32.dll", wglSwapLayerBuffers); \ FUNC("opengl32.dll", wglSwapMultipleBuffers); \ FUNC("", wglCreateContextAttribsARB); \ diff --git a/renderdoc/driver/gl/wgl_hooks.cpp b/renderdoc/driver/gl/wgl_hooks.cpp index 210ed5f2a..aa130d626 100644 --- a/renderdoc/driver/gl/wgl_hooks.cpp +++ b/renderdoc/driver/gl/wgl_hooks.cpp @@ -361,6 +361,24 @@ static HGLRC WINAPI wglCreateContextAttribsARB_hooked(HDC dc, HGLRC hShareContex return ret; } +static BOOL WINAPI wglShareLists_hooked(HGLRC oldContext, HGLRC newContext) +{ + bool ret = WGL.wglShareLists(oldContext, newContext) == TRUE; + + DWORD err = GetLastError(); + + if(ret) + { + SCOPED_LOCK(glLock); + + ret &= wglhook.driver.ForceSharedObjects(oldContext, newContext); + } + + SetLastError(err); + + return ret ? TRUE : FALSE; +} + static BOOL WINAPI wglMakeCurrent_hooked(HDC dc, HGLRC rc) { BOOL ret = WGL.wglMakeCurrent(dc, rc);