filament icon indicating copy to clipboard operation
filament copied to clipboard

Pixel format compatibility problem on Windows

Open borodust opened this issue 4 years ago • 3 comments

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.

borodust avatar Oct 27 '21 11:10 borodust

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.

bejado avatar Oct 28 '21 17:10 bejado

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

borodust avatar Oct 28 '21 18:10 borodust

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.

pixelflinger avatar Oct 31 '21 04:10 pixelflinger