mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-06 01:50:38 +00:00
Add workaround for strange systems with difficult visualinfo setups
This commit is contained in:
@@ -29,6 +29,63 @@
|
||||
|
||||
#include "../linux/linux_window.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
int visual_id = 0;
|
||||
};
|
||||
|
||||
static GLXFBConfig *GetGLXFBConfigs(Display *dpy)
|
||||
{
|
||||
// GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB MUST be the last attrib so that we can remove it to retry
|
||||
// if we find no srgb fbconfigs
|
||||
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_DEPTH_SIZE,
|
||||
0,
|
||||
GLX_STENCIL_SIZE,
|
||||
0,
|
||||
GLX_DOUBLEBUFFER,
|
||||
True,
|
||||
GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB,
|
||||
True,
|
||||
0};
|
||||
|
||||
int numCfgs = 0;
|
||||
GLXFBConfig *fbcfg = glXChooseFBConfig(dpy, DefaultScreen(dpy), visAttribs, &numCfgs);
|
||||
|
||||
if(fbcfg == NULL)
|
||||
{
|
||||
const size_t len = ARRAY_COUNT(visAttribs);
|
||||
if(visAttribs[len - 3] != GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB)
|
||||
{
|
||||
TEST_ERROR(
|
||||
"GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB isn't the last attribute, and no SRGB fbconfigs were "
|
||||
"found!");
|
||||
}
|
||||
else
|
||||
{
|
||||
visAttribs[len - 3] = 0;
|
||||
fbcfg = glXChooseFBConfig(dpy, DefaultScreen(dpy), visAttribs, &numCfgs);
|
||||
}
|
||||
}
|
||||
|
||||
return fbcfg;
|
||||
}
|
||||
|
||||
void OpenGLGraphicsTest::Prepare(int argc, char **argv)
|
||||
{
|
||||
GraphicsTest::Prepare(argc, argv);
|
||||
@@ -58,7 +115,19 @@ bool OpenGLGraphicsTest::Init()
|
||||
|
||||
gladLoadGLX(dpy, DefaultScreen(dpy));
|
||||
|
||||
mainWindow = new X11Window(screenWidth, screenHeight, screenTitle);
|
||||
// on some systems we need to choose a visual in advance that will be compatible if we want an
|
||||
// RGBA backbuffer. Do that now
|
||||
{
|
||||
Display *display = X11Window::GetDisplay();
|
||||
|
||||
GLXFBConfig *fbcfg = GetGLXFBConfigs(display);
|
||||
|
||||
glXGetFBConfigAttrib(display, fbcfg[0], GLX_VISUAL_ID, &visual_id);
|
||||
|
||||
XFree(fbcfg);
|
||||
}
|
||||
|
||||
mainWindow = new X11Window(screenWidth, screenHeight, visual_id, screenTitle);
|
||||
|
||||
mainContext = MakeContext(mainWindow, NULL);
|
||||
|
||||
@@ -85,7 +154,7 @@ bool OpenGLGraphicsTest::Init()
|
||||
|
||||
GraphicsWindow *OpenGLGraphicsTest::MakeWindow(int width, int height, const char *title)
|
||||
{
|
||||
return new X11Window(width, height, title);
|
||||
return new X11Window(width, height, visual_id, title);
|
||||
}
|
||||
|
||||
void *OpenGLGraphicsTest::MakeContext(GraphicsWindow *win, void *share)
|
||||
@@ -118,50 +187,8 @@ void *OpenGLGraphicsTest::MakeContext(GraphicsWindow *win, void *share)
|
||||
else
|
||||
attribs[i++] = GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
|
||||
|
||||
// GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB MUST be the last attrib so that we can remove it to retry
|
||||
// if we find no srgb fbconfigs
|
||||
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 = glXChooseFBConfig(x11win->xlib.display, DefaultScreen(x11win->xlib.display),
|
||||
visAttribs, &numCfgs);
|
||||
|
||||
if(fbcfg == NULL)
|
||||
{
|
||||
const size_t len = ARRAY_COUNT(visAttribs);
|
||||
if(visAttribs[len - 3] != GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB)
|
||||
{
|
||||
TEST_ERROR(
|
||||
"GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB isn't the last attribute, and no SRGB fbconfigs were "
|
||||
"found!");
|
||||
}
|
||||
else
|
||||
{
|
||||
visAttribs[len - 3] = 0;
|
||||
fbcfg = glXChooseFBConfig(x11win->xlib.display, DefaultScreen(x11win->xlib.display),
|
||||
visAttribs, &numCfgs);
|
||||
}
|
||||
}
|
||||
Display *dpy = x11win->xlib.display;
|
||||
GLXFBConfig *fbcfg = GetGLXFBConfigs(dpy);
|
||||
|
||||
if(fbcfg == NULL)
|
||||
{
|
||||
@@ -169,19 +196,8 @@ void *OpenGLGraphicsTest::MakeContext(GraphicsWindow *win, void *share)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Choose FB config with a GLX_VISUAL_ID that matches the X screen.
|
||||
VisualID visualid_correct =
|
||||
DefaultVisual(x11win->xlib.display, DefaultScreen(x11win->xlib.display))->visualid;
|
||||
for(int i = 0; i < numCfgs; i++)
|
||||
{
|
||||
int visualid;
|
||||
glXGetFBConfigAttrib(x11win->xlib.display, fbcfg[i], GLX_VISUAL_ID, &visualid);
|
||||
if((VisualID)visualid == visualid_correct)
|
||||
{
|
||||
fbcfg[0] = fbcfg[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
// we should have selected a compatible visual with the first fbcfg when creating the window, so
|
||||
// we can use fbcfg[0]
|
||||
|
||||
GLXContext ctx =
|
||||
glXCreateContextAttribsARB(x11win->xlib.display, fbcfg[0], (GLXContext)share, true, attribs);
|
||||
|
||||
@@ -54,7 +54,7 @@ Display *X11Window::GetDisplay()
|
||||
return display;
|
||||
}
|
||||
|
||||
X11Window::X11Window(int width, int height, const char *title)
|
||||
X11Window::X11Window(int width, int height, int visualid_override, const char *title)
|
||||
{
|
||||
uint32_t value_mask, value_list[32];
|
||||
|
||||
@@ -65,8 +65,19 @@ X11Window::X11Window(int width, int height, const char *title)
|
||||
value_list[1] =
|
||||
XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_STRUCTURE_NOTIFY;
|
||||
|
||||
xcb_visualid_t visual = screen->root_visual;
|
||||
|
||||
if(visualid_override)
|
||||
{
|
||||
visual = (xcb_visualid_t)visualid_override;
|
||||
|
||||
value_mask |= XCB_CW_COLORMAP;
|
||||
value_list[2] = xcb_generate_id(connection);
|
||||
xcb_create_colormap(connection, XCB_COLORMAP_ALLOC_NONE, value_list[2], screen->root, visual);
|
||||
}
|
||||
|
||||
xcb_create_window(connection, XCB_COPY_FROM_PARENT, window, screen->root, 0, 0, width, height, 0,
|
||||
XCB_WINDOW_CLASS_INPUT_OUTPUT, screen->root_visual, value_mask, value_list);
|
||||
XCB_WINDOW_CLASS_INPUT_OUTPUT, visual, value_mask, value_list);
|
||||
|
||||
/* Magic code that will send notification when window is destroyed */
|
||||
xcb_intern_atom_cookie_t cookie = xcb_intern_atom(connection, 1, 12, "WM_PROTOCOLS");
|
||||
|
||||
@@ -33,7 +33,7 @@ struct X11Window : public GraphicsWindow
|
||||
static void Init();
|
||||
static Display *GetDisplay();
|
||||
|
||||
X11Window(int width, int height, const char *title);
|
||||
X11Window(int width, int height, int visualid_override, const char *title);
|
||||
~X11Window();
|
||||
void Resize(int width, int height);
|
||||
bool Update();
|
||||
|
||||
@@ -513,7 +513,7 @@ VulkanWindow *VulkanGraphicsTest::MakeWindow(int width, int height, const char *
|
||||
#if defined(WIN32)
|
||||
GraphicsWindow *platWin = new Win32Window(width, height, title);
|
||||
#else
|
||||
GraphicsWindow *platWin = new X11Window(width, height, title);
|
||||
GraphicsWindow *platWin = new X11Window(width, height, 0, title);
|
||||
#endif
|
||||
|
||||
return new VulkanWindow(this, platWin);
|
||||
|
||||
Reference in New Issue
Block a user