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

  1. Ensure the window is created and its HDC is valid before calling ChoosePixelFormat (realize the HWND first).
  2. Relax the PIXELFORMATDESCRIPTOR (drop stencil, reduce depth bits) and retry; some software renderers only match minimal formats.
  3. Update/repair GPU drivers; on RDP, enable RemoteFX or test locally.
  4. 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

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


AI-assisted analysis of unoplatform/uno@0418340488 (2026-08-13). Data as JSON: /api/errors/2855d6e11dbb0b7a. Report an issue: GitHub.