google / google/filament

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

Open
#5,617 4 comments 2 reactions 0 assignees View on GitHub
linux opengl
Dominant language
C++
Stars
20.5k
Forks
2.3k
Avg merge
2d 14h
Merged PRs (30d)
83

Description

**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 https://github.com/google/filament/pull/1456 fixed my problem.

After writing some code to dump the difference between the two `GLXFBConfig`s (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

```cpp
...
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

Contributor guide

Open the contributing guide

Research direction

Start with PlatformGLX::makeCurrent() and the GLXFBConfig search introduced in pull request 1456. Reproduce the GLFW setup using a shared context, native X11 window handle, and the listed window hints, then compare the selected configurations; done means createSwapChain() and the first rendered frame no longer trigger BadMatch.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
computer-graphics
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.