bool GLReplay::CheckResizeOutputWindow(uint64_t id) { if(id == 0 || m_OutputWindows.find(id) == m_OutputWindows.end()) return false; OutputWindow &outw = m_OutputWindows[id]; if(outw.wnd == 0) return false; int32_t w, h; GetOutputWindowDimensions(id, w, h); if(w != outw.width || h != outw.height) { outw.width = w; outw.height = h; MakeCurrentReplayContext(m_DebugCtx); WrappedOpenGL &gl = *m_pDriver; gl.glDeleteTextures(1, &outw.BlitData.backbuffer); gl.glDeleteFramebuffers(1, &outw.BlitData.windowFBO); CreateOutputWindowBackbuffer(outw); return true; } return false; }
uint64_t GLReplay::MakeOutputWindow(void *wn, bool depth) { void **displayAndDrawable = (void **)wn; Display *dpy = NULL; GLXDrawable wnd = 0; if(wn) { dpy = (Display *)displayAndDrawable[0]; wnd = (GLXDrawable)displayAndDrawable[1]; } else { dpy = XOpenDisplay(NULL); if(dpy == NULL) return 0; } static int visAttribs[] = { GLX_X_RENDERABLE, True, GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, GLX_RENDER_TYPE, GLX_RGBA_BIT, GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR, GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, GLX_ALPHA_SIZE, 8, GLX_DOUBLEBUFFER, True, GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB, True, 0 }; int numCfgs = 0; GLXFBConfig *fbcfg = glXChooseFBConfigProc(dpy, DefaultScreen(dpy), visAttribs, &numCfgs); if(fbcfg == NULL) { XCloseDisplay(dpy); RDCERR("Couldn't choose default framebuffer config"); return eReplayCreate_APIInitFailed; } int attribs[64] = {0}; int i=0; attribs[i++] = GLX_CONTEXT_MAJOR_VERSION_ARB; attribs[i++] = 4; attribs[i++] = GLX_CONTEXT_MINOR_VERSION_ARB; attribs[i++] = 3; attribs[i++] = GLX_CONTEXT_FLAGS_ARB; attribs[i++] = GLX_CONTEXT_DEBUG_BIT_ARB; attribs[i++] = GLX_CONTEXT_PROFILE_MASK_ARB; attribs[i++] = GLX_CONTEXT_CORE_PROFILE_BIT_ARB; GLXContext ctx = glXCreateContextAttribsProc(dpy, fbcfg[0], m_ReplayCtx.ctx, true, attribs); if(ctx == NULL) { XCloseDisplay(dpy); RDCERR("Couldn't create 4.3 context - RenderDoc requires OpenGL 4.3 availability"); return 0; } if(wnd == 0) { // 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 }; wnd = glXCreatePbufferProc(dpy, fbcfg[0], pbAttribs); } XFree(fbcfg); OutputWindow win; win.dpy = dpy; win.ctx = ctx; win.wnd = wnd; glXQueryDrawableProc(dpy, wnd, GLX_WIDTH, (unsigned int *)&win.width); glXQueryDrawableProc(dpy, wnd, GLX_HEIGHT, (unsigned int *)&win.height); MakeCurrentReplayContext(&win); InitOutputWindow(win); CreateOutputWindowBackbuffer(win, depth); uint64_t ret = m_OutputWindowID++; m_OutputWindows[ret] = win; return ret; }
uint64_t GLReplay::MakeOutputWindow(WindowingSystem system, void *data, bool depth) { Display *dpy = NULL; Drawable draw = 0; if(system == eWindowingSystem_Xlib) { #if ENABLED(RDOC_XLIB) XlibWindowData *xlib = (XlibWindowData *)data; dpy = xlib->display; draw = xlib->window; #else RDCERR( "Xlib windowing system data passed in, but support is not compiled in. GL must have xlib " "support compiled in"); #endif } else if(system == eWindowingSystem_Unknown) { // allow undefined so that internally we can create a window-less context dpy = XOpenDisplay(NULL); if(dpy == NULL) return 0; } else { RDCERR("Unexpected window system %u", system); } static int visAttribs[] = {GLX_X_RENDERABLE, True, GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, GLX_RENDER_TYPE, GLX_RGBA_BIT, GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR, GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, GLX_DOUBLEBUFFER, True, GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB, True, 0}; int numCfgs = 0; GLXFBConfig *fbcfg = glXChooseFBConfigProc(dpy, DefaultScreen(dpy), visAttribs, &numCfgs); if(fbcfg == NULL) { XCloseDisplay(dpy); RDCERR("Couldn't choose default framebuffer config"); return eReplayCreate_APIInitFailed; } if(draw != 0) { // Choose FB config with a GLX_VISUAL_ID that matches the X screen. VisualID visualid_correct = DefaultVisual(dpy, DefaultScreen(dpy))->visualid; for(int i = 0; i < numCfgs; i++) { int visualid; glXGetFBConfigAttrib(dpy, fbcfg[i], GLX_VISUAL_ID, &visualid); if((VisualID)visualid == visualid_correct) { fbcfg[0] = fbcfg[i]; break; } } } int attribs[64] = {0}; int i = 0; attribs[i++] = GLX_CONTEXT_MAJOR_VERSION_ARB; attribs[i++] = 4; attribs[i++] = GLX_CONTEXT_MINOR_VERSION_ARB; attribs[i++] = 3; attribs[i++] = GLX_CONTEXT_FLAGS_ARB; #if ENABLED(RDOC_DEVEL) attribs[i++] = GLX_CONTEXT_DEBUG_BIT_ARB; #else attribs[i++] = 0; #endif attribs[i++] = GLX_CONTEXT_PROFILE_MASK_ARB; attribs[i++] = GLX_CONTEXT_CORE_PROFILE_BIT_ARB; GLXContext ctx = glXCreateContextAttribsProc(dpy, fbcfg[0], m_ReplayCtx.ctx, true, attribs); if(ctx == NULL) { XCloseDisplay(dpy); RDCERR("Couldn't create 4.3 context - RenderDoc requires OpenGL 4.3 availability"); return 0; } GLXDrawable wnd = 0; if(draw == 0) { // 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}; wnd = glXCreatePbufferProc(dpy, fbcfg[0], pbAttribs); } else { wnd = glXCreateWindow(dpy, fbcfg[0], draw, 0); } XFree(fbcfg); OutputWindow win; win.dpy = dpy; win.ctx = ctx; win.wnd = wnd; glXQueryDrawableProc(dpy, wnd, GLX_WIDTH, (unsigned int *)&win.width); glXQueryDrawableProc(dpy, wnd, GLX_HEIGHT, (unsigned int *)&win.height); MakeCurrentReplayContext(&win); InitOutputWindow(win); CreateOutputWindowBackbuffer(win, depth); uint64_t ret = m_OutputWindowID++; m_OutputWindows[ret] = win; return ret; }