inline DXGI_FORMAT GetDXGIFormat()

in Src/LoaderHelpers.h [642:905]


        inline DXGI_FORMAT GetDXGIFormat(const DDS_PIXELFORMAT& ddpf) noexcept
        {
            if (ddpf.flags & DDS_RGB)
            {
                // Note that sRGB formats are written using the "DX10" extended header

                switch (ddpf.RGBBitCount)
                 {
                case 32:
                    if (ISBITMASK(0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000))
                    {
                        return DXGI_FORMAT_R8G8B8A8_UNORM;
                    }

                    if (ISBITMASK(0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000))
                    {
                        return DXGI_FORMAT_B8G8R8A8_UNORM;
                    }

                    if (ISBITMASK(0x00ff0000, 0x0000ff00, 0x000000ff, 0))
                    {
                        return DXGI_FORMAT_B8G8R8X8_UNORM;
                    }

                    // No DXGI format maps to ISBITMASK(0x000000ff,0x0000ff00,0x00ff0000,0) aka D3DFMT_X8B8G8R8

                    // Note that many common DDS reader/writers (including D3DX) swap the
                    // the RED/BLUE masks for 10:10:10:2 formats. We assume
                    // below that the 'backwards' header mask is being used since it is most
                    // likely written by D3DX. The more robust solution is to use the 'DX10'
                    // header extension and specify the DXGI_FORMAT_R10G10B10A2_UNORM format directly

                    // For 'correct' writers, this should be 0x000003ff,0x000ffc00,0x3ff00000 for RGB data
                    if (ISBITMASK(0x3ff00000, 0x000ffc00, 0x000003ff, 0xc0000000))
                    {
                        return DXGI_FORMAT_R10G10B10A2_UNORM;
                    }

                    // No DXGI format maps to ISBITMASK(0x000003ff,0x000ffc00,0x3ff00000,0xc0000000) aka D3DFMT_A2R10G10B10

                    if (ISBITMASK(0x0000ffff, 0xffff0000, 0, 0))
                    {
                        return DXGI_FORMAT_R16G16_UNORM;
                    }

                    if (ISBITMASK(0xffffffff, 0, 0, 0))
                    {
                        // Only 32-bit color channel format in D3D9 was R32F
                        return DXGI_FORMAT_R32_FLOAT; // D3DX writes this out as a FourCC of 114
                    }
                    break;

                case 24:
                    // No 24bpp DXGI formats aka D3DFMT_R8G8B8
                    break;

                case 16:
                    if (ISBITMASK(0x7c00, 0x03e0, 0x001f, 0x8000))
                    {
                        return DXGI_FORMAT_B5G5R5A1_UNORM;
                    }
                    if (ISBITMASK(0xf800, 0x07e0, 0x001f, 0))
                    {
                        return DXGI_FORMAT_B5G6R5_UNORM;
                    }

                    // No DXGI format maps to ISBITMASK(0x7c00,0x03e0,0x001f,0) aka D3DFMT_X1R5G5B5

                    if (ISBITMASK(0x0f00, 0x00f0, 0x000f, 0xf000))
                    {
                        return DXGI_FORMAT_B4G4R4A4_UNORM;
                    }

                    // NVTT versions 1.x wrote this as RGB instead of LUMINANCE
                    if (ISBITMASK(0x00ff, 0, 0, 0xff00))
                    {
                        return DXGI_FORMAT_R8G8_UNORM;
                    }
                    if (ISBITMASK(0xffff, 0, 0, 0))
                    {
                        return DXGI_FORMAT_R16_UNORM;
                    }

                    // No DXGI format maps to ISBITMASK(0x0f00,0x00f0,0x000f,0) aka D3DFMT_X4R4G4B4

                    // No 3:3:2:8 or paletted DXGI formats aka D3DFMT_A8R3G3B2, D3DFMT_A8P8, etc.
                    break;

                case 8:
                    // NVTT versions 1.x wrote this as RGB instead of LUMINANCE
                    if (ISBITMASK(0xff, 0, 0, 0))
                    {
                        return DXGI_FORMAT_R8_UNORM;
                    }

                    // No 3:3:2 or paletted DXGI formats aka D3DFMT_R3G3B2, D3DFMT_P8
                    break;
                }
            }
            else if (ddpf.flags & DDS_LUMINANCE)
            {
                switch (ddpf.RGBBitCount)
                {
                case 16:
                    if (ISBITMASK(0xffff, 0, 0, 0))
                    {
                        return DXGI_FORMAT_R16_UNORM; // D3DX10/11 writes this out as DX10 extension
                    }
                    if (ISBITMASK(0x00ff, 0, 0, 0xff00))
                    {
                        return DXGI_FORMAT_R8G8_UNORM; // D3DX10/11 writes this out as DX10 extension
                    }
                    break;

                case 8:
                    if (ISBITMASK(0xff, 0, 0, 0))
                    {
                        return DXGI_FORMAT_R8_UNORM; // D3DX10/11 writes this out as DX10 extension
                    }

                    // No DXGI format maps to ISBITMASK(0x0f,0,0,0xf0) aka D3DFMT_A4L4

                    if (ISBITMASK(0x00ff, 0, 0, 0xff00))
                    {
                        return DXGI_FORMAT_R8G8_UNORM; // Some DDS writers assume the bitcount should be 8 instead of 16
                    }
                    break;
                }
            }
            else if (ddpf.flags & DDS_ALPHA)
            {
                if (8 == ddpf.RGBBitCount)
                {
                    return DXGI_FORMAT_A8_UNORM;
                }
            }
            else if (ddpf.flags & DDS_BUMPDUDV)
            {
                switch (ddpf.RGBBitCount)
                {
                case 32:
                    if (ISBITMASK(0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000))
                    {
                        return DXGI_FORMAT_R8G8B8A8_SNORM; // D3DX10/11 writes this out as DX10 extension
                    }
                    if (ISBITMASK(0x0000ffff, 0xffff0000, 0, 0))
                    {
                        return DXGI_FORMAT_R16G16_SNORM; // D3DX10/11 writes this out as DX10 extension
                    }

                    // No DXGI format maps to ISBITMASK(0x3ff00000, 0x000ffc00, 0x000003ff, 0xc0000000) aka D3DFMT_A2W10V10U10
                    break;

                case 16:
                    if (ISBITMASK(0x00ff, 0xff00, 0, 0))
                    {
                        return DXGI_FORMAT_R8G8_SNORM; // D3DX10/11 writes this out as DX10 extension
                    }
                    break;
                }

                // No DXGI format maps to DDPF_BUMPLUMINANCE aka D3DFMT_L6V5U5, D3DFMT_X8L8V8U8
            }
            else if (ddpf.flags & DDS_FOURCC)
            {
                if (MAKEFOURCC('D', 'X', 'T', '1') == ddpf.fourCC)
                {
                    return DXGI_FORMAT_BC1_UNORM;
                }
                if (MAKEFOURCC('D', 'X', 'T', '3') == ddpf.fourCC)
                {
                    return DXGI_FORMAT_BC2_UNORM;
                }
                if (MAKEFOURCC('D', 'X', 'T', '5') == ddpf.fourCC)
                {
                    return DXGI_FORMAT_BC3_UNORM;
                }

                // While pre-multiplied alpha isn't directly supported by the DXGI formats,
                // they are basically the same as these BC formats so they can be mapped
                if (MAKEFOURCC('D', 'X', 'T', '2') == ddpf.fourCC)
                {
                    return DXGI_FORMAT_BC2_UNORM;
                }
                if (MAKEFOURCC('D', 'X', 'T', '4') == ddpf.fourCC)
                {
                    return DXGI_FORMAT_BC3_UNORM;
                }

                if (MAKEFOURCC('A', 'T', 'I', '1') == ddpf.fourCC)
                {
                    return DXGI_FORMAT_BC4_UNORM;
                }
                if (MAKEFOURCC('B', 'C', '4', 'U') == ddpf.fourCC)
                {
                    return DXGI_FORMAT_BC4_UNORM;
                }
                if (MAKEFOURCC('B', 'C', '4', 'S') == ddpf.fourCC)
                {
                    return DXGI_FORMAT_BC4_SNORM;
                }

                if (MAKEFOURCC('A', 'T', 'I', '2') == ddpf.fourCC)
                {
                    return DXGI_FORMAT_BC5_UNORM;
                }
                if (MAKEFOURCC('B', 'C', '5', 'U') == ddpf.fourCC)
                {
                    return DXGI_FORMAT_BC5_UNORM;
                }
                if (MAKEFOURCC('B', 'C', '5', 'S') == ddpf.fourCC)
                {
                    return DXGI_FORMAT_BC5_SNORM;
                }

                // BC6H and BC7 are written using the "DX10" extended header

                if (MAKEFOURCC('R', 'G', 'B', 'G') == ddpf.fourCC)
                {
                    return DXGI_FORMAT_R8G8_B8G8_UNORM;
                }
                if (MAKEFOURCC('G', 'R', 'G', 'B') == ddpf.fourCC)
                {
                    return DXGI_FORMAT_G8R8_G8B8_UNORM;
                }

                if (MAKEFOURCC('Y', 'U', 'Y', '2') == ddpf.fourCC)
                {
                    return DXGI_FORMAT_YUY2;
                }

                // Check for D3DFORMAT enums being set here
                switch (ddpf.fourCC)
                {
                    case 36: // D3DFMT_A16B16G16R16
                        return DXGI_FORMAT_R16G16B16A16_UNORM;

                    case 110: // D3DFMT_Q16W16V16U16
                        return DXGI_FORMAT_R16G16B16A16_SNORM;

                    case 111: // D3DFMT_R16F
                        return DXGI_FORMAT_R16_FLOAT;

                    case 112: // D3DFMT_G16R16F
                        return DXGI_FORMAT_R16G16_FLOAT;

                    case 113: // D3DFMT_A16B16G16R16F
                        return DXGI_FORMAT_R16G16B16A16_FLOAT;

                    case 114: // D3DFMT_R32F
                        return DXGI_FORMAT_R32_FLOAT;

                    case 115: // D3DFMT_G32R32F
                        return DXGI_FORMAT_R32G32_FLOAT;

                    case 116: // D3DFMT_A32B32G32R32F
                        return DXGI_FORMAT_R32G32B32A32_FLOAT;

                    // No DXGI format maps to D3DFMT_CxV8U8
                }
            }

            return DXGI_FORMAT_UNKNOWN;
        }