Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GLX + GLFW: BadMatch with combination of shared context & native window handle #5617

Open
jfaust opened this issue Jun 1, 2022 · 4 comments
Labels
bug Something isn't working linux Issue/feature request for Linux only opengl Issue/request specific to OpenGL

Comments

@jfaust
Copy link
Contributor

jfaust commented Jun 1, 2022

Describe the bug
When passing a GL context to share into Filament and a native window handle to createSwapChain(), I get a BadMatch error thrown by the X server in the call to glXMakeContextCurrent() in PlatformGLX::makeCurrent().

Interestingly, disabling the GLXFBConfig search introduced in #1456 fixed my problem.

After writing some code to dump the difference between the two GLXFBConfigs (with & without the search), I discovered I needed:

glfwWindowHint(GLFW_ALPHA_BITS, 0);

With the default (where it's set to 8), somehow the GL context that was created was incompatible with the (glfw-created) window that was passed in.

To Reproduce
I'll try to find some time to create a repro repo, but in summary:
Using GLFW

  1. Create a 1x1 invisible window to act as the share context
  2. Create another window to use as the actual swapchain
  3. Create filament engine/swapchain/renderer, and render one frame
...
  glfwWindowHint(GLFW_SAMPLES, 1);
  glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
  glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);

 glfwWindowHint(GLFW_VISIBLE, GL_FALSE);

  glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API);
  GLFWwindow *share_win = glfwCreateWindow(1, 1, "dummy", nullptr, nullptr);

  glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);

  GLFWwindow *win = glfwCreateWindow(100, 100, "Main Window", nullptr, nullptr);

  void* share_context = (void *)glfwGetGLXContext(share_win);
  void* native_window = (void *)glfwGetX11Window(win);

  filament::Engine *engine = filament::Engine::create(
      filament::backend::Backend::OPENGL,
      nullptr,
      share_context
  );
  filament::SwapChain *swap_chain = engine->createSwapChain(native_window);

  // .. create a renderer, camera, view, etc.
  // do the main loop

Expected behavior
Ideally I'd be able to create a share context that has alpha bits in its framebuffer (though fortunately I don't need that right now). Since disabling the GLXFBConfig search results in exactly that situation, and it works, I'm very confused.

The glXMakeContextCurrent() docs also don't make it really clear to me what's going wrong.

BadMatch is generated if:
draw and read are not compatible. 
draw and read cannot fit into frame buffer memory simultaneously.
draw or read is a GLXPixmap and ctx is a direct-rendering context.
draw or read is a GLXPixmap and ctx was previously bound to a GLXWindow or GLXPbuffer.
draw or read is a GLXWindow or GLXPbuffer and ctx was previously bound to a GLXPixmap. 

The first one can't be true since draw and read are the same. The 2nd maybe, but the framebuffer I was creating is pretty small. The other three don't seem to apply, but I'm not sure.

Honestly, I'm mainly filing this ticket so if anyone else runs into this and searches for "shared context BadMatch" they'll find it.

Desktop (please complete the following information):

  • OS: Linux
  • GPU: NVIDIA GeForce GTX 980 Ti
  • Backend: OpenGL
@romainguy
Copy link
Collaborator

Right this is unfortunately a GL annoyance: shared contexts must have a compatible configuration, which often means matching the configurations. We should probably at least document our config to make it easier to match.

@jfaust
Copy link
Contributor Author

jfaust commented Jun 1, 2022

The weird part (unless I’m misunderstanding something), is that disabling the search implemented in #1456 yields a config that doesn’t match, but works. Whereas keeping the search ensures the configs match but doesn’t work. I must be missing something.

@romainguy
Copy link
Collaborator

We'd have to look at the exact differences but GL has a narrow definition of a match. Not all attributes need to match.

@jfaust
Copy link
Contributor Author

jfaust commented Jun 1, 2022

Right - my confusion comes from the fact that in the case where it's generating a BadMatch, the configs are identical. The search succeeds and retrieves the exact config that the share context is using.

Setting the context current on the dummy surface succeeds (PlatformGLX.cpp:227), but then the first time it tries to set current on the window it fails (PlatformGLX.cpp:275).

Anyway... I've created a repo demonstrating it working, as well as generating the BadMatch:
https://github.com/jfaust/filament-glfw-share-context

@romainguy romainguy added linux Issue/feature request for Linux only opengl Issue/request specific to OpenGL labels Jun 1, 2022
@bejado bejado added the bug Something isn't working label Aug 3, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working linux Issue/feature request for Linux only opengl Issue/request specific to OpenGL
Projects
None yet
Development

No branches or pull requests

3 participants