The SteamVR OpenXR Windows runtime incorrectly exposes GL_RGBA16 via xrEnumerateSwapchainFormats.
Because standard SDK sample applications (like the official Khronos Group hello_xr reference sample) parse the runtime array and choose the highest-fidelity color depth available, hello_xr defaults to GL_RGBA16 out-of-the-box. While xrCreateSwapchain succeeds for the format, the moment the texture handles are passed to the compositor, ComposeLayerProjection fails entirely with VRCompositorError_TextureUsesUnsupportedFormat. Switching the selection logic manually to floating-point GL_RGBA16F fixes the bug completely.
A historical precedent exists for this issue: Valve explicitly resolved this exact behavior for Linux in SteamVR 1.24 ("xrEnumerateSwapchainFormats no longer returns the following formats on Linux as they are not properly supported: GL_RGBA16"). This cleanup was never ported to the Windows runtime side.
Environment & Reproducible Steps
OS: Windows 10/11 (Tested with NVIDIA driver stack nvwgf2umx.dll)
Runtime: SteamVR OpenXR Runtime
API: OpenGL
Application: Official Khronos OpenXR SDK sample (hello_xr using OpenGL graphics plugin module).
Out of the box, hello_xr enumerates the formats, evaluates 32859 (GL_RGBA16) as preferred, generates the color swapchain, and fails frame submission immediately. (hello_xr.exe -g OpenGL -ff Hmd -vc Stereo -v)
The Windows runtime is returning these precise decimal identifiers: 32859 34842 34843 35905 35907 33189 33190 36012
Here is what SteamVR is offering to the OpenXR layer:
Decimal Token
OpenGL Hex
OpenGL Format Name
Status
Type
32859
0x805B
GL_RGBA16
❌ Broken
Color Swapchain (Triggers submission crash) (Tested)
34842
0x881A
GL_RGBA16F
Valid
Color Swapchain (Works fine) (Tested)
34843
0x881B
GL_RGB16F
⚠️ Suspect
Color Swapchain (Missing Alpha)
35905
0x8C41
GL_SRGB8
Valid
Color Swapchain
35907
0x8C43
GL_SRGB8_ALPHA8
Valid
Color Swapchain
33189
0x81A5
GL_DEPTH_COMPONENT16
Valid
Depth Buffer
33190
0x81A6
GL_DEPTH_COMPONENT24
Valid
Depth Buffer
36012
0x8C1A
GL_RGBA32F
Valid
Color Swapchain
Expected Behavior
SteamVR's Windows OpenXR runtime should strip GL_RGBA16 (32859) from the xrEnumerateSwapchainFormats return array. If the runtime cannot safely translate unorm 16-bit textures across its cross-API Vulkan interop path, it should not advertise them to OpenXR applications looking for a valid swapchain target.
Describe the Bug
The SteamVR OpenXR Windows runtime incorrectly exposes
GL_RGBA16viaxrEnumerateSwapchainFormats.Because standard SDK sample applications (like the official Khronos Group
hello_xrreference sample) parse the runtime array and choose the highest-fidelity color depth available,hello_xrdefaults toGL_RGBA16out-of-the-box. WhilexrCreateSwapchainsucceeds for the format, the moment the texture handles are passed to the compositor,ComposeLayerProjectionfails entirely withVRCompositorError_TextureUsesUnsupportedFormat. Switching the selection logic manually to floating-pointGL_RGBA16Ffixes the bug completely.A historical precedent exists for this issue: Valve explicitly resolved this exact behavior for Linux in SteamVR 1.24 ("xrEnumerateSwapchainFormats no longer returns the following formats on Linux as they are not properly supported: GL_RGBA16"). This cleanup was never ported to the Windows runtime side.
Environment & Reproducible Steps
nvwgf2umx.dll)hello_xrusing OpenGL graphics plugin module).hello_xrenumerates the formats, evaluates32859(GL_RGBA16) as preferred, generates the color swapchain, and fails frame submission immediately. (hello_xr.exe -g OpenGL -ff Hmd -vc Stereo -v)Raw Execution Logs
Exact Format Analysis
The Windows runtime is returning these precise decimal identifiers:
32859 34842 34843 35905 35907 33189 33190 36012Here is what SteamVR is offering to the OpenXR layer:
0x805BGL_RGBA160x881AGL_RGBA16F0x881BGL_RGB16F0x8C41GL_SRGB80x8C43GL_SRGB8_ALPHA80x81A5GL_DEPTH_COMPONENT160x81A6GL_DEPTH_COMPONENT240x8C1AGL_RGBA32FExpected Behavior
SteamVR's Windows OpenXR runtime should strip
GL_RGBA16(32859) from thexrEnumerateSwapchainFormatsreturn array. If the runtime cannot safely translate unorm 16-bit textures across its cross-API Vulkan interop path, it should not advertise them to OpenXR applications looking for a valid swapchain target.