Search code examples
graphicsdirectxvulkan

Is VK_FORMAT_A2B10G10R10_UNORM_PACK32 the equivalent of DXGI_FORMAT_R10G10B10A2_UNORM?


They look different formats, however an online LLM told me:

You're absolutely right to question this! The component order in the name of the Vulkan and DirectX formats is different, but the actual bitwise layout in memory is identical between DXGI_FORMAT_R10G10B10A2_UNORM and VK_FORMAT_A2R10G10B10_UNORM_PACK32. Why Are They Actually the Same in Memory?

Bit Range   DirectX(R10G10B10A2_UNORM)  Vulkan(VK_FORMAT_A2R10G10B10_UNORM_PACK32)
----------------------------------------------------------------------------------
[31:30]         Alpha(A2)                           Alpha(A2)
[29:20]         Red(R10)                            Red(R10)
[19:10]         Green(G10)                          Green(G10)
[9:0]           Blue(B10)                           Blue(B10)

Although Vulkan names the alpha first (A2R10G10B10), this is just a naming convention—the actual memory layout is identical to R10G10B10A2_UNORM in DirectX.

I was just wondering if this is true. The Vulkan version puts the A at the front in the name, but the bit patterns are the same?


Solution

  • Yes, they are the same.

    The Vulkan spec description for VK_FORMAT_A2B10G10R10_UNORM_PACK32 is [spec][archive]:

    VK_FORMAT_A2B10G10R10_UNORM_PACK32 specifies a four-component, 32-bit packed unsigned normalized format that has a 2-bit A component in bits 30..31, a 10-bit B component in bits 20..29, a 10-bit G component in bits 10..19, and a 10-bit R component in bits 0..9

    Further, packed formats are defined to have first value be the most significant bit [spec][archive]:

    Packed formats store multiple components within one underlying type. The bit representation is that the first component specified in the name of the format is in the most-significant bits and the last component specified is in the least-significant bits of the underlying type. The in-memory ordering of bytes comprising the underlying type is determined by the host endianness.

    DXGI is a little more nebulous in how they define the bit ordering, but they conveniently provide a sample with this exact format [spec][archive]:

    // DXGI_FORMAT_R10G10B10A2_UNORM
    UINT32* pR10G10B10A2 = ...;
    pR10G10B10A2 = (0x3ff) | (0x1 << 30);  // R=0x3ff, and A=0x1
    

    This sample confirms that bits 30..31 are the alpha channel, and that bits 0..9 are the red channel, just like in Vulkan.