in MiniEngine/Core/DDSTextureLoader.cpp [312:439]
static 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 (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;
}
}