Search code examples
dwmdxgi

RGBA vs BGRA pixel layout


I'm wondering about the difference between DXGI_FORMAT_R8G8B8A8_UNORM vs DXGI_FORMAT_B8G8R8A8_UNORM.

Do monitors natively support both, or just a single format?

How do we tell which formant DWM is using?


Solution

  • The video signal actually sent to the monitor is entirely up to the GPU as negotiated with the display though all the various electrical standards, so generally speaking you don't have any direct control over that as an application. All you can do is choose one of the valid swapchain formats and then leave it up to the system.

    The video signal hardware is generally designed so that it doesn't make any difference at all if the framework source format is RGB or BGR. Fixed display-out hardware does all the conversion so it's essentially 'free'.

    For modern monitors the 'best color' is usually a 10:10:10:2 format as the video signal over modern cables is typically more than 8-bits for each channel (somewhere in the 8-12 range). For HDR monitors, the video signal is an HDR10 encoded 10:10:10:2 format as well.

    For HDR10, the signal prep is not usually done 'automagically' since there are many choices here so it's typically done by the GPU hardware via a shader (either provided by the driver/DWM, or the application).

    What does noticeably impact performance is if you use DXGI_FORMAT_R16G16B16A16_FLOAT which requires DWM to do some conversions. Typically you only use this format as your display-out if you want to use the default HDR10 signal generation built into DWM.

    IOW: This not something you need worry about. The majority of modern samples and application use DXGI_FORMAT_B8G8R8A8_UNORM for non-HDR or DXGI_FORMAT_R10G10B10A2 for HDR10 for the swapchain format. If you are creating a Direct3D 11 device, best practice would be to use D3D11_CREATE_DEVICE_BGRA_SUPPORT as Direct2D/DirectWrite interop requires BGR. Really all modern drivers support BGR formats, but this flag dates from a time when first-generation WDDM tried to force everyone to use RGB color ordering only.

    Note that using DXGI_FORMAT_*_UNORM_SRGB has a bit of a complicated story. See this blog series for more information.