Separate out function to make shared context for vendor checks

* This is only to be used to make a temporary context to share with. We make
  sure to use the same visual/config as the parent context to ensure it will
  successfully share.
This commit is contained in:
baldurk
2018-07-06 13:01:38 +01:00
parent 44f9b08e71
commit 178f61abd0
10 changed files with 113 additions and 75 deletions
+2 -2
View File
@@ -27,13 +27,13 @@
class CGLPlatform : public GLPlatform
{
bool MakeContextCurrent(GLWindowingData data) { return false; }
GLWindowingData MakeContext(GLWindowingData share)
GLWindowingData CloneTemporaryContext(GLWindowingData share)
{
GLWindowingData ret;
return ret;
}
void DeleteContext(GLWindowingData context) {}
void DeleteClonedContext(GLWindowingData context) {}
void DeleteReplayContext(GLWindowingData context) {}
void SwapBuffers(GLWindowingData context) {}
void GetOutputWindowDimensions(GLWindowingData context, int32_t &w, int32_t &h) { w = h = 0; }
+7
View File
@@ -51,6 +51,7 @@ public:
void *handle = DEFAULT_HANDLE;
WrappedOpenGL driver;
std::set<EGLContext> contexts;
std::map<EGLContext, EGLConfig> configs;
} eglhook;
HOOK_EXPORT EGLDisplay eglGetDisplay(EGLNativeDisplayType display)
@@ -165,6 +166,9 @@ HOOK_EXPORT EGLContext eglCreateContext(EGLDisplay display, EGLConfig config,
data.egl_dpy = display;
data.egl_wnd = (EGLSurface)NULL;
data.egl_ctx = ret;
data.egl_cfg = config;
eglhook.configs[ret] = config;
eglhook.driver.SetDriverType(RDCDriver::OpenGLES);
{
@@ -231,6 +235,9 @@ HOOK_EXPORT EGLBoolean eglMakeCurrent(EGLDisplay display, EGLSurface draw, EGLSu
data.egl_wnd = draw;
data.egl_ctx = ctx;
// we could query this out technically but it's easier to keep a map
data.egl_cfg = eglhook.configs[ctx];
eglhook.driver.SetDriverType(RDCDriver::OpenGLES);
eglhook.driver.ActivateContext(data);
+17 -21
View File
@@ -50,23 +50,25 @@ class EGLPlatform : public GLPlatform
return false;
}
GLWindowingData MakeContext(GLWindowingData share)
GLWindowingData CloneTemporaryContext(GLWindowingData share)
{
GLWindowingData ret;
GLWindowingData ret = share;
if(EGL.CreateContext && EGL.ChooseConfig && EGL.CreatePbufferSurface)
ret.egl_ctx = NULL;
if(EGL.CreateContext)
{
ret = CreateWindowingData(share.egl_dpy, share.ctx, 0);
EGLint baseAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, 3, EGL_CONTEXT_FLAGS_KHR,
EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR, EGL_NONE};
ret.egl_ctx = EGL.CreateContext(share.egl_dpy, share.egl_cfg, share.egl_ctx, baseAttribs);
}
return ret;
}
void DeleteContext(GLWindowingData context)
void DeleteClonedContext(GLWindowingData context)
{
if(context.wnd && EGL.DestroySurface)
EGL.DestroySurface(context.egl_dpy, context.egl_wnd);
if(context.ctx && EGL.DestroyContext)
EGL.DestroyContext(context.egl_dpy, context.egl_ctx);
}
@@ -159,8 +161,7 @@ class EGLPlatform : public GLPlatform
EGL_NONE};
EGLint numConfigs;
EGLConfig config;
if(!EGL.ChooseConfig(eglDisplay, configAttribs, &config, 1, &numConfigs))
if(!EGL.ChooseConfig(eglDisplay, configAttribs, &ret.egl_cfg, 1, &numConfigs))
{
RDCERR("Couldn't find a suitable EGL config");
return ret;
@@ -185,7 +186,7 @@ class EGLPlatform : public GLPlatform
{
verAttribs[1] = v.major;
verAttribs[3] = v.minor;
ctx = EGL.CreateContext(eglDisplay, config, share_ctx, verAttribs);
ctx = EGL.CreateContext(eglDisplay, ret.egl_cfg, share_ctx, verAttribs);
if(ctx)
break;
@@ -197,7 +198,7 @@ class EGLPlatform : public GLPlatform
static const EGLint baseAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, 3, EGL_CONTEXT_FLAGS_KHR,
EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR, EGL_NONE};
ctx = EGL.CreateContext(eglDisplay, config, share_ctx, baseAttribs);
ctx = EGL.CreateContext(eglDisplay, ret.egl_cfg, share_ctx, baseAttribs);
}
if(ctx == NULL)
@@ -211,7 +212,7 @@ class EGLPlatform : public GLPlatform
EGLSurface surface = 0;
if(window != 0)
{
surface = EGL.CreateWindowSurface(eglDisplay, config, window, NULL);
surface = EGL.CreateWindowSurface(eglDisplay, ret.egl_cfg, window, NULL);
if(surface == NULL)
RDCERR("Couldn't create surface for window");
@@ -219,7 +220,7 @@ class EGLPlatform : public GLPlatform
else
{
static const EGLint pbAttribs[] = {EGL_WIDTH, 32, EGL_HEIGHT, 32, EGL_NONE};
surface = EGL.CreatePbufferSurface(eglDisplay, config, pbAttribs);
surface = EGL.CreatePbufferSurface(eglDisplay, ret.egl_cfg, pbAttribs);
if(surface == NULL)
RDCERR("Couldn't create a suitable PBuffer");
@@ -254,17 +255,12 @@ class EGLPlatform : public GLPlatform
int major, minor;
EGL.Initialize(eglDisplay, &major, &minor);
GLWindowingData base;
base.egl_dpy = eglDisplay;
base.egl_ctx = EGL_NO_CONTEXT;
base.egl_wnd = 0;
replayContext = MakeContext(base);
replayContext = CreateWindowingData(eglDisplay, EGL_NO_CONTEXT, 0);
if(!replayContext.ctx || !replayContext.wnd)
{
RDCERR("Couldn't create OpenGL ES 3.x replay context - required for replay");
DeleteContext(replayContext);
DeleteReplayContext(replayContext);
RDCEraseEl(replayContext);
return ReplayStatus::APIHardwareUnsupported;
}
+2 -2
View File
@@ -718,7 +718,7 @@ void DoVendorChecks(GLPlatform &platform, GLWindowingData context)
GL.glBindVertexArray(vao);
// make a context that shares with the current one, and switch to it
GLWindowingData child = platform.MakeContext(context);
GLWindowingData child = platform.CloneTemporaryContext(context);
if(child.ctx)
{
@@ -737,7 +737,7 @@ void DoVendorChecks(GLPlatform &platform, GLWindowingData context)
// switch back to context
platform.MakeContextCurrent(context);
platform.DeleteContext(child);
platform.DeleteClonedContext(child);
}
GL.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, prevFBO);
+15 -8
View File
@@ -96,7 +96,6 @@ struct GLWindowingData
wnd = NULL;
}
void SetCtx(void *c) { ctx = (HGLRC)c; }
union
{
HDC DC;
@@ -112,6 +111,8 @@ struct GLWindowingData
HWND wnd;
EGLSurface egl_wnd;
};
EGLConfig egl_cfg;
};
#elif ENABLED(RDOC_LINUX)
@@ -149,26 +150,28 @@ struct GLWindowingData
wnd = 0;
}
void SetCtx(void *c) { ctx = (GLContextPtr)c; }
#if defined(RENDERDOC_SUPPORT_GL)
typedef Display *GLDisplayPtr;
typedef GLXContext GLContextPtr;
typedef GLXDrawable GLWindowPtr;
typedef XVisualInfo *GLConfigPtr;
#else
typedef void *GLDisplayPtr;
typedef void *GLContextPtr;
typedef void *GLWindowPtr;
typedef void *GLConfigPtr;
#endif
#if defined(RENDERDOC_SUPPORT_GLES)
typedef EGLDisplay GLESDisplayPtr;
typedef EGLContext GLESContextPtr;
typedef EGLSurface GLESWindowPtr;
typedef EGLConfig GLESConfigPtr;
#else
typedef void *GLESDisplayPtr;
typedef void *GLESContextPtr;
typedef void *GLESWindowPtr;
typedef vpod *GLESConfigPtr;
#endif
union
@@ -186,6 +189,11 @@ struct GLWindowingData
GLWindowPtr wnd;
GLESWindowPtr egl_wnd;
};
union
{
GLConfigPtr cfg;
GLESConfigPtr egl_cfg;
};
};
#elif ENABLED(RDOC_APPLE)
@@ -198,7 +206,6 @@ struct GLWindowingData
wnd = 0;
}
void SetCtx(void *c) { ctx = (void *)c; }
void *ctx;
void *wnd;
};
@@ -222,19 +229,19 @@ struct GLWindowingData
egl_wnd = 0;
}
void SetCtx(void *c) { egl_ctx = (void *)c; }
union
{
// currently required to allow compatiblity with the driver parts
void *ctx;
EGLContext egl_ctx;
};
EGLDisplay egl_dpy;
union
{
EGLSurface egl_wnd;
void *wnd;
};
EGLDisplay egl_dpy;
EGLConfig egl_cfg;
};
#else
@@ -246,8 +253,8 @@ struct GLWindowingData
struct GLPlatform
{
// simple wrapper for OS functions to make/delete a context
virtual GLWindowingData MakeContext(GLWindowingData share) = 0;
virtual void DeleteContext(GLWindowingData context) = 0;
virtual GLWindowingData CloneTemporaryContext(GLWindowingData share) = 0;
virtual void DeleteClonedContext(GLWindowingData context) = 0;
virtual void DeleteReplayContext(GLWindowingData context) = 0;
virtual bool MakeContextCurrent(GLWindowingData data) = 0;
virtual void SwapBuffers(GLWindowingData context) = 0;
+5 -5
View File
@@ -3251,7 +3251,7 @@ ReplayStatus CreateReplayDevice(RDCFile *rdc, GLPlatform &platform, IReplayDrive
if(!current)
{
RDCERR("Couldn't active the created GL ES context");
platform.DeleteContext(data);
platform.DeleteReplayContext(data);
return ReplayStatus::APIInitFailed;
}
@@ -3269,14 +3269,14 @@ ReplayStatus CreateReplayDevice(RDCFile *rdc, GLPlatform &platform, IReplayDrive
if(!extensionsValidated)
{
platform.DeleteContext(data);
platform.DeleteReplayContext(data);
return ReplayStatus::APIInitFailed;
}
bool functionsValidated = ValidateFunctionPointers();
if(!functionsValidated)
{
platform.DeleteContext(data);
platform.DeleteReplayContext(data);
return ReplayStatus::APIHardwareUnsupported;
}
@@ -3299,8 +3299,8 @@ ReplayStatus CreateReplayDevice(RDCFile *rdc, GLPlatform &platform, IReplayDrive
class GLDummyPlatform : public GLPlatform
{
virtual GLWindowingData MakeContext(GLWindowingData share) { return GLWindowingData(); }
virtual void DeleteContext(GLWindowingData context) {}
virtual GLWindowingData CloneTemporaryContext(GLWindowingData share) { return GLWindowingData(); }
virtual void DeleteClonedContext(GLWindowingData context) {}
virtual void DeleteReplayContext(GLWindowingData context) {}
virtual bool MakeContextCurrent(GLWindowingData data) { return true; }
virtual void SwapBuffers(GLWindowingData context) {}
+2
View File
@@ -33,6 +33,7 @@ typedef void (*PFN_glXDestroyContext)(Display *dpy, GLXContext ctx);
typedef Bool (*PFN_glXMakeCurrent)(Display *dpy, GLXDrawable drawable, GLXContext ctx);
typedef void (*PFN_glXSwapBuffers)(Display *dpy, GLXDrawable drawable);
typedef int (*PFN_glXGetConfig)(Display *dpy, XVisualInfo *vis, int attrib, int *value);
typedef int (*PFN_glXQueryContext)(Display *dpy, GLXContext ctx, int attribute, int *value);
typedef Bool (*PFN_glXIsDirect)(Display *dpy, GLXContext ctx);
typedef __GLXextFuncPtr (*PFN_glXGetProcAddress)(const GLubyte *);
typedef __GLXextFuncPtr (*PFN_glXGetProcAddressARB)(const GLubyte *);
@@ -74,6 +75,7 @@ typedef void (*PFN_glEnd)();
#define GLX_NONHOOKED_SYMBOLS(FUNC) \
FUNC(glXGetConfig); \
FUNC(glXQueryContext); \
FUNC(glXIsDirect); \
FUNC(glXGetVisualFromFBConfig); \
FUNC(glXChooseFBConfig); \
+40 -2
View File
@@ -113,6 +113,7 @@ HOOK_EXPORT GLXContext glXCreateContext(Display *dpy, XVisualInfo *vis, GLXConte
data.dpy = dpy;
data.wnd = (GLXDrawable)NULL;
data.ctx = ret;
data.cfg = vis;
{
SCOPED_LOCK(glLock);
@@ -249,18 +250,19 @@ HOOK_EXPORT GLXContext glXCreateContextAttribsARB(Display *dpy, GLXFBConfig conf
GLX.glXGetConfig(dpy, vis, GLX_SAMPLES_ARB, &value);
init.isSRGB = RDCMAX(1, value);
XFree(vis);
GLWindowingData data;
data.dpy = dpy;
data.wnd = (GLXDrawable)NULL;
data.ctx = ret;
data.cfg = vis;
{
SCOPED_LOCK(glLock);
glxhook.driver.CreateContext(data, shareList, init, core, true);
}
XFree(vis);
return ret;
}
@@ -299,7 +301,25 @@ HOOK_EXPORT Bool glXMakeCurrent(Display *dpy, GLXDrawable drawable, GLXContext c
data.wnd = drawable;
data.ctx = ctx;
int fbconfigid = -1;
GLX.glXQueryContext(dpy, ctx, GLX_FBCONFIG_ID, &fbconfigid);
int attribs[] = {GLX_FBCONFIG_ID, fbconfigid, 0};
int numElems = 0;
GLXFBConfig *config = GLX.glXChooseFBConfig(dpy, DefaultScreen(dpy), attribs, &numElems);
if(config)
data.cfg = GLX.glXGetVisualFromFBConfig(dpy, *config);
else
data.cfg = NULL;
glxhook.driver.ActivateContext(data);
if(config)
XFree(config);
if(data.cfg)
XFree(data.cfg);
}
return ret;
@@ -341,7 +361,25 @@ HOOK_EXPORT Bool glXMakeContextCurrent(Display *dpy, GLXDrawable draw, GLXDrawab
data.wnd = draw;
data.ctx = ctx;
int fbconfigid = -1;
GLX.glXQueryContext(dpy, ctx, GLX_FBCONFIG_ID, &fbconfigid);
int attribs[] = {GLX_FBCONFIG_ID, fbconfigid, 0};
int numElems = 0;
GLXFBConfig *config = GLX.glXChooseFBConfig(dpy, DefaultScreen(dpy), attribs, &numElems);
if(config)
data.cfg = GLX.glXGetVisualFromFBConfig(dpy, *config);
else
data.cfg = NULL;
glxhook.driver.ActivateContext(data);
if(config)
XFree(config);
if(data.cfg)
XFree(data.cfg);
}
return ret;
+17 -31
View File
@@ -55,58 +55,44 @@ class GLXPlatform : public GLPlatform
return false;
}
GLWindowingData MakeContext(GLWindowingData share)
GLWindowingData CloneTemporaryContext(GLWindowingData share)
{
GLWindowingData ret = {};
GLWindowingData ret = share;
if(!GLX.glXCreateContextAttribsARB)
ret.ctx = NULL;
if(!GLX.glXCreateContext)
return ret;
const int attribs[] = {
GLX_CONTEXT_MAJOR_VERSION_ARB,
3,
GLX_CONTEXT_MINOR_VERSION_ARB,
2,
GLX_CONTEXT_FLAGS_ARB,
0,
GLX_CONTEXT_PROFILE_MASK_ARB,
GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
0,
0,
};
bool is_direct = false;
if(GLX.glXIsDirect)
is_direct = GLX.glXIsDirect(share.dpy, share.ctx);
if(GLX.glXChooseFBConfig && GLX.glXCreatePbuffer)
XVisualInfo *cfg = share.cfg;
if(cfg == NULL)
{
// don't need to care about the fb config as we won't be using the default framebuffer
// (backbuffer)
int visAttribs[] = {0};
static int visAttribs[] = {0};
int numCfgs = 0;
GLXFBConfig *fbcfg =
GLX.glXChooseFBConfig(share.dpy, DefaultScreen(share.dpy), visAttribs, &numCfgs);
// don't care about pbuffer properties as we won't render directly to this
int pbAttribs[] = {GLX_PBUFFER_WIDTH, 32, GLX_PBUFFER_HEIGHT, 32, 0};
cfg = GLX.glXGetVisualFromFBConfig(share.dpy, fbcfg[0]);
}
if(fbcfg)
{
ret.wnd = GLX.glXCreatePbuffer(share.dpy, fbcfg[0], pbAttribs);
ret.dpy = share.dpy;
ret.ctx = GLX.glXCreateContextAttribsARB(share.dpy, fbcfg[0], share.ctx, is_direct, attribs);
}
ret.ctx = GLX.glXCreateContext(share.dpy, cfg, share.ctx, is_direct);
if(cfg != share.cfg)
{
XFree(cfg);
}
return ret;
}
void DeleteContext(GLWindowingData context)
void DeleteClonedContext(GLWindowingData context)
{
if(context.wnd && GLX.glXDestroyPbuffer)
GLX.glXDestroyPbuffer(context.dpy, context.wnd);
if(context.ctx && GLX.glXDestroyContext)
GLX.glXDestroyContext(context.dpy, context.ctx);
}
+6 -4
View File
@@ -37,9 +37,11 @@ class WGLPlatform : public GLPlatform
return false;
}
GLWindowingData MakeContext(GLWindowingData share)
GLWindowingData CloneTemporaryContext(GLWindowingData share)
{
GLWindowingData ret;
GLWindowingData ret = share;
ret.ctx = NULL;
if(!WGL.wglCreateContextAttribsARB)
return ret;
@@ -55,13 +57,13 @@ class WGLPlatform : public GLPlatform
0,
0,
};
ret.DC = share.DC;
ret.ctx = WGL.wglCreateContextAttribsARB(share.DC, share.ctx, attribs);
return ret;
}
void DeleteContext(GLWindowingData context)
void DeleteClonedContext(GLWindowingData context)
{
if(context.ctx && WGL.wglDeleteContext)
WGL.wglDeleteContext(context.ctx);