in shared/SampleShared/DirectXTK/LoaderHelpers.h [408:548]
inline void GetSurfaceInfo(_In_ size_t width,
_In_ size_t height,
_In_ DXGI_FORMAT fmt,
_Out_opt_ size_t* outNumBytes,
_Out_opt_ size_t* outRowBytes,
_Out_opt_ size_t* outNumRows)
{
size_t numBytes = 0;
size_t rowBytes = 0;
size_t numRows = 0;
bool bc = false;
bool packed = false;
bool planar = false;
size_t bpe = 0;
switch (fmt)
{
case DXGI_FORMAT_BC1_TYPELESS:
case DXGI_FORMAT_BC1_UNORM:
case DXGI_FORMAT_BC1_UNORM_SRGB:
case DXGI_FORMAT_BC4_TYPELESS:
case DXGI_FORMAT_BC4_UNORM:
case DXGI_FORMAT_BC4_SNORM:
bc = true;
bpe = 8;
break;
case DXGI_FORMAT_BC2_TYPELESS:
case DXGI_FORMAT_BC2_UNORM:
case DXGI_FORMAT_BC2_UNORM_SRGB:
case DXGI_FORMAT_BC3_TYPELESS:
case DXGI_FORMAT_BC3_UNORM:
case DXGI_FORMAT_BC3_UNORM_SRGB:
case DXGI_FORMAT_BC5_TYPELESS:
case DXGI_FORMAT_BC5_UNORM:
case DXGI_FORMAT_BC5_SNORM:
case DXGI_FORMAT_BC6H_TYPELESS:
case DXGI_FORMAT_BC6H_UF16:
case DXGI_FORMAT_BC6H_SF16:
case DXGI_FORMAT_BC7_TYPELESS:
case DXGI_FORMAT_BC7_UNORM:
case DXGI_FORMAT_BC7_UNORM_SRGB:
bc = true;
bpe = 16;
break;
case DXGI_FORMAT_R8G8_B8G8_UNORM:
case DXGI_FORMAT_G8R8_G8B8_UNORM:
case DXGI_FORMAT_YUY2:
packed = true;
bpe = 4;
break;
case DXGI_FORMAT_Y210:
case DXGI_FORMAT_Y216:
packed = true;
bpe = 8;
break;
case DXGI_FORMAT_NV12:
case DXGI_FORMAT_420_OPAQUE:
planar = true;
bpe = 2;
break;
case DXGI_FORMAT_P010:
case DXGI_FORMAT_P016:
planar = true;
bpe = 4;
break;
#if defined(_XBOX_ONE) && defined(_TITLE)
case DXGI_FORMAT_D16_UNORM_S8_UINT:
case DXGI_FORMAT_R16_UNORM_X8_TYPELESS:
case DXGI_FORMAT_X16_TYPELESS_G8_UINT:
planar = true;
bpe = 4;
break;
#endif
default:
break;
}
if (bc)
{
size_t numBlocksWide = 0;
if (width > 0)
{
numBlocksWide = std::max<size_t>(1, (width + 3) / 4);
}
size_t numBlocksHigh = 0;
if (height > 0)
{
numBlocksHigh = std::max<size_t>(1, (height + 3) / 4);
}
rowBytes = numBlocksWide * bpe;
numRows = numBlocksHigh;
numBytes = rowBytes * numBlocksHigh;
}
else if (packed)
{
rowBytes = ((width + 1) >> 1) * bpe;
numRows = height;
numBytes = rowBytes * height;
}
else if (fmt == DXGI_FORMAT_NV11)
{
rowBytes = ((width + 3) >> 2) * 4;
numRows = height * 2; // Direct3D makes this simplifying assumption, although it is larger than the 4:1:1 data
numBytes = rowBytes * numRows;
}
else if (planar)
{
rowBytes = ((width + 1) >> 1) * bpe;
numBytes = (rowBytes * height) + ((rowBytes * height + 1) >> 1);
numRows = height + ((height + 1) >> 1);
}
else
{
size_t bpp = BitsPerPixel(fmt);
rowBytes = (width * bpp + 7) / 8; // round up to nearest byte
numRows = height;
numBytes = rowBytes * height;
}
if (outNumBytes)
{
*outNumBytes = numBytes;
}
if (outRowBytes)
{
*outRowBytes = rowBytes;
}
if (outNumRows)
{
*outNumRows = numRows;
}
}