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;
}