unoplatform/uno · critical · InvalidOperationException
ChoosePixelFormat failed
Error message
ChoosePixelFormat failed
What it means
WinUINativeOpenGLWrapper (Windows OpenGL host for GLCanvasElement) calls GDI ChoosePixelFormat on the window's HDC with a PIXELFORMATDESCRIPTOR requesting double-buffer, RGBA, 24-bit color, 8-bit stencil, 16-bit depth. ChoosePixelFormat returns 0 when no pixel format on the device matches the descriptor or the HDC is invalid. The wrapper throws InvalidOperationException, halting GL context creation.
Source
Thrown at src/AddIns/Uno.WinUI.Graphics3DGL/Windows/WinUINativeOpenGLWrapper.cs:63
pfd.iPixelType = WindowsRenderingNativeMethods.PFD_TYPE_RGBA;
pfd.cColorBits = 32;
pfd.cRedBits = 8;
pfd.cGreenBits = 8;
pfd.cBlueBits = 8;
pfd.cAlphaBits = 8;
pfd.cDepthBits = 16;
pfd.cStencilBits = 1; // anything > 0 is fine, we will most likely get 8
pfd.iLayerType = WindowsRenderingNativeMethods.PFD_MAIN_PLANE;
var pixelFormat = WindowsRenderingNativeMethods.ChoosePixelFormat(_hdc, ref pfd);
// To inspect the chosen pixel format:
// WindowsRenderingNativeMethods.PIXELFORMATDESCRIPTOR temp_pfd = default;
// WindowsRenderingNativeMethods.DescribePixelFormat(_hdc, _pixelFormat, (uint)Marshal.SizeOf<WindowsRenderingNativeMethods.PIXELFORMATDESCRIPTOR>(), ref temp_pfd);
if (pixelFormat == 0)
{
throw new InvalidOperationException("ChoosePixelFormat failed");
}
if (WindowsRenderingNativeMethods.SetPixelFormat(_hdc, pixelFormat, ref pfd) == 0)
{
throw new InvalidOperationException("SetPixelFormat failed");
}
_glContext = WindowsRenderingNativeMethods.wglCreateContext(_hdc);
if (_glContext == IntPtr.Zero)
{
throw new InvalidOperationException("wglCreateContext failed");
}
}
// https://sharovarskyi.com/blog/posts/csharp-win32-opengl-silknet/
public bool TryGetProcAddress(string proc, out nint addr)
{View on GitHub (pinned to 0418340488)
Solutions
- Ensure the window is created and its HDC is valid before calling ChoosePixelFormat (realize the HWND first).
- Relax the PIXELFORMATDESCRIPTOR (drop stencil, reduce depth bits) and retry; some software renderers only match minimal formats.
- Update/repair GPU drivers; on RDP, enable RemoteFX or test locally.
- Confirm the DC has not already had a different pixel format applied (it cannot be changed after SetPixelFormat on some implementations).
Defensive patterns
Strategy: validation
Validate before calling
if (_hdc == IntPtr.Zero) throw new InvalidOperationException("HDC not ready; realize the window first.");
var pf = WindowsRenderingNativeMethods.ChoosePixelFormat(_hdc, ref pfd);
if (pf == 0) { /* log GetLastError, relax descriptor, retry */ } Prevention
- Ensure the HWND is created and its HDC valid before pixel format selection.
- Relax depth/stencil requirements if no format matches.
- Update GPU drivers; avoid RDP sessions without GPU/RemoteFX for GL.
When it happens
Trigger: HDC is null/invalid (window not realized before init); the display driver exposes no pixel format matching the requested depth/stencil/double-buffer combination; running over Remote Desktop / a software renderer with reduced format support; the DC was already released.
Common situations: Headless or RDP session with no hardware accelerated pixel format; the OpenGL host initialized before the HWND/HDC is ready; outdated/missing GPU drivers; conflicting pixel format already set on the DC (a DC can only have its pixel format set once).
Related errors
- SetPixelFormat failed
- wglCreateContext failed
- No function was found with the name {proc}.
- PInvoke.RegisterClassEx failed: {Win32Helper.GetErrorMessage
- PInvoke.CreateWindowEx failed: {Win32Helper.GetErrorMessage(
AI-assisted analysis of unoplatform/uno@0418340488 (2026-08-13).
Data as JSON: /api/errors/2855d6e11dbb0b7a.
Report an issue: GitHub.