Skip to content

Commit 5a1ded7

Browse files
Michael Renniebaldurk
authored andcommitted
Moved API-specific GLReplay code to GLPlatform.
ENABLE_GL & ENABLE_GLES can now both be ON without build errors on Linux.
1 parent 2ee5f76 commit 5a1ded7

13 files changed

Lines changed: 532 additions & 617 deletions

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ if(ANDROID)
8989
message(STATUS "Disabling GL driver on android and enabling GLES")
9090
endif()
9191
set(ENABLE_GL OFF CACHE BOOL "" FORCE)
92-
set(ENABLE_GLES ON CACHE BOOL "" FORCE)
92+
set(ENABLE_GLES OFF CACHE BOOL "" FORCE)
9393

9494
# Android doesn't support the Qt UI for obvious reasons
9595
message(STATUS "Disabling qrenderdoc for android build")

renderdoc/driver/gl/gl_common.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,12 +161,20 @@ struct GLWindowingData
161161
#error "Unknown platform"
162162
#endif
163163

164+
#include "api/replay/renderdoc_replay.h"
165+
164166
struct GLPlatform
165167
{
166168
// simple wrapper for OS functions to make/delete a context
167169
virtual GLWindowingData MakeContext(GLWindowingData share) = 0;
168170
virtual void DeleteContext(GLWindowingData context) = 0;
171+
virtual void DeleteReplayContext(GLWindowingData context) = 0;
169172
virtual void MakeContextCurrent(GLWindowingData data) = 0;
173+
virtual void SwapBuffers(GLWindowingData context) = 0;
174+
virtual void GetOutputWindowDimensions(GLWindowingData context, int32_t &w, int32_t &h) = 0;
175+
virtual bool IsOutputWindowVisible(GLWindowingData context) = 0;
176+
virtual GLWindowingData MakeOutputWindow(WindowingSystem system, void *data, bool depth,
177+
GLWindowingData share_context) = 0;
170178

171179
// for 'backwards compatible' overlay rendering
172180
virtual bool DrawQuads(float width, float height, const std::vector<Vec4f> &vertices) = 0;

renderdoc/driver/gl/gl_hooks_apple.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,28 @@ class OpenGLHook : LibraryHook
4949
return GLWindowingData();
5050
}
5151
virtual void DeleteContext(GLWindowingData context) { RDCUNIMPLEMENTED("DeleteContext"); }
52+
virtual void DeleteReplayContext(GLWindowingData context)
53+
{
54+
RDCUNIMPLEMENTED("DeleteReplayContext");
55+
}
5256
virtual void MakeContextCurrent(GLWindowingData data) { RDCUNIMPLEMENTED("MakeContextCurrent"); }
57+
virtual void SwapBuffers(GLWindowingData context) { RDCUNIMPLEMENTED("SwapBuffers"); }
58+
virtual void GetOutputWindowDimensions(GLWindowingData context, int32_t &w, int32_t &h)
59+
{
60+
RDCUNIMPLEMENTED("GetOutputWindowDimensions");
61+
}
62+
virtual bool IsOutputWindowVisible(GLWindowingData context)
63+
{
64+
RDCUNIMPLEMENTED("IsOutputWindowVisible");
65+
return true;
66+
}
67+
virtual GLWindowingData MakeOutputWindow(WindowingSystem system, void *data, bool depth,
68+
GLWindowingData share_context)
69+
{
70+
RDCUNIMPLEMENTED("MakeOutputWindow");
71+
return GLWindowingData();
72+
}
73+
5374
virtual bool DrawQuads(float width, float height, const std::vector<Vec4f> &vertices)
5475
{
5576
RDCUNIMPLEMENTED("DrawQuads");

renderdoc/driver/gl/gl_hooks_egl.cpp

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ typedef EGLContext (*PFN_eglCreateContext)(EGLDisplay dpy, EGLConfig config,
4141
typedef EGLBoolean (*PFN_eglDestroyContext)(EGLDisplay dpy, EGLContext ctx);
4242
typedef EGLSurface (*PFN_eglCreatePbufferSurface)(EGLDisplay dpy, EGLConfig config,
4343
const EGLint *attrib_list);
44+
typedef EGLSurface (*PFN_eglCreateWindowSurface)(EGLDisplay dpy, EGLConfig config,
45+
EGLNativeWindowType win, const EGLint *attrib_list);
4446
typedef EGLBoolean (*PFN_eglQuerySurface)(EGLDisplay dpy, EGLSurface surface, EGLint attribute,
4547
EGLint *value);
4648
typedef EGLBoolean (*PFN_eglDestroySurface)(EGLDisplay dpy, EGLSurface surface);
@@ -174,6 +176,110 @@ class EGLHook : LibraryHook, public GLPlatform
174176
eglDestroyContext_real(context.egl_dpy, context.egl_ctx);
175177
}
176178

179+
void DeleteReplayContext(GLWindowingData context)
180+
{
181+
if(eglDestroyContext_real)
182+
{
183+
eglMakeCurrent_real(context.egl_dpy, 0L, 0L, NULL);
184+
eglDestroyContext_real(context.egl_dpy, context.egl_ctx);
185+
}
186+
}
187+
188+
void SwapBuffers(GLWindowingData context)
189+
{
190+
eglSwapBuffers_real(context.egl_dpy, context.egl_wnd);
191+
}
192+
193+
void GetOutputWindowDimensions(GLWindowingData context, int32_t &w, int32_t &h)
194+
{
195+
eglQuerySurface_real(context.egl_dpy, context.egl_wnd, EGL_WIDTH, &w);
196+
eglQuerySurface_real(context.egl_dpy, context.egl_wnd, EGL_HEIGHT, &h);
197+
}
198+
199+
bool IsOutputWindowVisible(GLWindowingData context) { return true; }
200+
GLWindowingData MakeOutputWindow(WindowingSystem system, void *data, bool depth,
201+
GLWindowingData share_context)
202+
{
203+
GLWindowingData ret;
204+
EGLNativeWindowType window = 0;
205+
206+
if(system == eWindowingSystem_Xlib)
207+
{
208+
XlibWindowData *xlib = (XlibWindowData *)data;
209+
window = (EGLNativeWindowType)xlib->window;
210+
}
211+
else if(system == eWindowingSystem_Unknown)
212+
{
213+
// allow undefined so that internally we can create a window-less context
214+
Display *dpy = XOpenDisplay(NULL);
215+
216+
if(dpy == NULL)
217+
return ret;
218+
}
219+
else
220+
{
221+
RDCERR("Unexpected window system %u", system);
222+
}
223+
224+
EGLDisplay eglDisplay = eglGetDisplay_real(EGL_DEFAULT_DISPLAY);
225+
RDCASSERT(eglDisplay);
226+
227+
static const EGLint configAttribs[] = {EGL_RED_SIZE,
228+
8,
229+
EGL_GREEN_SIZE,
230+
8,
231+
EGL_BLUE_SIZE,
232+
8,
233+
EGL_RENDERABLE_TYPE,
234+
EGL_OPENGL_ES3_BIT,
235+
EGL_SURFACE_TYPE,
236+
EGL_PBUFFER_BIT | EGL_WINDOW_BIT,
237+
EGL_NONE};
238+
239+
PFN_eglChooseConfig eglChooseConfig = (PFN_eglChooseConfig)dlsym(RTLD_NEXT, "eglChooseConfig");
240+
PFN_eglCreateWindowSurface eglCreateWindowSurface =
241+
(PFN_eglCreateWindowSurface)dlsym(RTLD_NEXT, "eglCreateWindowSurfaceProc");
242+
PFN_eglCreatePbufferSurface eglCreatePbufferSurface =
243+
(PFN_eglCreatePbufferSurface)dlsym(RTLD_NEXT, "eglCreatePbufferSurface");
244+
245+
EGLint numConfigs;
246+
EGLConfig config;
247+
if(!eglChooseConfig(eglDisplay, configAttribs, &config, 1, &numConfigs))
248+
{
249+
RDCERR("Couldn't find a suitable EGL config");
250+
return ret;
251+
}
252+
253+
static const EGLint ctxAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, 3, EGL_CONTEXT_FLAGS_KHR,
254+
EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR, EGL_NONE};
255+
256+
EGLContext ctx = eglCreateContext_real(eglDisplay, config, EGL_NO_CONTEXT, ctxAttribs);
257+
258+
if(ctx == NULL)
259+
{
260+
RDCERR("Couldn't create GL ES context");
261+
return ret;
262+
}
263+
264+
EGLSurface surface = 0;
265+
266+
if(window != 0)
267+
{
268+
surface = eglCreateWindowSurface(eglDisplay, config, window, NULL);
269+
}
270+
else
271+
{
272+
static const EGLint pbAttribs[] = {EGL_WIDTH, 32, EGL_HEIGHT, 32, EGL_NONE};
273+
surface = eglCreatePbufferSurface(eglDisplay, config, pbAttribs);
274+
}
275+
276+
ret.egl_dpy = eglDisplay;
277+
ret.egl_ctx = ctx;
278+
ret.egl_wnd = surface;
279+
280+
return ret;
281+
}
282+
177283
bool DrawQuads(float width, float height, const std::vector<Vec4f> &vertices);
178284

179285
WrappedOpenGL *GetDriver()

renderdoc/driver/gl/gl_hooks_linux.cpp

Lines changed: 160 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -153,22 +153,20 @@ class OpenGLHook : LibraryHook, public GLPlatform
153153
bool is_direct = false;
154154

155155
PFNGLXISDIRECTPROC glXIsDirectProc = (PFNGLXISDIRECTPROC)dlsym(RTLD_NEXT, "glXIsDirect");
156-
PFNGLXCHOOSEFBCONFIGPROC glXChooseFBConfigProc =
157-
(PFNGLXCHOOSEFBCONFIGPROC)dlsym(RTLD_NEXT, "glXChooseFBConfig");
158156
PFNGLXCREATEPBUFFERPROC glXCreatePbufferProc =
159157
(PFNGLXCREATEPBUFFERPROC)dlsym(RTLD_NEXT, "glXCreatePbuffer");
160158

161159
if(glXIsDirectProc)
162160
is_direct = glXIsDirectProc(share.dpy, share.ctx);
163161

164-
if(glXChooseFBConfigProc && glXCreatePbufferProc)
162+
if(glXChooseFBConfig_real && glXCreatePbufferProc)
165163
{
166164
// don't need to care about the fb config as we won't be using the default framebuffer
167165
// (backbuffer)
168166
int visAttribs[] = {0};
169167
int numCfgs = 0;
170168
GLXFBConfig *fbcfg =
171-
glXChooseFBConfigProc(share.dpy, DefaultScreen(share.dpy), visAttribs, &numCfgs);
169+
glXChooseFBConfig_real(share.dpy, DefaultScreen(share.dpy), visAttribs, &numCfgs);
172170

173171
// don't care about pbuffer properties as we won't render directly to this
174172
int pbAttribs[] = {GLX_PBUFFER_WIDTH, 32, GLX_PBUFFER_HEIGHT, 32, 0};
@@ -197,6 +195,157 @@ class OpenGLHook : LibraryHook, public GLPlatform
197195
glXDestroyContext_real(context.dpy, context.ctx);
198196
}
199197

198+
void DeleteReplayContext(GLWindowingData context)
199+
{
200+
if(glXDestroyContext_real)
201+
{
202+
glXMakeContextCurrent_real(context.dpy, 0L, 0L, NULL);
203+
glXDestroyContext_real(context.dpy, context.ctx);
204+
}
205+
}
206+
207+
void SwapBuffers(GLWindowingData context) { glXSwapBuffers_real(context.dpy, context.wnd); }
208+
void GetOutputWindowDimensions(GLWindowingData context, int32_t &w, int32_t &h)
209+
{
210+
glXQueryDrawable_real(context.dpy, context.wnd, GLX_WIDTH, (unsigned int *)&w);
211+
glXQueryDrawable_real(context.dpy, context.wnd, GLX_HEIGHT, (unsigned int *)&h);
212+
}
213+
214+
bool IsOutputWindowVisible(GLWindowingData context)
215+
{
216+
GLNOTIMP("Optimisation missing - output window always returning true");
217+
218+
return true;
219+
}
220+
221+
GLWindowingData MakeOutputWindow(WindowingSystem system, void *data, bool depth,
222+
GLWindowingData share_context)
223+
{
224+
GLWindowingData ret;
225+
226+
Display *dpy = NULL;
227+
Drawable draw = 0;
228+
229+
if(system == eWindowingSystem_Xlib)
230+
{
231+
#if ENABLED(RDOC_XLIB)
232+
XlibWindowData *xlib = (XlibWindowData *)data;
233+
234+
dpy = xlib->display;
235+
draw = xlib->window;
236+
#else
237+
RDCERR(
238+
"Xlib windowing system data passed in, but support is not compiled in. GL must have xlib "
239+
"support compiled in");
240+
#endif
241+
}
242+
else if(system == eWindowingSystem_Unknown)
243+
{
244+
// allow undefined so that internally we can create a window-less context
245+
dpy = XOpenDisplay(NULL);
246+
247+
if(dpy == NULL)
248+
return ret;
249+
}
250+
else
251+
{
252+
RDCERR("Unexpected window system %u", system);
253+
}
254+
255+
static int visAttribs[] = {GLX_X_RENDERABLE,
256+
True,
257+
GLX_DRAWABLE_TYPE,
258+
GLX_WINDOW_BIT,
259+
GLX_RENDER_TYPE,
260+
GLX_RGBA_BIT,
261+
GLX_X_VISUAL_TYPE,
262+
GLX_TRUE_COLOR,
263+
GLX_RED_SIZE,
264+
8,
265+
GLX_GREEN_SIZE,
266+
8,
267+
GLX_BLUE_SIZE,
268+
8,
269+
GLX_DOUBLEBUFFER,
270+
True,
271+
GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB,
272+
True,
273+
0};
274+
int numCfgs = 0;
275+
GLXFBConfig *fbcfg = glXChooseFBConfig_real(dpy, DefaultScreen(dpy), visAttribs, &numCfgs);
276+
277+
if(fbcfg == NULL)
278+
{
279+
XCloseDisplay(dpy);
280+
RDCERR("Couldn't choose default framebuffer config");
281+
return ret;
282+
}
283+
284+
if(draw != 0)
285+
{
286+
// Choose FB config with a GLX_VISUAL_ID that matches the X screen.
287+
VisualID visualid_correct = DefaultVisual(dpy, DefaultScreen(dpy))->visualid;
288+
for(int i = 0; i < numCfgs; i++)
289+
{
290+
int visualid;
291+
glXGetFBConfigAttrib(dpy, fbcfg[i], GLX_VISUAL_ID, &visualid);
292+
if((VisualID)visualid == visualid_correct)
293+
{
294+
fbcfg[0] = fbcfg[i];
295+
break;
296+
}
297+
}
298+
}
299+
300+
int attribs[64] = {0};
301+
int i = 0;
302+
303+
attribs[i++] = GLX_CONTEXT_MAJOR_VERSION_ARB;
304+
attribs[i++] = GLCoreVersion / 10;
305+
attribs[i++] = GLX_CONTEXT_MINOR_VERSION_ARB;
306+
attribs[i++] = GLCoreVersion % 10;
307+
attribs[i++] = GLX_CONTEXT_FLAGS_ARB;
308+
#if ENABLED(RDOC_DEVEL)
309+
attribs[i++] = GLX_CONTEXT_DEBUG_BIT_ARB;
310+
#else
311+
attribs[i++] = 0;
312+
#endif
313+
attribs[i++] = GLX_CONTEXT_PROFILE_MASK_ARB;
314+
attribs[i++] = GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
315+
316+
GLXContext ctx = glXCreateContextAttribsARB_real(dpy, fbcfg[0], share_context.ctx, true, attribs);
317+
318+
if(ctx == NULL)
319+
{
320+
XCloseDisplay(dpy);
321+
RDCERR("Couldn't create %d.%d context - something changed since creation", GLCoreVersion / 10,
322+
GLCoreVersion % 10);
323+
return ret;
324+
}
325+
326+
GLXDrawable wnd = 0;
327+
328+
if(draw == 0)
329+
{
330+
// don't care about pbuffer properties as we won't render directly to this
331+
int pbAttribs[] = {GLX_PBUFFER_WIDTH, 32, GLX_PBUFFER_HEIGHT, 32, 0};
332+
333+
wnd = glXCreatePbuffer(dpy, fbcfg[0], pbAttribs);
334+
}
335+
else
336+
{
337+
wnd = glXCreateWindow(dpy, fbcfg[0], draw, 0);
338+
}
339+
340+
XFree(fbcfg);
341+
342+
ret.dpy = dpy;
343+
ret.ctx = ctx;
344+
ret.wnd = wnd;
345+
346+
return ret;
347+
}
348+
200349
bool DrawQuads(float width, float height, const std::vector<Vec4f> &vertices);
201350

202351
WrappedOpenGL *GetDriver()
@@ -218,6 +367,8 @@ class OpenGLHook : LibraryHook, public GLPlatform
218367
PFNGLXGETVISUALFROMFBCONFIGPROC glXGetVisualFromFBConfig_real;
219368
PFNGLXCREATEWINDOWPROC glXCreateWindow_real;
220369
PFNGLXDESTROYWINDOWPROC glXDestroyWindow_real;
370+
PFNGLXCHOOSEFBCONFIGPROC glXChooseFBConfig_real;
371+
PFNGLXQUERYDRAWABLEPROC glXQueryDrawable_real;
221372

222373
set<GLXContext> m_Contexts;
223374

@@ -258,6 +409,11 @@ class OpenGLHook : LibraryHook, public GLPlatform
258409
glXCreateWindow_real = (PFNGLXCREATEWINDOWPROC)dlsym(libGLdlsymHandle, "glXCreateWindow");
259410
if(glXDestroyWindow_real == NULL)
260411
glXDestroyWindow_real = (PFNGLXDESTROYWINDOWPROC)dlsym(libGLdlsymHandle, "glXDestroyWindow");
412+
if(glXChooseFBConfig_real == NULL)
413+
glXChooseFBConfig_real =
414+
(PFNGLXCHOOSEFBCONFIGPROC)dlsym(libGLdlsymHandle, "glXChooseFBConfig");
415+
if(glXQueryDrawable_real == NULL)
416+
glXQueryDrawable_real = (PFNGLXQUERYDRAWABLEPROC)dlsym(RTLD_NEXT, "glXQueryDrawable");
261417

262418
return success;
263419
}

0 commit comments

Comments
 (0)