From 49e6ee5c1323209e03822ac20570dabc2e01e167 Mon Sep 17 00:00:00 2001 From: baldurk Date: Mon, 13 Feb 2017 10:23:27 +0000 Subject: [PATCH] Add locking around context creation/activation/deletion on GL * The GL back-end will do work for each of these operations and in particular the case of MakeCurrent while capturing will cause the state of that context to be serialised as a context switch. We don't want that to happen while we're also serialising draw data on another thread. --- renderdoc/driver/gl/gl_hooks_egl.cpp | 13 ++++++++++-- renderdoc/driver/gl/gl_hooks_linux.cpp | 29 +++++++++++++++++++++----- renderdoc/driver/gl/gl_hooks_win32.cpp | 27 ++++++++++++++---------- 3 files changed, 51 insertions(+), 18 deletions(-) diff --git a/renderdoc/driver/gl/gl_hooks_egl.cpp b/renderdoc/driver/gl/gl_hooks_egl.cpp index 515ec275a..4d1b10aeb 100644 --- a/renderdoc/driver/gl/gl_hooks_egl.cpp +++ b/renderdoc/driver/gl/gl_hooks_egl.cpp @@ -958,7 +958,10 @@ __attribute__((visibility("default"))) EGLContext eglCreateContext(EGLDisplay di data.wnd = (EGLSurface)NULL; data.ctx = ret; - OpenGLHook::glhooks.GetDriver()->CreateContext(data, shareContext, init, true, true); + { + SCOPED_LOCK(glLock); + OpenGLHook::glhooks.GetDriver()->CreateContext(data, shareContext, init, true, true); + } return ret; } @@ -968,7 +971,11 @@ __attribute__((visibility("default"))) EGLBoolean eglDestroyContext(EGLDisplay d if(OpenGLHook::glhooks.eglDestroyContext_real == NULL) OpenGLHook::glhooks.SetupExportedFunctions(); - OpenGLHook::glhooks.GetDriver()->DeleteContext(ctx); + { + SCOPED_LOCK(glLock); + OpenGLHook::glhooks.GetDriver()->DeleteContext(ctx); + } + return OpenGLHook::glhooks.eglDestroyContext_real(dpy, ctx); } @@ -980,6 +987,8 @@ __attribute__((visibility("default"))) EGLBoolean eglMakeCurrent(EGLDisplay disp EGLBoolean ret = OpenGLHook::glhooks.eglMakeCurrent_real(display, draw, read, ctx); + SCOPED_LOCK(glLock); + if(ctx && OpenGLHook::glhooks.m_Contexts.find(ctx) == OpenGLHook::glhooks.m_Contexts.end()) { OpenGLHook::glhooks.m_Contexts.insert(ctx); diff --git a/renderdoc/driver/gl/gl_hooks_linux.cpp b/renderdoc/driver/gl/gl_hooks_linux.cpp index e0bc1e596..7170b363d 100644 --- a/renderdoc/driver/gl/gl_hooks_linux.cpp +++ b/renderdoc/driver/gl/gl_hooks_linux.cpp @@ -949,7 +949,10 @@ __attribute__((visibility("default"))) GLXContext glXCreateContext(Display *dpy, data.wnd = (GLXDrawable)NULL; data.ctx = ret; - OpenGLHook::glhooks.GetDriver()->CreateContext(data, shareList, init, false, false); + { + SCOPED_LOCK(glLock); + OpenGLHook::glhooks.GetDriver()->CreateContext(data, shareList, init, false, false); + } return ret; } @@ -959,7 +962,10 @@ __attribute__((visibility("default"))) void glXDestroyContext(Display *dpy, GLXC if(OpenGLHook::glhooks.glXDestroyContext_real == NULL) OpenGLHook::glhooks.SetupExportedFunctions(); - OpenGLHook::glhooks.GetDriver()->DeleteContext(ctx); + { + SCOPED_LOCK(glLock); + OpenGLHook::glhooks.GetDriver()->DeleteContext(ctx); + } OpenGLHook::glhooks.glXDestroyContext_real(dpy, ctx); } @@ -1065,7 +1071,10 @@ __attribute__((visibility("default"))) GLXContext glXCreateContextAttribsARB( data.wnd = (GLXDrawable)NULL; data.ctx = ret; - OpenGLHook::glhooks.GetDriver()->CreateContext(data, shareList, init, core, true); + { + SCOPED_LOCK(glLock); + OpenGLHook::glhooks.GetDriver()->CreateContext(data, shareList, init, core, true); + } return ret; } @@ -1078,6 +1087,8 @@ __attribute__((visibility("default"))) Bool glXMakeCurrent(Display *dpy, GLXDraw Bool ret = OpenGLHook::glhooks.glXMakeCurrent_real(dpy, drawable, ctx); + SCOPED_LOCK(glLock); + if(ctx && OpenGLHook::glhooks.m_Contexts.find(ctx) == OpenGLHook::glhooks.m_Contexts.end()) { OpenGLHook::glhooks.m_Contexts.insert(ctx); @@ -1103,6 +1114,8 @@ __attribute__((visibility("default"))) Bool glXMakeContextCurrent(Display *dpy, Bool ret = OpenGLHook::glhooks.glXMakeContextCurrent_real(dpy, draw, read, ctx); + SCOPED_LOCK(glLock); + if(ctx && OpenGLHook::glhooks.m_Contexts.find(ctx) == OpenGLHook::glhooks.m_Contexts.end()) { OpenGLHook::glhooks.m_Contexts.insert(ctx); @@ -1220,7 +1233,10 @@ __attribute__((visibility("default"))) GLXWindow glXCreateWindow(Display *dpy, G GLXWindow ret = OpenGLHook::glhooks.glXCreateWindow_real(dpy, config, win, attribList); - OpenGLHook::glhooks.AddGLXWindow(ret, win); + { + SCOPED_LOCK(glLock); + OpenGLHook::glhooks.AddGLXWindow(ret, win); + } return ret; } @@ -1230,7 +1246,10 @@ __attribute__((visibility("default"))) void glXDestroyWindow(Display *dpy, GLXWi if(OpenGLHook::glhooks.glXDestroyWindow_real == NULL) OpenGLHook::glhooks.SetupExportedFunctions(); - OpenGLHook::glhooks.RemoveGLXWindow(window); + { + SCOPED_LOCK(glLock); + OpenGLHook::glhooks.RemoveGLXWindow(window); + } return OpenGLHook::glhooks.glXDestroyWindow_real(dpy, window); } diff --git a/renderdoc/driver/gl/gl_hooks_win32.cpp b/renderdoc/driver/gl/gl_hooks_win32.cpp index a868bfab8..424aa4157 100644 --- a/renderdoc/driver/gl/gl_hooks_win32.cpp +++ b/renderdoc/driver/gl/gl_hooks_win32.cpp @@ -675,21 +675,26 @@ private: DWORD err = GetLastError(); - if(rc && glhooks.m_HaveContextCreation && glhooks.m_Contexts.find(rc) == glhooks.m_Contexts.end()) { - glhooks.m_Contexts.insert(rc); + SCOPED_LOCK(glLock); - glhooks.PopulateHooks(); + if(rc && glhooks.m_HaveContextCreation && + glhooks.m_Contexts.find(rc) == glhooks.m_Contexts.end()) + { + glhooks.m_Contexts.insert(rc); + + glhooks.PopulateHooks(); + } + + GLWindowingData data; + data.DC = dc; + data.wnd = WindowFromDC(dc); + data.ctx = rc; + + if(glhooks.m_HaveContextCreation) + glhooks.GetDriver()->ActivateContext(data); } - GLWindowingData data; - data.DC = dc; - data.wnd = WindowFromDC(dc); - data.ctx = rc; - - if(glhooks.m_HaveContextCreation) - glhooks.GetDriver()->ActivateContext(data); - SetLastError(err); return ret;