filament
filament copied to clipboard
Pixel format compatibility problem on Windows
Describe the bug TL;DR:
SetPixelFormat(swapChain->hDc, pixelFormat, &mPfd);
SetPixelFormat can only be called once for a particular window on Windows. This behavior is specified in WinAPI docs. Meaning createSwapChain expects a window that doesn't have pixel format set. If this is a requirement, docs for SwapChain probably must mention that. What's more misleading, is that example explains how to get it from SDL, but the problem is that SDL always call SetPixelFormat for its windows meaning Filament's call always ignored.
The issue might be related to https://github.com/google/filament/issues/1921
Expected behavior Documentation should probably mention this Windows-specific behavior.
I'm unsure what would be a better solution without breaking Filament's API.
Maybe users should provide context explicitly, just like shared context can be passed for a driver to be created. Because window creation seems to be out of Filament's scope, it must be specified that 24bit depth buffer and OpenGL 4.1 required (for OpenGL backend).
Logs
in void __cdecl filament::PlatformWGL::makeCurrent(struct filament::backend::Platform::SwapChain *,struct filament::backend::Platform::SwapChain *) noexcept:245
reason: wglMakeCurrent() failed. hdc = FFFFFFFFE8010DB8
Windows error code: 2000. (null)
Desktop:
- OS: Windows 10 x64
- GPU: NVIDIA RTX 2080Ti, some Intel GPU, some AMD GPU (If required, I can look them up better)
- Backend: OpenGL
Usecase
I use Filament as a main rendering engine that controls window buffers (non-headless SwapChain) and Skia as a secondary rendering option for 2D that outputs into a Filament texture in its own rendering thread. For that to work I use shared OpenGL contexts.
On Linux platforms, this seemed to work, while on some Windows machines there was a black screen instead of a proper output. stderr had errors that Pixel Format was not compatible. Apparently, some drivers might select different and incompatible pixel formats for my SDL window and hidden Filament STATIC dummy window. I figured I could enforce same values as in Filament's PIXELFORMATDESCRIPTOR through SDL_GL_SetAttribute, but no, just matching those numbers with FIlament's doesn't work on different machines either.
Workaround
So here's what I do now: I create this same window Filament uses internally to figure out exactly the same pixel format Filament receives, and set those values as SDL's GL attrib hints. This seems to work across different vendors.
This looks like a very brittle solution that relies on internal knowledge of Filament and how it exactly fills PIXELFORMATDESCRIPTOR.
Thanks for the report. I think our best option now is to update the documentation for SwapChain. We're not particularly attached to SDL and may switch in the future. I'm curious how other libraries handle this.
Skia, as an example, exposes some of a driver machinery giving more leverage to a user: https://skia.org/docs/user/api/skcanvas_creation/#gpu
One solution, even if kind of lame, would be for us to always do a blit, and never try to register in the swapchain directly on windows.