GLX Context Creation Error: GLXBadFBConfig

。_饼干妹妹 提交于 2021-02-11 04:28:36

问题


I used glXCreateContext to create the contexts, but the function is deprecated and always results in an OpenGL Version 3.0, where I would need at least 4. Now, if I have understood it right, GLXContext glXCreateContextAttribsARB(Display* dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int* attrib_list); replaced glXCreateContext. The "new" function allows for explicitly specifying the major version, minor version, profile et cetera in it's attrib_list like this for example:

int context_attribs[] =
{
    GLX_CONTEXT_MAJOR_VERSION_ARB, 4,
    GLX_CONTEXT_MINOR_VERSION_ARB, 5,
    GLX_CONTEXT_FLAGS_ARB,         GLX_CONTEXT_DEBUG_BIT_ARB,
    GLX_CONTEXT_PROFILE_MASK_ARB,  GLX_CONTEXT_COMPABILITY_PROFILE_BIT_ARB,
    None
};

Then use the function:

glXCreateContextAttribsARB(dpy, config, NULL, true, context_attribs);

That is how I have done it in my program. The window is already created and dpy is a valid pointer to Display. config I have defined like this:

// GLXFBConfig config; created at the beginning of the program
int attrib_list[] =
{
    GLX_RENDER_TYPE,    GLX_RGBA_BIT,
    GLX_RED_SIZE,       8,
    GLX_GREEN_SIZE,     8,
    GLX_BLUE_SIZE,      8,
    GLX_DEPTH_SIZE,     24,
    GLX_DOUBLEBUFFER,   True,
    None
};
int nAttribs;

config = glXChooseFBConfig(dpy, 0, attrib_list, &nAttribs);

Checking with glxinfo, I have the correct visual for it; vi has been set to 0x120, which I can confirm with glxinfo | grep 0x120. It exactly fulfills the above. So far, so good. But when running the application (compiling works fine), I get the following error:

X Error of failed request: GLXBadFBConfig
Major opcode of failed request: 152 (GLX)
Minor opcode of failed request: 34 ()
Serial number of failed request: 31
Current serial number in output stream: 31

Now, this is what the error is about:

If <config> does not support compatible OpenGL contexts providing the requested API major and minor version, forward-compatible flag, and debug context flag, GLXBadFBConfig is generated.

So, the problem is pretty straightforward. I don't know how to solve it though. What it essentially means is that no OpenGL context corresponding both to the attributes I specified in attrib_list[] and the attributes in context_attribs can be found. With glxinfo | grep Max I confirmed that my highest possible OpenGL Version is 4.5. I would like to hear your advice on what I should do now. I have played around with the attributes in context_attribs for a while, but did not get anywhere. Maybe the problem really is in another place. Maybe my conception of the GLX functions is flawed in general, please point it out if so!


回答1:


The specification of GLX_ARB_create_context is clear about when GLXBadFBConfig error may be returned:

  * If <config> does not support compatible OpenGL contexts
    providing the requested API major and minor version,
    forward-compatible flag, and debug context flag, GLXBadFBConfig
    is generated.

This maybe confusing (as error has nothing to do with already created GLXFBConfig), but I that's what we have. So the most obvious reason for the error you have is that your system doesn't actually support OpenGL 4.5 Compatible Profile you have requested - it might have, though, support OpenGL 4.5 Core Profile or compatible/core profiles of lower versions. This is a pretty common case for Mesa drivers supporting only OpenGL 3.3+ Core Profiles and just OpenGL 3.0 Compatible Profile for many GPUs (but not all - some gets better Compatible Profile support like Radeons).

If you are not familiar yet with conception of OpenGL profiles - you can start here.

glxinfo shows information about both Core and Compatible profiles, which could be filtered out like this:

glxinfo | grep -e "OpenGL version" -e "Core" -e "Compatible"

which returns this on a virtual Ubuntu 18.04 to me:

OpenGL core profile version string: 3.3 (Core Profile) Mesa 19.2.8
OpenGL version string: 3.1 Mesa 19.2.8

If your application really needs OpenGL 4.5 or higher, than just try creating a context with GLX_CONTEXT_CORE_PROFILE_BIT_ARB bit instead of GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB and ensure not using any deprecated functionality.

Note that requesting a Compatible Profile of specific version usually makes no sense - it is enough just skipping version parameters to get the highest supported one and filter out unsupported versions from GL_VERSION/GL_MAJOR_VERSION of already created context like it was done in days before profiles have been introduced. In case of a Core Profile, it might be tricky on some OpenGL drivers requesting the highest supported version (e.g. without disabled functionality of versions higher than requested) - the following code snippet could be useful:

  //! A dummy XError handler which just skips errors
  static int xErrorDummyHandler (Display* , XErrorEvent* ) { return 0; }
  ...

  Window      aWindow    = ...;
  Display*    aDisp      = ...;
  GLXFBConfig anFBConfig = ...;
  bool toDebugContext = false;

  GLXContext  aGContext  = NULL
  const char* aGlxExts   = glXQueryExtensionsString (aDisp, aVisInfo.screen);
  if (!checkGlExtension (aGlxExts, "GLX_ARB_create_context_profile"))
  {
    std::cerr << "GLX_ARB_create_context_profile is NOT supported\n";
    return;
  }

  // Replace default XError handler to ignore errors.
  // Warning - this is global for all threads!
  typedef int (*xerrorhandler_t)(Display* , XErrorEvent* );
  xerrorhandler_t anOldHandler = XSetErrorHandler(xErrorDummyHandler);

  typedef GLXContext (*glXCreateContextAttribsARB_t)(Display* dpy, GLXFBConfig config,
                                                     GLXContext share_context, Bool direct,
                                                     const int* attrib_list);
  glXCreateContextAttribsARB_t aCreateCtxProc = (glXCreateContextAttribsARB_t )glXGetProcAddress((const GLubyte* )"glXCreateContextAttribsARB");
  int aCoreCtxAttribs[] =
  {
    GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
    GLX_CONTEXT_MINOR_VERSION_ARB, 2,
    GLX_CONTEXT_PROFILE_MASK_ARB,  GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
    GLX_CONTEXT_FLAGS_ARB,         toDebugContext ? GLX_CONTEXT_DEBUG_BIT_ARB : 0,
    0, 0
  };

  // try to create a Core Profile of highest OpenGL version (up to 4.6)
  for (int aLowVer4 = 6; aLowVer4 >= 0 && aGContext == NULL; --aLowVer4)
  {
    aCoreCtxAttribs[1] = 4;
    aCoreCtxAttribs[3] = aLowVer4;
    aGContext = aCreateCtxProc (aDisp, anFBConfig, NULL, True, aCoreCtxAttribs);
  }
  for (int aLowVer3 = 3; aLowVer3 >= 2 && aGContext == NULL; --aLowVer3)
  {
    aCoreCtxAttribs[1] = 3;
    aCoreCtxAttribs[3] = aLowVer3;
    aGContext = aCreateCtxProc (aDisp, anFBConfig, NULL, True, aCoreCtxAttribs);
  }
  bool isCoreProfile = aGContext != NULL;
  if (!isCoreProfile)
  {
    std::cerr << "glXCreateContextAttribsARB() failed to create Core Profile\n";
  }

  // try to create Compatible Profile
  if (aGContext == NULL)
  {
    int aCtxAttribs[] =
    {
      GLX_CONTEXT_FLAGS_ARB, toDebugContext ? GLX_CONTEXT_DEBUG_BIT_ARB : 0,
      0, 0
    };
    aGContext = aCreateCtxProc (aDisp, anFBConfig, NULL, True, aCtxAttribs);
  }
  XSetErrorHandler (anOldHandler);

  // fallback to glXCreateContext() as last resort
  if (aGContext == NULL)
  {
    aGContext = glXCreateContext (aDisp, aVis.get(), NULL, GL_TRUE);
    if (aGContext == NULL) { std::cerr << "glXCreateContext() failed\n"; }
  }


来源:https://stackoverflow.com/questions/65531911/glx-context-creation-error-glxbadfbconfig

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!