950 lines
28 KiB
C++
950 lines
28 KiB
C++
//-------------------------------------------------------------------------------------
|
|
// DirectXTexUtil.cpp
|
|
//
|
|
// DirectX Texture Library - Utilities
|
|
//
|
|
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
|
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
|
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
|
// PARTICULAR PURPOSE.
|
|
//
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
//
|
|
// http://go.microsoft.com/fwlink/?LinkId=248926
|
|
//-------------------------------------------------------------------------------------
|
|
|
|
#include "directxtexp.h"
|
|
|
|
//-------------------------------------------------------------------------------------
|
|
// WIC Pixel Format Translation Data
|
|
//-------------------------------------------------------------------------------------
|
|
struct WICTranslate
|
|
{
|
|
GUID wic;
|
|
DXGI_FORMAT format;
|
|
bool srgb;
|
|
};
|
|
|
|
static WICTranslate g_WICFormats[] =
|
|
{
|
|
{ GUID_WICPixelFormat128bppRGBAFloat, DXGI_FORMAT_R32G32B32A32_FLOAT, false },
|
|
|
|
{ GUID_WICPixelFormat64bppRGBAHalf, DXGI_FORMAT_R16G16B16A16_FLOAT, false },
|
|
{ GUID_WICPixelFormat64bppRGBA, DXGI_FORMAT_R16G16B16A16_UNORM, true },
|
|
|
|
{ GUID_WICPixelFormat32bppRGBA, DXGI_FORMAT_R8G8B8A8_UNORM, true },
|
|
{ GUID_WICPixelFormat32bppBGRA, DXGI_FORMAT_B8G8R8A8_UNORM, true }, // DXGI 1.1
|
|
{ GUID_WICPixelFormat32bppBGR, DXGI_FORMAT_B8G8R8X8_UNORM, true }, // DXGI 1.1
|
|
|
|
{ GUID_WICPixelFormat32bppRGBA1010102XR, DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM, true }, // DXGI 1.1
|
|
{ GUID_WICPixelFormat32bppRGBA1010102, DXGI_FORMAT_R10G10B10A2_UNORM, true },
|
|
|
|
{ GUID_WICPixelFormat16bppBGRA5551, DXGI_FORMAT_B5G5R5A1_UNORM, true },
|
|
{ GUID_WICPixelFormat16bppBGR565, DXGI_FORMAT_B5G6R5_UNORM, true },
|
|
|
|
{ GUID_WICPixelFormat32bppGrayFloat, DXGI_FORMAT_R32_FLOAT, false },
|
|
{ GUID_WICPixelFormat16bppGrayHalf, DXGI_FORMAT_R16_FLOAT, false },
|
|
{ GUID_WICPixelFormat16bppGray, DXGI_FORMAT_R16_UNORM, true },
|
|
{ GUID_WICPixelFormat8bppGray, DXGI_FORMAT_R8_UNORM, true },
|
|
|
|
{ GUID_WICPixelFormat8bppAlpha, DXGI_FORMAT_A8_UNORM, false },
|
|
|
|
{ GUID_WICPixelFormatBlackWhite, DXGI_FORMAT_R1_UNORM, false },
|
|
};
|
|
|
|
static bool g_WIC2 = false;
|
|
|
|
namespace DirectX
|
|
{
|
|
|
|
//=====================================================================================
|
|
// WIC Utilities
|
|
//=====================================================================================
|
|
|
|
_Use_decl_annotations_
|
|
DXGI_FORMAT _WICToDXGI( const GUID& guid )
|
|
{
|
|
for( size_t i=0; i < _countof(g_WICFormats); ++i )
|
|
{
|
|
if ( memcmp( &g_WICFormats[i].wic, &guid, sizeof(GUID) ) == 0 )
|
|
return g_WICFormats[i].format;
|
|
}
|
|
|
|
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE)
|
|
if ( g_WIC2 )
|
|
{
|
|
if ( memcmp( &GUID_WICPixelFormat96bppRGBFloat, &guid, sizeof(GUID) ) == 0 )
|
|
return DXGI_FORMAT_R32G32B32_FLOAT;
|
|
}
|
|
#endif
|
|
|
|
return DXGI_FORMAT_UNKNOWN;
|
|
}
|
|
|
|
_Use_decl_annotations_
|
|
bool _DXGIToWIC( DXGI_FORMAT format, GUID& guid, bool ignoreRGBvsBGR )
|
|
{
|
|
switch( format )
|
|
{
|
|
case DXGI_FORMAT_R8G8B8A8_UNORM:
|
|
case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
|
|
if ( ignoreRGBvsBGR )
|
|
{
|
|
// If we are not doing conversion so don't really care about BGR vs RGB color-order,
|
|
// we can use the canonical WIC 32bppBGRA format which avoids an extra format conversion when using the WIC scaler
|
|
memcpy( &guid, &GUID_WICPixelFormat32bppBGRA, sizeof(GUID) );
|
|
}
|
|
else
|
|
{
|
|
memcpy( &guid, &GUID_WICPixelFormat32bppRGBA, sizeof(GUID) );
|
|
}
|
|
return true;
|
|
|
|
case DXGI_FORMAT_D32_FLOAT:
|
|
memcpy( &guid, &GUID_WICPixelFormat32bppGrayFloat, sizeof(GUID) );
|
|
return true;
|
|
|
|
case DXGI_FORMAT_D16_UNORM:
|
|
memcpy( &guid, &GUID_WICPixelFormat16bppGray, sizeof(GUID) );
|
|
return true;
|
|
|
|
case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
|
|
memcpy( &guid, &GUID_WICPixelFormat32bppBGRA, sizeof(GUID) );
|
|
return true;
|
|
|
|
case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
|
|
memcpy( &guid, &GUID_WICPixelFormat32bppBGR, sizeof(GUID) );
|
|
return true;
|
|
|
|
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE)
|
|
case DXGI_FORMAT_R32G32B32_FLOAT:
|
|
if ( g_WIC2 )
|
|
{
|
|
memcpy( &guid, &GUID_WICPixelFormat96bppRGBFloat, sizeof(GUID) );
|
|
return true;
|
|
}
|
|
break;
|
|
#endif
|
|
|
|
default:
|
|
for( size_t i=0; i < _countof(g_WICFormats); ++i )
|
|
{
|
|
if ( g_WICFormats[i].format == format )
|
|
{
|
|
memcpy( &guid, &g_WICFormats[i].wic, sizeof(GUID) );
|
|
return true;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
memcpy( &guid, &GUID_NULL, sizeof(GUID) );
|
|
return false;
|
|
}
|
|
|
|
DWORD _CheckWICColorSpace( _In_ const GUID& sourceGUID, _In_ const GUID& targetGUID )
|
|
{
|
|
DWORD srgb = 0;
|
|
|
|
for( size_t i=0; i < _countof(g_WICFormats); ++i )
|
|
{
|
|
if ( memcmp( &g_WICFormats[i].wic, &sourceGUID, sizeof(GUID) ) == 0 )
|
|
{
|
|
if ( g_WICFormats[i].srgb )
|
|
srgb |= TEX_FILTER_SRGB_IN;
|
|
}
|
|
|
|
if ( memcmp( &g_WICFormats[i].wic, &targetGUID, sizeof(GUID) ) == 0 )
|
|
{
|
|
if ( g_WICFormats[i].srgb )
|
|
srgb |= TEX_FILTER_SRGB_OUT;
|
|
}
|
|
}
|
|
|
|
if ( (srgb & (TEX_FILTER_SRGB_IN|TEX_FILTER_SRGB_OUT)) == (TEX_FILTER_SRGB_IN|TEX_FILTER_SRGB_OUT) )
|
|
{
|
|
srgb &= ~(TEX_FILTER_SRGB_IN|TEX_FILTER_SRGB_OUT);
|
|
}
|
|
|
|
return srgb;
|
|
}
|
|
|
|
bool _IsWIC2()
|
|
{
|
|
return g_WIC2;
|
|
}
|
|
|
|
IWICImagingFactory* _GetWIC()
|
|
{
|
|
static IWICImagingFactory* s_Factory = nullptr;
|
|
|
|
if ( s_Factory )
|
|
return s_Factory;
|
|
|
|
#if(_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE)
|
|
HRESULT hr = CoCreateInstance(
|
|
CLSID_WICImagingFactory2,
|
|
nullptr,
|
|
CLSCTX_INPROC_SERVER,
|
|
__uuidof(IWICImagingFactory2),
|
|
(LPVOID*)&s_Factory
|
|
);
|
|
|
|
if ( SUCCEEDED(hr) )
|
|
{
|
|
// WIC2 is available on Windows 8 and Windows 7 SP1 with KB 2670838 installed
|
|
g_WIC2 = true;
|
|
}
|
|
else
|
|
{
|
|
hr = CoCreateInstance(
|
|
CLSID_WICImagingFactory1,
|
|
nullptr,
|
|
CLSCTX_INPROC_SERVER,
|
|
__uuidof(IWICImagingFactory),
|
|
(LPVOID*)&s_Factory
|
|
);
|
|
|
|
if ( FAILED(hr) )
|
|
{
|
|
s_Factory = nullptr;
|
|
return nullptr;
|
|
}
|
|
}
|
|
#else
|
|
HRESULT hr = CoCreateInstance(
|
|
CLSID_WICImagingFactory,
|
|
nullptr,
|
|
CLSCTX_INPROC_SERVER,
|
|
__uuidof(IWICImagingFactory),
|
|
(LPVOID*)&s_Factory
|
|
);
|
|
|
|
if ( FAILED(hr) )
|
|
{
|
|
s_Factory = nullptr;
|
|
return nullptr;
|
|
}
|
|
#endif
|
|
|
|
return s_Factory;
|
|
}
|
|
|
|
|
|
//-------------------------------------------------------------------------------------
|
|
// Public helper function to get common WIC codec GUIDs
|
|
//-------------------------------------------------------------------------------------
|
|
_Use_decl_annotations_
|
|
REFGUID GetWICCodec( WICCodecs codec )
|
|
{
|
|
switch( codec )
|
|
{
|
|
case WIC_CODEC_BMP:
|
|
return GUID_ContainerFormatBmp;
|
|
|
|
case WIC_CODEC_JPEG:
|
|
return GUID_ContainerFormatJpeg;
|
|
|
|
case WIC_CODEC_PNG:
|
|
return GUID_ContainerFormatPng;
|
|
|
|
case WIC_CODEC_TIFF:
|
|
return GUID_ContainerFormatTiff;
|
|
|
|
case WIC_CODEC_GIF:
|
|
return GUID_ContainerFormatGif;
|
|
|
|
case WIC_CODEC_WMP:
|
|
return GUID_ContainerFormatWmp;
|
|
|
|
case WIC_CODEC_ICO:
|
|
return GUID_ContainerFormatIco;
|
|
|
|
default:
|
|
return GUID_NULL;
|
|
}
|
|
}
|
|
|
|
|
|
//=====================================================================================
|
|
// DXGI Format Utilities
|
|
//=====================================================================================
|
|
|
|
//-------------------------------------------------------------------------------------
|
|
// Returns bits-per-pixel for a given DXGI format, or 0 on failure
|
|
//-------------------------------------------------------------------------------------
|
|
_Use_decl_annotations_
|
|
size_t BitsPerPixel( DXGI_FORMAT fmt )
|
|
{
|
|
switch( fmt )
|
|
{
|
|
case DXGI_FORMAT_R32G32B32A32_TYPELESS:
|
|
case DXGI_FORMAT_R32G32B32A32_FLOAT:
|
|
case DXGI_FORMAT_R32G32B32A32_UINT:
|
|
case DXGI_FORMAT_R32G32B32A32_SINT:
|
|
return 128;
|
|
|
|
case DXGI_FORMAT_R32G32B32_TYPELESS:
|
|
case DXGI_FORMAT_R32G32B32_FLOAT:
|
|
case DXGI_FORMAT_R32G32B32_UINT:
|
|
case DXGI_FORMAT_R32G32B32_SINT:
|
|
return 96;
|
|
|
|
case DXGI_FORMAT_R16G16B16A16_TYPELESS:
|
|
case DXGI_FORMAT_R16G16B16A16_FLOAT:
|
|
case DXGI_FORMAT_R16G16B16A16_UNORM:
|
|
case DXGI_FORMAT_R16G16B16A16_UINT:
|
|
case DXGI_FORMAT_R16G16B16A16_SNORM:
|
|
case DXGI_FORMAT_R16G16B16A16_SINT:
|
|
case DXGI_FORMAT_R32G32_TYPELESS:
|
|
case DXGI_FORMAT_R32G32_FLOAT:
|
|
case DXGI_FORMAT_R32G32_UINT:
|
|
case DXGI_FORMAT_R32G32_SINT:
|
|
case DXGI_FORMAT_R32G8X24_TYPELESS:
|
|
case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
|
|
case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
|
|
case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:
|
|
return 64;
|
|
|
|
case DXGI_FORMAT_R10G10B10A2_TYPELESS:
|
|
case DXGI_FORMAT_R10G10B10A2_UNORM:
|
|
case DXGI_FORMAT_R10G10B10A2_UINT:
|
|
case DXGI_FORMAT_R11G11B10_FLOAT:
|
|
case DXGI_FORMAT_R8G8B8A8_TYPELESS:
|
|
case DXGI_FORMAT_R8G8B8A8_UNORM:
|
|
case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
|
|
case DXGI_FORMAT_R8G8B8A8_UINT:
|
|
case DXGI_FORMAT_R8G8B8A8_SNORM:
|
|
case DXGI_FORMAT_R8G8B8A8_SINT:
|
|
case DXGI_FORMAT_R16G16_TYPELESS:
|
|
case DXGI_FORMAT_R16G16_FLOAT:
|
|
case DXGI_FORMAT_R16G16_UNORM:
|
|
case DXGI_FORMAT_R16G16_UINT:
|
|
case DXGI_FORMAT_R16G16_SNORM:
|
|
case DXGI_FORMAT_R16G16_SINT:
|
|
case DXGI_FORMAT_R32_TYPELESS:
|
|
case DXGI_FORMAT_D32_FLOAT:
|
|
case DXGI_FORMAT_R32_FLOAT:
|
|
case DXGI_FORMAT_R32_UINT:
|
|
case DXGI_FORMAT_R32_SINT:
|
|
case DXGI_FORMAT_R24G8_TYPELESS:
|
|
case DXGI_FORMAT_D24_UNORM_S8_UINT:
|
|
case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
|
|
case DXGI_FORMAT_X24_TYPELESS_G8_UINT:
|
|
case DXGI_FORMAT_R9G9B9E5_SHAREDEXP:
|
|
case DXGI_FORMAT_R8G8_B8G8_UNORM:
|
|
case DXGI_FORMAT_G8R8_G8B8_UNORM:
|
|
case DXGI_FORMAT_B8G8R8A8_UNORM:
|
|
case DXGI_FORMAT_B8G8R8X8_UNORM:
|
|
case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM:
|
|
case DXGI_FORMAT_B8G8R8A8_TYPELESS:
|
|
case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
|
|
case DXGI_FORMAT_B8G8R8X8_TYPELESS:
|
|
case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
|
|
return 32;
|
|
|
|
case DXGI_FORMAT_R8G8_TYPELESS:
|
|
case DXGI_FORMAT_R8G8_UNORM:
|
|
case DXGI_FORMAT_R8G8_UINT:
|
|
case DXGI_FORMAT_R8G8_SNORM:
|
|
case DXGI_FORMAT_R8G8_SINT:
|
|
case DXGI_FORMAT_R16_TYPELESS:
|
|
case DXGI_FORMAT_R16_FLOAT:
|
|
case DXGI_FORMAT_D16_UNORM:
|
|
case DXGI_FORMAT_R16_UNORM:
|
|
case DXGI_FORMAT_R16_UINT:
|
|
case DXGI_FORMAT_R16_SNORM:
|
|
case DXGI_FORMAT_R16_SINT:
|
|
case DXGI_FORMAT_B5G6R5_UNORM:
|
|
case DXGI_FORMAT_B5G5R5A1_UNORM:
|
|
return 16;
|
|
|
|
case DXGI_FORMAT_R8_TYPELESS:
|
|
case DXGI_FORMAT_R8_UNORM:
|
|
case DXGI_FORMAT_R8_UINT:
|
|
case DXGI_FORMAT_R8_SNORM:
|
|
case DXGI_FORMAT_R8_SINT:
|
|
case DXGI_FORMAT_A8_UNORM:
|
|
return 8;
|
|
|
|
case DXGI_FORMAT_R1_UNORM:
|
|
return 1;
|
|
|
|
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:
|
|
return 4;
|
|
|
|
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:
|
|
return 8;
|
|
|
|
#ifdef DXGI_1_2_FORMATS
|
|
case DXGI_FORMAT_B4G4R4A4_UNORM:
|
|
return 16;
|
|
|
|
// We don't support the video formats ( see IsVideo function )
|
|
#endif // DXGI_1_2_FORMATS
|
|
|
|
default:
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
//-------------------------------------------------------------------------------------
|
|
// Returns bits-per-color-channel for a given DXGI format, or 0 on failure
|
|
// For mixed formats, it returns the largest color-depth in the format
|
|
//-------------------------------------------------------------------------------------
|
|
_Use_decl_annotations_
|
|
size_t BitsPerColor( DXGI_FORMAT fmt )
|
|
{
|
|
switch( fmt )
|
|
{
|
|
case DXGI_FORMAT_R32G32B32A32_TYPELESS:
|
|
case DXGI_FORMAT_R32G32B32A32_FLOAT:
|
|
case DXGI_FORMAT_R32G32B32A32_UINT:
|
|
case DXGI_FORMAT_R32G32B32A32_SINT:
|
|
case DXGI_FORMAT_R32G32B32_TYPELESS:
|
|
case DXGI_FORMAT_R32G32B32_FLOAT:
|
|
case DXGI_FORMAT_R32G32B32_UINT:
|
|
case DXGI_FORMAT_R32G32B32_SINT:
|
|
case DXGI_FORMAT_R32G32_TYPELESS:
|
|
case DXGI_FORMAT_R32G32_FLOAT:
|
|
case DXGI_FORMAT_R32G32_UINT:
|
|
case DXGI_FORMAT_R32G32_SINT:
|
|
case DXGI_FORMAT_R32G8X24_TYPELESS:
|
|
case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
|
|
case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
|
|
case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:
|
|
case DXGI_FORMAT_R32_TYPELESS:
|
|
case DXGI_FORMAT_D32_FLOAT:
|
|
case DXGI_FORMAT_R32_FLOAT:
|
|
case DXGI_FORMAT_R32_UINT:
|
|
case DXGI_FORMAT_R32_SINT:
|
|
return 32;
|
|
|
|
case DXGI_FORMAT_R24G8_TYPELESS:
|
|
case DXGI_FORMAT_D24_UNORM_S8_UINT:
|
|
case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
|
|
case DXGI_FORMAT_X24_TYPELESS_G8_UINT:
|
|
return 24;
|
|
|
|
case DXGI_FORMAT_R16G16B16A16_TYPELESS:
|
|
case DXGI_FORMAT_R16G16B16A16_FLOAT:
|
|
case DXGI_FORMAT_R16G16B16A16_UNORM:
|
|
case DXGI_FORMAT_R16G16B16A16_UINT:
|
|
case DXGI_FORMAT_R16G16B16A16_SNORM:
|
|
case DXGI_FORMAT_R16G16B16A16_SINT:
|
|
case DXGI_FORMAT_R16G16_TYPELESS:
|
|
case DXGI_FORMAT_R16G16_FLOAT:
|
|
case DXGI_FORMAT_R16G16_UNORM:
|
|
case DXGI_FORMAT_R16G16_UINT:
|
|
case DXGI_FORMAT_R16G16_SNORM:
|
|
case DXGI_FORMAT_R16G16_SINT:
|
|
case DXGI_FORMAT_R16_TYPELESS:
|
|
case DXGI_FORMAT_R16_FLOAT:
|
|
case DXGI_FORMAT_D16_UNORM:
|
|
case DXGI_FORMAT_R16_UNORM:
|
|
case DXGI_FORMAT_R16_UINT:
|
|
case DXGI_FORMAT_R16_SNORM:
|
|
case DXGI_FORMAT_R16_SINT:
|
|
case DXGI_FORMAT_BC6H_TYPELESS:
|
|
case DXGI_FORMAT_BC6H_UF16:
|
|
case DXGI_FORMAT_BC6H_SF16:
|
|
return 16;
|
|
|
|
case DXGI_FORMAT_R9G9B9E5_SHAREDEXP:
|
|
return 14;
|
|
|
|
case DXGI_FORMAT_R11G11B10_FLOAT:
|
|
return 11;
|
|
|
|
case DXGI_FORMAT_R10G10B10A2_TYPELESS:
|
|
case DXGI_FORMAT_R10G10B10A2_UNORM:
|
|
case DXGI_FORMAT_R10G10B10A2_UINT:
|
|
case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM:
|
|
return 10;
|
|
|
|
case DXGI_FORMAT_R8G8B8A8_TYPELESS:
|
|
case DXGI_FORMAT_R8G8B8A8_UNORM:
|
|
case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
|
|
case DXGI_FORMAT_R8G8B8A8_UINT:
|
|
case DXGI_FORMAT_R8G8B8A8_SNORM:
|
|
case DXGI_FORMAT_R8G8B8A8_SINT:
|
|
case DXGI_FORMAT_R8G8_TYPELESS:
|
|
case DXGI_FORMAT_R8G8_UNORM:
|
|
case DXGI_FORMAT_R8G8_UINT:
|
|
case DXGI_FORMAT_R8G8_SNORM:
|
|
case DXGI_FORMAT_R8G8_SINT:
|
|
case DXGI_FORMAT_R8_TYPELESS:
|
|
case DXGI_FORMAT_R8_UNORM:
|
|
case DXGI_FORMAT_R8_UINT:
|
|
case DXGI_FORMAT_R8_SNORM:
|
|
case DXGI_FORMAT_R8_SINT:
|
|
case DXGI_FORMAT_A8_UNORM:
|
|
case DXGI_FORMAT_R8G8_B8G8_UNORM:
|
|
case DXGI_FORMAT_G8R8_G8B8_UNORM:
|
|
case DXGI_FORMAT_BC4_TYPELESS:
|
|
case DXGI_FORMAT_BC4_UNORM:
|
|
case DXGI_FORMAT_BC4_SNORM:
|
|
case DXGI_FORMAT_BC5_TYPELESS:
|
|
case DXGI_FORMAT_BC5_UNORM:
|
|
case DXGI_FORMAT_BC5_SNORM:
|
|
case DXGI_FORMAT_B8G8R8A8_UNORM:
|
|
case DXGI_FORMAT_B8G8R8X8_UNORM:
|
|
case DXGI_FORMAT_B8G8R8A8_TYPELESS:
|
|
case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
|
|
case DXGI_FORMAT_B8G8R8X8_TYPELESS:
|
|
case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
|
|
return 8;
|
|
|
|
case DXGI_FORMAT_BC7_TYPELESS:
|
|
case DXGI_FORMAT_BC7_UNORM:
|
|
case DXGI_FORMAT_BC7_UNORM_SRGB:
|
|
return 7;
|
|
|
|
case DXGI_FORMAT_BC1_TYPELESS:
|
|
case DXGI_FORMAT_BC1_UNORM:
|
|
case DXGI_FORMAT_BC1_UNORM_SRGB:
|
|
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_B5G6R5_UNORM:
|
|
return 6;
|
|
|
|
case DXGI_FORMAT_B5G5R5A1_UNORM:
|
|
return 5;
|
|
|
|
#ifdef DXGI_1_2_FORMATS
|
|
case DXGI_FORMAT_B4G4R4A4_UNORM:
|
|
return 4;
|
|
|
|
// We don't support the video formats ( see IsVideo function )
|
|
#endif // DXGI_1_2_FORMATS
|
|
|
|
case DXGI_FORMAT_R1_UNORM:
|
|
return 1;
|
|
|
|
default:
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
//-------------------------------------------------------------------------------------
|
|
// Computes the image row pitch in bytes, and the slice ptich (size in bytes of the image)
|
|
// based on DXGI format, width, and height
|
|
//-------------------------------------------------------------------------------------
|
|
_Use_decl_annotations_
|
|
void ComputePitch( DXGI_FORMAT fmt, size_t width, size_t height,
|
|
size_t& rowPitch, size_t& slicePitch, DWORD flags )
|
|
{
|
|
assert( IsValid(fmt) && !IsVideo(fmt) );
|
|
|
|
if ( IsCompressed(fmt) )
|
|
{
|
|
size_t bpb = ( fmt == DXGI_FORMAT_BC1_TYPELESS
|
|
|| fmt == DXGI_FORMAT_BC1_UNORM
|
|
|| fmt == DXGI_FORMAT_BC1_UNORM_SRGB
|
|
|| fmt == DXGI_FORMAT_BC4_TYPELESS
|
|
|| fmt == DXGI_FORMAT_BC4_UNORM
|
|
|| fmt == DXGI_FORMAT_BC4_SNORM) ? 8 : 16;
|
|
size_t nbw = std::max<size_t>( 1, (width + 3) / 4 );
|
|
size_t nbh = std::max<size_t>( 1, (height + 3) / 4 );
|
|
rowPitch = nbw * bpb;
|
|
|
|
slicePitch = rowPitch * nbh;
|
|
}
|
|
else if ( IsPacked(fmt) )
|
|
{
|
|
rowPitch = ( ( width + 1 ) >> 1) * 4;
|
|
|
|
slicePitch = rowPitch * height;
|
|
}
|
|
else
|
|
{
|
|
size_t bpp;
|
|
|
|
if ( flags & CP_FLAGS_24BPP )
|
|
bpp = 24;
|
|
else if ( flags & CP_FLAGS_16BPP )
|
|
bpp = 16;
|
|
else if ( flags & CP_FLAGS_8BPP )
|
|
bpp = 8;
|
|
else
|
|
bpp = BitsPerPixel( fmt );
|
|
|
|
if ( flags & CP_FLAGS_LEGACY_DWORD )
|
|
{
|
|
// Special computation for some incorrectly created DDS files based on
|
|
// legacy DirectDraw assumptions about pitch alignment
|
|
rowPitch = ( ( width * bpp + 31 ) / 32 ) * sizeof(uint32_t);
|
|
slicePitch = rowPitch * height;
|
|
}
|
|
else
|
|
{
|
|
rowPitch = ( width * bpp + 7 ) / 8;
|
|
slicePitch = rowPitch * height;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//-------------------------------------------------------------------------------------
|
|
// Converts to an SRGB equivalent type if available
|
|
//-------------------------------------------------------------------------------------
|
|
_Use_decl_annotations_
|
|
DXGI_FORMAT MakeSRGB( DXGI_FORMAT fmt )
|
|
{
|
|
switch( fmt )
|
|
{
|
|
case DXGI_FORMAT_R8G8B8A8_UNORM:
|
|
return DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
|
|
|
|
case DXGI_FORMAT_BC1_UNORM:
|
|
return DXGI_FORMAT_BC1_UNORM_SRGB;
|
|
|
|
case DXGI_FORMAT_BC2_UNORM:
|
|
return DXGI_FORMAT_BC2_UNORM_SRGB;
|
|
|
|
case DXGI_FORMAT_BC3_UNORM:
|
|
return DXGI_FORMAT_BC3_UNORM_SRGB;
|
|
|
|
case DXGI_FORMAT_B8G8R8A8_UNORM:
|
|
return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
|
|
|
|
case DXGI_FORMAT_B8G8R8X8_UNORM:
|
|
return DXGI_FORMAT_B8G8R8X8_UNORM_SRGB;
|
|
|
|
case DXGI_FORMAT_BC7_UNORM:
|
|
return DXGI_FORMAT_BC7_UNORM_SRGB;
|
|
|
|
default:
|
|
return fmt;
|
|
}
|
|
}
|
|
|
|
|
|
//-------------------------------------------------------------------------------------
|
|
// Converts to a format to an equivalent TYPELESS format if available
|
|
//-------------------------------------------------------------------------------------
|
|
_Use_decl_annotations_
|
|
DXGI_FORMAT MakeTypeless( DXGI_FORMAT fmt )
|
|
{
|
|
switch( fmt )
|
|
{
|
|
case DXGI_FORMAT_R32G32B32A32_FLOAT:
|
|
case DXGI_FORMAT_R32G32B32A32_UINT:
|
|
case DXGI_FORMAT_R32G32B32A32_SINT:
|
|
return DXGI_FORMAT_R32G32B32A32_TYPELESS;
|
|
|
|
case DXGI_FORMAT_R32G32B32_FLOAT:
|
|
case DXGI_FORMAT_R32G32B32_UINT:
|
|
case DXGI_FORMAT_R32G32B32_SINT:
|
|
return DXGI_FORMAT_R32G32B32_TYPELESS;
|
|
|
|
case DXGI_FORMAT_R16G16B16A16_FLOAT:
|
|
case DXGI_FORMAT_R16G16B16A16_UNORM:
|
|
case DXGI_FORMAT_R16G16B16A16_UINT:
|
|
case DXGI_FORMAT_R16G16B16A16_SNORM:
|
|
case DXGI_FORMAT_R16G16B16A16_SINT:
|
|
return DXGI_FORMAT_R16G16B16A16_TYPELESS;
|
|
|
|
case DXGI_FORMAT_R32G32_FLOAT:
|
|
case DXGI_FORMAT_R32G32_UINT:
|
|
case DXGI_FORMAT_R32G32_SINT:
|
|
return DXGI_FORMAT_R32G32_TYPELESS;
|
|
|
|
case DXGI_FORMAT_R10G10B10A2_UNORM:
|
|
case DXGI_FORMAT_R10G10B10A2_UINT:
|
|
return DXGI_FORMAT_R10G10B10A2_TYPELESS;
|
|
|
|
case DXGI_FORMAT_R8G8B8A8_UNORM:
|
|
case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
|
|
case DXGI_FORMAT_R8G8B8A8_UINT:
|
|
case DXGI_FORMAT_R8G8B8A8_SNORM:
|
|
case DXGI_FORMAT_R8G8B8A8_SINT:
|
|
return DXGI_FORMAT_R8G8B8A8_TYPELESS;
|
|
|
|
case DXGI_FORMAT_R16G16_FLOAT:
|
|
case DXGI_FORMAT_R16G16_UNORM:
|
|
case DXGI_FORMAT_R16G16_UINT:
|
|
case DXGI_FORMAT_R16G16_SNORM:
|
|
case DXGI_FORMAT_R16G16_SINT:
|
|
return DXGI_FORMAT_R16G16_TYPELESS;
|
|
|
|
case DXGI_FORMAT_D32_FLOAT:
|
|
case DXGI_FORMAT_R32_FLOAT:
|
|
case DXGI_FORMAT_R32_UINT:
|
|
case DXGI_FORMAT_R32_SINT:
|
|
return DXGI_FORMAT_R32_TYPELESS;
|
|
|
|
case DXGI_FORMAT_R8G8_UNORM:
|
|
case DXGI_FORMAT_R8G8_UINT:
|
|
case DXGI_FORMAT_R8G8_SNORM:
|
|
case DXGI_FORMAT_R8G8_SINT:
|
|
return DXGI_FORMAT_R8G8_TYPELESS;
|
|
|
|
case DXGI_FORMAT_R16_FLOAT:
|
|
case DXGI_FORMAT_D16_UNORM:
|
|
case DXGI_FORMAT_R16_UNORM:
|
|
case DXGI_FORMAT_R16_UINT:
|
|
case DXGI_FORMAT_R16_SNORM:
|
|
case DXGI_FORMAT_R16_SINT:
|
|
return DXGI_FORMAT_R16_TYPELESS;
|
|
|
|
case DXGI_FORMAT_R8_UNORM:
|
|
case DXGI_FORMAT_R8_UINT:
|
|
case DXGI_FORMAT_R8_SNORM:
|
|
case DXGI_FORMAT_R8_SINT:
|
|
case DXGI_FORMAT_A8_UNORM:
|
|
return DXGI_FORMAT_R8_TYPELESS;
|
|
|
|
case DXGI_FORMAT_BC1_UNORM:
|
|
case DXGI_FORMAT_BC1_UNORM_SRGB:
|
|
return DXGI_FORMAT_BC1_TYPELESS;
|
|
|
|
case DXGI_FORMAT_BC2_UNORM:
|
|
case DXGI_FORMAT_BC2_UNORM_SRGB:
|
|
return DXGI_FORMAT_BC2_TYPELESS;
|
|
|
|
case DXGI_FORMAT_BC3_UNORM:
|
|
case DXGI_FORMAT_BC3_UNORM_SRGB:
|
|
return DXGI_FORMAT_BC3_TYPELESS;
|
|
|
|
case DXGI_FORMAT_BC4_UNORM:
|
|
case DXGI_FORMAT_BC4_SNORM:
|
|
return DXGI_FORMAT_BC4_TYPELESS;
|
|
|
|
case DXGI_FORMAT_BC5_UNORM:
|
|
case DXGI_FORMAT_BC5_SNORM:
|
|
return DXGI_FORMAT_BC5_TYPELESS;
|
|
|
|
case DXGI_FORMAT_B8G8R8A8_UNORM:
|
|
case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
|
|
return DXGI_FORMAT_B8G8R8A8_TYPELESS;
|
|
|
|
case DXGI_FORMAT_B8G8R8X8_UNORM:
|
|
case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
|
|
return DXGI_FORMAT_B8G8R8X8_TYPELESS;
|
|
|
|
case DXGI_FORMAT_BC6H_UF16:
|
|
case DXGI_FORMAT_BC6H_SF16:
|
|
return DXGI_FORMAT_BC6H_TYPELESS;
|
|
|
|
case DXGI_FORMAT_BC7_UNORM:
|
|
case DXGI_FORMAT_BC7_UNORM_SRGB:
|
|
return DXGI_FORMAT_BC7_TYPELESS;
|
|
|
|
default:
|
|
return fmt;
|
|
}
|
|
}
|
|
|
|
|
|
//-------------------------------------------------------------------------------------
|
|
// Converts to a TYPELESS format to an equivalent UNORM format if available
|
|
//-------------------------------------------------------------------------------------
|
|
_Use_decl_annotations_
|
|
DXGI_FORMAT MakeTypelessUNORM( DXGI_FORMAT fmt )
|
|
{
|
|
switch( fmt )
|
|
{
|
|
case DXGI_FORMAT_R16G16B16A16_TYPELESS:
|
|
return DXGI_FORMAT_R16G16B16A16_UNORM;
|
|
|
|
case DXGI_FORMAT_R10G10B10A2_TYPELESS:
|
|
return DXGI_FORMAT_R10G10B10A2_UNORM;
|
|
|
|
case DXGI_FORMAT_R8G8B8A8_TYPELESS:
|
|
return DXGI_FORMAT_R8G8B8A8_UNORM;
|
|
|
|
case DXGI_FORMAT_R16G16_TYPELESS:
|
|
return DXGI_FORMAT_R16G16_UNORM;
|
|
|
|
case DXGI_FORMAT_R8G8_TYPELESS:
|
|
return DXGI_FORMAT_R8G8_UNORM;
|
|
|
|
case DXGI_FORMAT_R16_TYPELESS:
|
|
return DXGI_FORMAT_R16_UNORM;
|
|
|
|
case DXGI_FORMAT_R8_TYPELESS:
|
|
return DXGI_FORMAT_R8_UNORM;
|
|
|
|
case DXGI_FORMAT_BC1_TYPELESS:
|
|
return DXGI_FORMAT_BC1_UNORM;
|
|
|
|
case DXGI_FORMAT_BC2_TYPELESS:
|
|
return DXGI_FORMAT_BC2_UNORM;
|
|
|
|
case DXGI_FORMAT_BC3_TYPELESS:
|
|
return DXGI_FORMAT_BC3_UNORM;
|
|
|
|
case DXGI_FORMAT_BC4_TYPELESS:
|
|
return DXGI_FORMAT_BC4_UNORM;
|
|
|
|
case DXGI_FORMAT_BC5_TYPELESS:
|
|
return DXGI_FORMAT_BC5_UNORM;
|
|
|
|
case DXGI_FORMAT_B8G8R8A8_TYPELESS:
|
|
return DXGI_FORMAT_B8G8R8A8_UNORM;
|
|
|
|
case DXGI_FORMAT_B8G8R8X8_TYPELESS:
|
|
return DXGI_FORMAT_B8G8R8X8_UNORM;
|
|
|
|
case DXGI_FORMAT_BC7_TYPELESS:
|
|
return DXGI_FORMAT_BC7_UNORM;
|
|
|
|
default:
|
|
return fmt;
|
|
}
|
|
}
|
|
|
|
|
|
//-------------------------------------------------------------------------------------
|
|
// Converts to a TYPELESS format to an equivalent FLOAT format if available
|
|
//-------------------------------------------------------------------------------------
|
|
_Use_decl_annotations_
|
|
DXGI_FORMAT MakeTypelessFLOAT( DXGI_FORMAT fmt )
|
|
{
|
|
switch( fmt )
|
|
{
|
|
case DXGI_FORMAT_R32G32B32A32_TYPELESS:
|
|
return DXGI_FORMAT_R32G32B32A32_FLOAT;
|
|
|
|
case DXGI_FORMAT_R32G32B32_TYPELESS:
|
|
return DXGI_FORMAT_R32G32B32_FLOAT;
|
|
|
|
case DXGI_FORMAT_R16G16B16A16_TYPELESS:
|
|
return DXGI_FORMAT_R16G16B16A16_FLOAT;
|
|
|
|
case DXGI_FORMAT_R32G32_TYPELESS:
|
|
return DXGI_FORMAT_R32G32_FLOAT;
|
|
|
|
case DXGI_FORMAT_R16G16_TYPELESS:
|
|
return DXGI_FORMAT_R16G16_FLOAT;
|
|
|
|
case DXGI_FORMAT_R32_TYPELESS:
|
|
return DXGI_FORMAT_R32_FLOAT;
|
|
|
|
case DXGI_FORMAT_R16_TYPELESS:
|
|
return DXGI_FORMAT_R16_FLOAT;
|
|
|
|
default:
|
|
return fmt;
|
|
}
|
|
}
|
|
|
|
|
|
//=====================================================================================
|
|
// TexMetadata
|
|
//=====================================================================================
|
|
|
|
_Use_decl_annotations_
|
|
size_t TexMetadata::ComputeIndex( size_t mip, size_t item, size_t slice ) const
|
|
{
|
|
if ( mip >= mipLevels )
|
|
return size_t(-1);
|
|
|
|
switch( dimension )
|
|
{
|
|
case TEX_DIMENSION_TEXTURE1D:
|
|
case TEX_DIMENSION_TEXTURE2D:
|
|
if ( slice > 0 )
|
|
return size_t(-1);
|
|
|
|
if ( item >= arraySize )
|
|
return size_t(-1);
|
|
|
|
return (item*( mipLevels ) + mip);
|
|
|
|
case TEX_DIMENSION_TEXTURE3D:
|
|
if ( item > 0 )
|
|
{
|
|
// No support for arrays of volumes
|
|
return size_t(-1);
|
|
}
|
|
else
|
|
{
|
|
size_t index = 0;
|
|
size_t d = depth;
|
|
|
|
for( size_t level = 0; level < mip; ++level )
|
|
{
|
|
index += d;
|
|
if ( d > 1 )
|
|
d >>= 1;
|
|
}
|
|
|
|
if ( slice >= d )
|
|
return size_t(-1);
|
|
|
|
index += slice;
|
|
|
|
return index;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return size_t(-1);
|
|
}
|
|
}
|
|
|
|
|
|
//=====================================================================================
|
|
// Blob - Bitmap image container
|
|
//=====================================================================================
|
|
|
|
void Blob::Release()
|
|
{
|
|
if ( _buffer )
|
|
{
|
|
_aligned_free( _buffer );
|
|
_buffer = nullptr;
|
|
}
|
|
|
|
_size = 0;
|
|
}
|
|
|
|
_Use_decl_annotations_
|
|
HRESULT Blob::Initialize( size_t size )
|
|
{
|
|
if ( !size )
|
|
return E_INVALIDARG;
|
|
|
|
Release();
|
|
|
|
_buffer = _aligned_malloc( size, 16 );
|
|
if ( !_buffer )
|
|
{
|
|
Release();
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
|
|
_size = size;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
}; // namespace
|