diff --git a/DirectXTex/DirectXTex.h b/DirectXTex/DirectXTex.h index 85e8d37..1a7481c 100644 --- a/DirectXTex/DirectXTex.h +++ b/DirectXTex/DirectXTex.h @@ -57,7 +57,7 @@ #endif #endif -#define DIRECTX_TEX_VERSION 132 +#define DIRECTX_TEX_VERSION 133 namespace DirectX { diff --git a/DirectXTex/DirectXTex.inl b/DirectXTex/DirectXTex.inl index 8ab5731..ea0852b 100644 --- a/DirectXTex/DirectXTex.inl +++ b/DirectXTex/DirectXTex.inl @@ -22,7 +22,7 @@ _Use_decl_annotations_ inline bool __cdecl IsValid( DXGI_FORMAT fmt ) { - return ( static_cast(fmt) >= 1 && static_cast(fmt) <= 120 ); + return ( static_cast(fmt) >= 1 && static_cast(fmt) <= 190 ); } _Use_decl_annotations_ @@ -58,46 +58,6 @@ inline bool __cdecl IsCompressed(DXGI_FORMAT fmt) } } -_Use_decl_annotations_ -inline bool __cdecl IsPacked(DXGI_FORMAT fmt) -{ - switch( fmt ) - { - case DXGI_FORMAT_R8G8_B8G8_UNORM: - case DXGI_FORMAT_G8R8_G8B8_UNORM: - case DXGI_FORMAT_YUY2: // 4:2:2 8-bit - case DXGI_FORMAT_Y210: // 4:2:2 10-bit - case DXGI_FORMAT_Y216: // 4:2:2 16-bit - return true; - - default: - return false; - } -} - -_Use_decl_annotations_ -inline bool __cdecl IsPlanar(DXGI_FORMAT fmt) -{ - switch ( static_cast(fmt) ) - { - case DXGI_FORMAT_NV12: // 4:2:0 8-bit - case DXGI_FORMAT_P010: // 4:2:0 10-bit - case DXGI_FORMAT_P016: // 4:2:0 16-bit - case DXGI_FORMAT_420_OPAQUE:// 4:2:0 8-bit - case DXGI_FORMAT_NV11: // 4:1:1 8-bit - return true; - - case 118 /* DXGI_FORMAT_D16_UNORM_S8_UINT */: - case 119 /* DXGI_FORMAT_R16_UNORM_X8_TYPELESS */: - case 120 /* DXGI_FORMAT_X16_TYPELESS_G8_UINT */: - // These are Xbox One platform specific types - return true; - - default: - return false; - } -} - _Use_decl_annotations_ inline bool __cdecl IsPalettized(DXGI_FORMAT fmt) { @@ -114,59 +74,6 @@ inline bool __cdecl IsPalettized(DXGI_FORMAT fmt) } } -_Use_decl_annotations_ -inline bool __cdecl IsVideo(DXGI_FORMAT fmt) -{ - switch ( fmt ) - { - case DXGI_FORMAT_AYUV: - case DXGI_FORMAT_Y410: - case DXGI_FORMAT_Y416: - case DXGI_FORMAT_NV12: - case DXGI_FORMAT_P010: - case DXGI_FORMAT_P016: - case DXGI_FORMAT_YUY2: - case DXGI_FORMAT_Y210: - case DXGI_FORMAT_Y216: - case DXGI_FORMAT_NV11: - // These video formats can be used with the 3D pipeline through special view mappings - - case DXGI_FORMAT_420_OPAQUE: - case DXGI_FORMAT_AI44: - case DXGI_FORMAT_IA44: - case DXGI_FORMAT_P8: - case DXGI_FORMAT_A8P8: - // These are limited use video formats not usable in any way by the 3D pipeline - return true; - - default: - return false; - } -} - -_Use_decl_annotations_ -inline bool __cdecl IsDepthStencil(DXGI_FORMAT fmt) -{ - switch( static_cast(fmt) ) - { - case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: - case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: - case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: - case DXGI_FORMAT_D32_FLOAT: - case DXGI_FORMAT_D24_UNORM_S8_UINT: - case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: - case DXGI_FORMAT_X24_TYPELESS_G8_UINT: - case DXGI_FORMAT_D16_UNORM: - case 118 /* DXGI_FORMAT_D16_UNORM_S8_UINT */: - case 119 /* DXGI_FORMAT_R16_UNORM_X8_TYPELESS */: - case 120 /* DXGI_FORMAT_X16_TYPELESS_G8_UINT */: - return true; - - default: - return false; - } -} - _Use_decl_annotations_ inline bool __cdecl IsSRGB(DXGI_FORMAT fmt) { @@ -186,133 +93,6 @@ inline bool __cdecl IsSRGB(DXGI_FORMAT fmt) } } -_Use_decl_annotations_ -inline bool __cdecl IsTypeless(DXGI_FORMAT fmt, bool partialTypeless) -{ - switch( static_cast(fmt) ) - { - case DXGI_FORMAT_R32G32B32A32_TYPELESS: - case DXGI_FORMAT_R32G32B32_TYPELESS: - case DXGI_FORMAT_R16G16B16A16_TYPELESS: - case DXGI_FORMAT_R32G32_TYPELESS: - case DXGI_FORMAT_R32G8X24_TYPELESS: - case DXGI_FORMAT_R10G10B10A2_TYPELESS: - case DXGI_FORMAT_R8G8B8A8_TYPELESS: - case DXGI_FORMAT_R16G16_TYPELESS: - case DXGI_FORMAT_R32_TYPELESS: - case DXGI_FORMAT_R24G8_TYPELESS: - case DXGI_FORMAT_R8G8_TYPELESS: - case DXGI_FORMAT_R16_TYPELESS: - case DXGI_FORMAT_R8_TYPELESS: - case DXGI_FORMAT_BC1_TYPELESS: - case DXGI_FORMAT_BC2_TYPELESS: - case DXGI_FORMAT_BC3_TYPELESS: - case DXGI_FORMAT_BC4_TYPELESS: - case DXGI_FORMAT_BC5_TYPELESS: - case DXGI_FORMAT_B8G8R8A8_TYPELESS: - case DXGI_FORMAT_B8G8R8X8_TYPELESS: - case DXGI_FORMAT_BC6H_TYPELESS: - case DXGI_FORMAT_BC7_TYPELESS: - return true; - - case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: - case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: - case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: - case DXGI_FORMAT_X24_TYPELESS_G8_UINT: - return partialTypeless; - - case 119 /* DXGI_FORMAT_R16_UNORM_X8_TYPELESS */: - case 120 /* DXGI_FORMAT_X16_TYPELESS_G8_UINT */: - // These are Xbox One platform specific types - return partialTypeless; - - default: - return false; - } -} - -_Use_decl_annotations_ -inline bool __cdecl HasAlpha(DXGI_FORMAT fmt) -{ - switch( static_cast(fmt) ) - { - case DXGI_FORMAT_R32G32B32A32_TYPELESS: - case DXGI_FORMAT_R32G32B32A32_FLOAT: - case DXGI_FORMAT_R32G32B32A32_UINT: - case DXGI_FORMAT_R32G32B32A32_SINT: - 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_R10G10B10A2_TYPELESS: - case DXGI_FORMAT_R10G10B10A2_UNORM: - case DXGI_FORMAT_R10G10B10A2_UINT: - 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_A8_UNORM: - 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_B5G5R5A1_UNORM: - case DXGI_FORMAT_B8G8R8A8_UNORM: - case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: - case DXGI_FORMAT_B8G8R8A8_TYPELESS: - case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: - case DXGI_FORMAT_BC7_TYPELESS: - case DXGI_FORMAT_BC7_UNORM: - case DXGI_FORMAT_BC7_UNORM_SRGB: - case DXGI_FORMAT_AYUV: - case DXGI_FORMAT_Y410: - case DXGI_FORMAT_Y416: - case DXGI_FORMAT_AI44: - case DXGI_FORMAT_IA44: - case DXGI_FORMAT_A8P8: - case DXGI_FORMAT_B4G4R4A4_UNORM: - return true; - - case 116 /* DXGI_FORMAT_R10G10B10_7E3_A2_FLOAT */: - case 117 /* DXGI_FORMAT_R10G10B10_6E4_A2_FLOAT */: - // These are Xbox One platform specific types - return true; - - default: - return false; - } -} - -_Use_decl_annotations_ -inline size_t __cdecl ComputeScanlines(DXGI_FORMAT fmt, size_t height) -{ - if ( IsCompressed(fmt) ) - { - return std::max( 1, (height + 3) / 4 ); - } - else if ( fmt == DXGI_FORMAT_NV11 ) - { - // Direct3D makes this simplifying assumption, although it is larger than the 4:1:1 data - return height * 2; - } - else if ( IsPlanar(fmt) ) - { - return height + ( ( height + 1 ) >> 1 ); - } - else - { - return height; - } -} //===================================================================================== // Image I/O diff --git a/DirectXTex/DirectXTexConvert.cpp b/DirectXTex/DirectXTexConvert.cpp index abdda07..f1e5713 100644 --- a/DirectXTex/DirectXTexConvert.cpp +++ b/DirectXTex/DirectXTexConvert.cpp @@ -235,7 +235,7 @@ void _CopyScanline(_When_(pDestination == pSource, _Inout_updates_bytes_(outSize *(dPtr++) = *(sPtr++); *(dPtr++) = *(sPtr++); *(dPtr++) = alpha; - sPtr++; + ++sPtr; } } } @@ -279,7 +279,7 @@ void _CopyScanline(_When_(pDestination == pSource, _Inout_updates_bytes_(outSize *(dPtr++) = *(sPtr++); *(dPtr++) = *(sPtr++); *(dPtr++) = alpha; - sPtr++; + ++sPtr; } } } @@ -291,8 +291,9 @@ void _CopyScanline(_When_(pDestination == pSource, _Inout_updates_bytes_(outSize case DXGI_FORMAT_R10G10B10A2_UINT: case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: case DXGI_FORMAT_Y410: - case 116 /* DXGI_FORMAT_R10G10B10_7E3_A2_FLOAT */: - case 117 /* DXGI_FORMAT_R10G10B10_6E4_A2_FLOAT */: + case XBOX_DXGI_FORMAT_R10G10B10_7E3_A2_FLOAT: + case XBOX_DXGI_FORMAT_R10G10B10_6E4_A2_FLOAT: + case XBOX_DXGI_FORMAT_R10G10B10_SNORM_A2_UNORM: if ( inSize >= 4 && outSize >= 4 ) { if ( pDestination == pSource ) @@ -434,13 +435,14 @@ void _SwizzleScanline( LPVOID pDestination, size_t outSize, LPCVOID pSource, siz assert( pSource && inSize > 0 ); assert( IsValid(format) && !IsPlanar(format) && !IsPalettized(format) ); - switch( format ) + switch( static_cast(format) ) { //--------------------------------------------------------------------------------- case DXGI_FORMAT_R10G10B10A2_TYPELESS: case DXGI_FORMAT_R10G10B10A2_UNORM: case DXGI_FORMAT_R10G10B10A2_UINT: case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: + case XBOX_DXGI_FORMAT_R10G10B10_SNORM_A2_UNORM: if ( inSize >= 4 && outSize >= 4 ) { if ( flags & TEXP_SCANLINE_LEGACY ) @@ -1521,7 +1523,7 @@ _Use_decl_annotations_ bool _LoadScanline( XMVECTOR* pDestination, size_t count, } return false; - case 116 /* DXGI_FORMAT_R10G10B10_7E3_A2_FLOAT */: + case XBOX_DXGI_FORMAT_R10G10B10_7E3_A2_FLOAT: // Xbox One specific 7e3 format if ( size >= sizeof(XMUDECN4) ) { @@ -1545,7 +1547,7 @@ _Use_decl_annotations_ bool _LoadScanline( XMVECTOR* pDestination, size_t count, } return false; - case 117 /* DXGI_FORMAT_R10G10B10_6E4_A2_FLOAT */: + case XBOX_DXGI_FORMAT_R10G10B10_6E4_A2_FLOAT: // Xbox One specific 6e4 format if ( size >= sizeof(XMUDECN4) ) { @@ -1569,6 +1571,29 @@ _Use_decl_annotations_ bool _LoadScanline( XMVECTOR* pDestination, size_t count, } return false; + case XBOX_DXGI_FORMAT_R10G10B10_SNORM_A2_UNORM: + // Xbox One specific format + LOAD_SCANLINE( XMXDECN4, XMLoadXDecN4 ); + + case XBOX_DXGI_FORMAT_R4G4_UNORM: + // Xbox One specific format + if ( size >= sizeof(uint8_t) ) + { + static const XMVECTORF32 s_Scale = { 1.f/15.f, 1.f/15.f, 0.f, 0.f }; + const uint8_t * __restrict sPtr = reinterpret_cast(pSource); + for( size_t icount = 0; icount < ( size - sizeof(uint8_t) + 1 ); icount += sizeof(uint8_t) ) + { + XMUNIBBLE4 nibble; + nibble.v = static_cast( *sPtr++ ); + XMVECTOR v = XMLoadUNibble4( &nibble ); + v = XMVectorMultiply( v, s_Scale ); + if ( dPtr >= ePtr ) break; + *(dPtr++) = XMVectorSelect( g_XMIdentityR3, v, g_XMSelect1100 ); + } + return true; + } + return false; + // We don't support the planar or palettized formats default: @@ -2429,7 +2454,7 @@ bool _StoreScanline( LPVOID pDestination, size_t size, DXGI_FORMAT format, } return false; - case 116 /* DXGI_FORMAT_R10G10B10_7E3_A2_FLOAT */: + case XBOX_DXGI_FORMAT_R10G10B10_7E3_A2_FLOAT: // Xbox One specific 7e3 format with alpha if ( size >= sizeof(XMUDECN4) ) { @@ -2457,7 +2482,7 @@ bool _StoreScanline( LPVOID pDestination, size_t size, DXGI_FORMAT format, } return false; - case 117 /* DXGI_FORMAT_R10G10B10_6E4_A2_FLOAT */: + case XBOX_DXGI_FORMAT_R10G10B10_6E4_A2_FLOAT: // Xbox One specific 6e4 format with alpha if ( size >= sizeof(XMUDECN4) ) { @@ -2485,6 +2510,30 @@ bool _StoreScanline( LPVOID pDestination, size_t size, DXGI_FORMAT format, } return false; + case XBOX_DXGI_FORMAT_R10G10B10_SNORM_A2_UNORM: + // Xbox One specific format + STORE_SCANLINE( XMXDECN4, XMStoreXDecN4 ); + + case XBOX_DXGI_FORMAT_R4G4_UNORM: + // Xbox One specific format + if ( size >= sizeof(uint8_t) ) + { + static const XMVECTORF32 s_Scale = { 15.f, 15.f, 0.f, 0.f }; + uint8_t * __restrict dPtr = reinterpret_cast(pDestination); + for( size_t icount = 0; icount < ( size - sizeof(uint8_t) + 1 ); icount += sizeof(uint8_t) ) + { + if ( sPtr >= ePtr ) break; + XMVECTOR v = XMVectorMultiply( *sPtr++, s_Scale ); + + XMUNIBBLE4 nibble; + XMStoreUNibble4( &nibble, v ); + *dPtr = static_cast( nibble.v ); + ++dPtr; + } + return true; + } + return false; + // We don't support the planar or palettized formats default: @@ -2929,10 +2978,10 @@ static const ConvertData g_ConvertTable[] = { { DXGI_FORMAT_Y210, 10, CONVF_UNORM | CONVF_YUV | CONVF_PACKED | CONVF_R | CONVF_G | CONVF_B }, { DXGI_FORMAT_Y216, 16, CONVF_UNORM | CONVF_YUV | CONVF_PACKED | CONVF_R | CONVF_G | CONVF_B }, { DXGI_FORMAT_B4G4R4A4_UNORM, 4, CONVF_UNORM | CONVF_BGR | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, - { DXGI_FORMAT(116) - /* DXGI_FORMAT_R10G10B10_7E3_A2_FLOAT */, 10, CONVF_FLOAT | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, - { DXGI_FORMAT(117) - /* DXGI_FORMAT_R10G10B10_6E4_A2_FLOAT */, 10, CONVF_FLOAT | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, + { XBOX_DXGI_FORMAT_R10G10B10_7E3_A2_FLOAT, 10, CONVF_FLOAT | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, + { XBOX_DXGI_FORMAT_R10G10B10_6E4_A2_FLOAT, 10, CONVF_FLOAT | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, + { XBOX_DXGI_FORMAT_R10G10B10_SNORM_A2_UNORM,10, CONVF_SNORM | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, + { XBOX_DXGI_FORMAT_R4G4_UNORM, 4, CONVF_UNORM | CONVF_R | CONVF_G }, }; #pragma prefast( suppress : 25004, "Signature must match bsearch_s" ); @@ -3588,6 +3637,7 @@ static const float g_Dither[] = static const XMVECTORF32 g_Scale16pc = { 65535.f, 65535.f, 65535.f, 65535.f }; static const XMVECTORF32 g_Scale15pc = { 32767.f, 32767.f, 32767.f, 32767.f }; static const XMVECTORF32 g_Scale10pc = { 1023.f, 1023.f, 1023.f, 3.f }; +static const XMVECTORF32 g_Scale9pc = { 511.f, 511.f, 511.f, 3.f }; static const XMVECTORF32 g_Scale8pc = { 255.f, 255.f, 255.f, 255.f }; static const XMVECTORF32 g_Scale7pc = { 127.f, 127.f, 127.f, 127.f }; static const XMVECTORF32 g_Scale565pc = { 31.f, 63.f, 31.f, 1.f }; @@ -3801,7 +3851,7 @@ bool _StoreScanlineDither( LPVOID pDestination, size_t size, DXGI_FORMAT format, XMVECTOR vError = XMVectorZero(); - switch( format ) + switch( static_cast(format) ) { case DXGI_FORMAT_R16G16B16A16_UNORM: STORE_SCANLINE( XMUSHORTN4, g_Scale16pc, true, true, uint16_t, 0xFFFF, y, false ) @@ -4143,6 +4193,54 @@ bool _StoreScanlineDither( LPVOID pDestination, size_t size, DXGI_FORMAT format, case DXGI_FORMAT_B4G4R4A4_UNORM: STORE_SCANLINE( XMUNIBBLE4, g_Scale4pc, true, true, uint8_t, 0xF, y, true ) + case XBOX_DXGI_FORMAT_R10G10B10_SNORM_A2_UNORM: + STORE_SCANLINE( XMXDECN4, g_Scale9pc, false, true, uint16_t, 0x3FF, y, false ) + + case XBOX_DXGI_FORMAT_R4G4_UNORM: + if ( size >= sizeof(uint8_t) ) + { + uint8_t * __restrict dest = reinterpret_cast(pDestination); + for( size_t i = 0; i < count; ++i ) + { + ptrdiff_t index = static_cast( ( y & 1 ) ? ( count - i - 1 ) : i ); + ptrdiff_t delta = ( y & 1 ) ? -2 : 0; + + XMVECTOR v = XMVectorSaturate( sPtr[ index ] ); + v = XMVectorAdd( v, vError ); + v = XMVectorMultiply( v, g_Scale4pc ); + + XMVECTOR target; + if ( pDiffusionErrors ) + { + target = XMVectorRound( v ); + vError = XMVectorSubtract( v, target ); + vError = XMVectorDivide( vError, g_Scale4pc ); + + // Distribute error to next scanline and next pixel + pDiffusionErrors[ index-delta ] += XMVectorMultiply( g_ErrorWeight3, vError ); + pDiffusionErrors[ index+1 ] += XMVectorMultiply( g_ErrorWeight5, vError ); + pDiffusionErrors[ index+2+delta ] += XMVectorMultiply( g_ErrorWeight1, vError ); + vError = XMVectorMultiply( vError, g_ErrorWeight7 ); + } + else + { + // Applied ordered dither + target = XMVectorAdd( v, ordered[ index & 3 ] ); + target = XMVectorRound( target ); + } + + target = XMVectorClamp( target, g_XMZero, g_Scale4pc ); + + XMFLOAT4A tmp; + XMStoreFloat4A( &tmp, target ); + + dest[index] = ( static_cast( tmp.x ) & 0xF ) + | ( ( static_cast( tmp.y ) & 0xF ) << 4 ); + } + return true; + } + return false; + default: return _StoreScanline( pDestination, size, format, pSource, count, threshold ); } @@ -4415,10 +4513,12 @@ static DXGI_FORMAT _PlanarToSingle( _In_ DXGI_FORMAT format ) case DXGI_FORMAT_P016: return DXGI_FORMAT_Y216; - // We currently do not support conversion for Xbox One specific depth formats + // We currently do not support conversion for Xbox One specific 16-bit depth formats // We can't do anything with DXGI_FORMAT_420_OPAQUE because it's an opaque blob of bits + // We don't support conversion of JPEG Hardware decode formats + default: return DXGI_FORMAT_UNKNOWN; } diff --git a/DirectXTex/DirectXTexP.h b/DirectXTex/DirectXTexP.h index 497b001..e4edc06 100644 --- a/DirectXTex/DirectXTexP.h +++ b/DirectXTex/DirectXTexP.h @@ -15,7 +15,18 @@ #pragma once +#if !defined(WIN32_LEAN_AND_MEAN) +#define WIN32_LEAN_AND_MEAN +#endif + +#if !defined(NOMINMAX) #define NOMINMAX +#endif + +#ifndef _WIN32_WINNT_WIN10 +#define _WIN32_WINNT_WIN10 0x0A00 +#endif + #include #include #include @@ -48,6 +59,23 @@ struct IWICImagingFactory; #define TEX_FILTER_MASK 0xF00000 +#define XBOX_DXGI_FORMAT_R10G10B10_7E3_A2_FLOAT DXGI_FORMAT(116) +#define XBOX_DXGI_FORMAT_R10G10B10_6E4_A2_FLOAT DXGI_FORMAT(117) +#define XBOX_DXGI_FORMAT_D16_UNORM_S8_UINT DXGI_FORMAT(118) +#define XBOX_DXGI_FORMAT_R16_UNORM_X8_TYPELESS DXGI_FORMAT(119) +#define XBOX_DXGI_FORMAT_X16_TYPELESS_G8_UINT DXGI_FORMAT(120) + +#define WIN10_DXGI_FORMAT_P208 DXGI_FORMAT(130) +#define WIN10_DXGI_FORMAT_V208 DXGI_FORMAT(131) +#define WIN10_DXGI_FORMAT_V408 DXGI_FORMAT(132) + +#ifndef XBOX_DXGI_FORMAT_R10G10B10_SNORM_A2_UNORM +#define XBOX_DXGI_FORMAT_R10G10B10_SNORM_A2_UNORM DXGI_FORMAT(189) +#endif + +#define XBOX_DXGI_FORMAT_R4G4_UNORM DXGI_FORMAT(190) + + namespace DirectX { //--------------------------------------------------------------------------------- diff --git a/DirectXTex/DirectXTexUtil.cpp b/DirectXTex/DirectXTexUtil.cpp index 3f7850e..3170ee3 100644 --- a/DirectXTex/DirectXTexUtil.cpp +++ b/DirectXTex/DirectXTexUtil.cpp @@ -15,6 +15,23 @@ #include "directxtexp.h" +#if defined(_XBOX_ONE) && defined(_TITLE) +static_assert(XBOX_DXGI_FORMAT_R10G10B10_7E3_A2_FLOAT == DXGI_FORMAT_R10G10B10_7E3_A2_FLOAT, "Xbox One XDK mismatch detected"); +static_assert(XBOX_DXGI_FORMAT_R10G10B10_6E4_A2_FLOAT == DXGI_FORMAT_R10G10B10_6E4_A2_FLOAT, "Xbox One XDK mismatch detected"); +static_assert(XBOX_DXGI_FORMAT_D16_UNORM_S8_UINT == DXGI_FORMAT_D16_UNORM_S8_UINT, "Xbox One XDK mismatch detected"); +static_assert(XBOX_DXGI_FORMAT_R16_UNORM_X8_TYPELESS == DXGI_FORMAT_R16_UNORM_X8_TYPELESS, "Xbox One XDK mismatch detected"); +static_assert(XBOX_DXGI_FORMAT_X16_TYPELESS_G8_UINT == DXGI_FORMAT_X16_TYPELESS_G8_UINT, "Xbox One XDK mismatch detected"); +static_assert(XBOX_DXGI_FORMAT_R10G10B10_SNORM_A2_UNORM == DXGI_FORMAT_R10G10B10_SNORM_A2_UNORM, "Xbox One XDK mismatch detected"); +static_assert(XBOX_DXGI_FORMAT_R4G4_UNORM == DXGI_FORMAT_R4G4_UNORM, "Xbox One XDK mismatch detected"); +#endif + +#if (_WIN32_WINNT >= _WIN32_WINNT_WIN10) +static_assert(WIN10_DXGI_FORMAT_P208 == DXGI_FORMAT_P208, "Windows SDK mismatch detected"); +static_assert(WIN10_DXGI_FORMAT_V208 == DXGI_FORMAT_V208, "Windows SDK mismatch detected"); +static_assert(WIN10_DXGI_FORMAT_V408 == DXGI_FORMAT_V408, "Windows SDK mismatch detected"); +#endif + + //------------------------------------------------------------------------------------- // WIC Pixel Format Translation Data //------------------------------------------------------------------------------------- @@ -270,6 +287,222 @@ REFGUID GetWICCodec( WICCodecs codec ) // DXGI Format Utilities //===================================================================================== +//------------------------------------------------------------------------------------- +_Use_decl_annotations_ +bool IsPacked(DXGI_FORMAT fmt) +{ + switch( static_cast(fmt) ) + { + case DXGI_FORMAT_R8G8_B8G8_UNORM: + case DXGI_FORMAT_G8R8_G8B8_UNORM: + case DXGI_FORMAT_YUY2: // 4:2:2 8-bit + case DXGI_FORMAT_Y210: // 4:2:2 10-bit + case DXGI_FORMAT_Y216: // 4:2:2 16-bit + return true; + + default: + return false; + } +} + + +//------------------------------------------------------------------------------------- +_Use_decl_annotations_ +bool IsVideo(DXGI_FORMAT fmt) +{ + switch ( static_cast(fmt) ) + { + case DXGI_FORMAT_AYUV: + case DXGI_FORMAT_Y410: + case DXGI_FORMAT_Y416: + case DXGI_FORMAT_NV12: + case DXGI_FORMAT_P010: + case DXGI_FORMAT_P016: + case DXGI_FORMAT_YUY2: + case DXGI_FORMAT_Y210: + case DXGI_FORMAT_Y216: + case DXGI_FORMAT_NV11: + // These video formats can be used with the 3D pipeline through special view mappings + + case DXGI_FORMAT_420_OPAQUE: + case DXGI_FORMAT_AI44: + case DXGI_FORMAT_IA44: + case DXGI_FORMAT_P8: + case DXGI_FORMAT_A8P8: + // These are limited use video formats not usable in any way by the 3D pipeline + + case WIN10_DXGI_FORMAT_P208: + case WIN10_DXGI_FORMAT_V208: + case WIN10_DXGI_FORMAT_V408: + // These video formats are for JPEG Hardware decode (DXGI 1.4) + return true; + + default: + return false; + } +} + + +//------------------------------------------------------------------------------------- +_Use_decl_annotations_ +bool IsPlanar(DXGI_FORMAT fmt) +{ + switch ( static_cast(fmt) ) + { + case DXGI_FORMAT_NV12: // 4:2:0 8-bit + case DXGI_FORMAT_P010: // 4:2:0 10-bit + case DXGI_FORMAT_P016: // 4:2:0 16-bit + case DXGI_FORMAT_420_OPAQUE:// 4:2:0 8-bit + case DXGI_FORMAT_NV11: // 4:1:1 8-bit + + case WIN10_DXGI_FORMAT_P208: // 4:2:2 8-bit + case WIN10_DXGI_FORMAT_V208: // 4:4:0 8-bit + case WIN10_DXGI_FORMAT_V408: // 4:4:4 8-bit + // These are JPEG Hardware decode formats (DXGI 1.4) + + case XBOX_DXGI_FORMAT_D16_UNORM_S8_UINT: + case XBOX_DXGI_FORMAT_R16_UNORM_X8_TYPELESS: + case XBOX_DXGI_FORMAT_X16_TYPELESS_G8_UINT: + // These are Xbox One platform specific types + return true; + + default: + return false; + } + +} + + +//------------------------------------------------------------------------------------- +_Use_decl_annotations_ +bool IsDepthStencil(DXGI_FORMAT fmt) +{ + switch( static_cast(fmt) ) + { + case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: + case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: + case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: + case DXGI_FORMAT_D32_FLOAT: + case DXGI_FORMAT_D24_UNORM_S8_UINT: + case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: + case DXGI_FORMAT_X24_TYPELESS_G8_UINT: + case DXGI_FORMAT_D16_UNORM: + case XBOX_DXGI_FORMAT_D16_UNORM_S8_UINT: + case XBOX_DXGI_FORMAT_R16_UNORM_X8_TYPELESS: + case XBOX_DXGI_FORMAT_X16_TYPELESS_G8_UINT: + return true; + + default: + return false; + } +} + + +//------------------------------------------------------------------------------------- +_Use_decl_annotations_ +bool IsTypeless(DXGI_FORMAT fmt, bool partialTypeless) +{ + switch( static_cast(fmt) ) + { + case DXGI_FORMAT_R32G32B32A32_TYPELESS: + case DXGI_FORMAT_R32G32B32_TYPELESS: + case DXGI_FORMAT_R16G16B16A16_TYPELESS: + case DXGI_FORMAT_R32G32_TYPELESS: + case DXGI_FORMAT_R32G8X24_TYPELESS: + case DXGI_FORMAT_R10G10B10A2_TYPELESS: + case DXGI_FORMAT_R8G8B8A8_TYPELESS: + case DXGI_FORMAT_R16G16_TYPELESS: + case DXGI_FORMAT_R32_TYPELESS: + case DXGI_FORMAT_R24G8_TYPELESS: + case DXGI_FORMAT_R8G8_TYPELESS: + case DXGI_FORMAT_R16_TYPELESS: + case DXGI_FORMAT_R8_TYPELESS: + case DXGI_FORMAT_BC1_TYPELESS: + case DXGI_FORMAT_BC2_TYPELESS: + case DXGI_FORMAT_BC3_TYPELESS: + case DXGI_FORMAT_BC4_TYPELESS: + case DXGI_FORMAT_BC5_TYPELESS: + case DXGI_FORMAT_B8G8R8A8_TYPELESS: + case DXGI_FORMAT_B8G8R8X8_TYPELESS: + case DXGI_FORMAT_BC6H_TYPELESS: + case DXGI_FORMAT_BC7_TYPELESS: + return true; + + case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: + case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: + case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: + case DXGI_FORMAT_X24_TYPELESS_G8_UINT: + case XBOX_DXGI_FORMAT_R16_UNORM_X8_TYPELESS: + case XBOX_DXGI_FORMAT_X16_TYPELESS_G8_UINT: + return partialTypeless; + + default: + return false; + } +} + + +//------------------------------------------------------------------------------------- +_Use_decl_annotations_ +bool HasAlpha(DXGI_FORMAT fmt) +{ + switch( static_cast(fmt) ) + { + case DXGI_FORMAT_R32G32B32A32_TYPELESS: + case DXGI_FORMAT_R32G32B32A32_FLOAT: + case DXGI_FORMAT_R32G32B32A32_UINT: + case DXGI_FORMAT_R32G32B32A32_SINT: + 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_R10G10B10A2_TYPELESS: + case DXGI_FORMAT_R10G10B10A2_UNORM: + case DXGI_FORMAT_R10G10B10A2_UINT: + 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_A8_UNORM: + 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_B5G5R5A1_UNORM: + case DXGI_FORMAT_B8G8R8A8_UNORM: + case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: + case DXGI_FORMAT_B8G8R8A8_TYPELESS: + case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: + case DXGI_FORMAT_BC7_TYPELESS: + case DXGI_FORMAT_BC7_UNORM: + case DXGI_FORMAT_BC7_UNORM_SRGB: + case DXGI_FORMAT_AYUV: + case DXGI_FORMAT_Y410: + case DXGI_FORMAT_Y416: + case DXGI_FORMAT_AI44: + case DXGI_FORMAT_IA44: + case DXGI_FORMAT_A8P8: + case DXGI_FORMAT_B4G4R4A4_UNORM: + case XBOX_DXGI_FORMAT_R10G10B10_7E3_A2_FLOAT: + case XBOX_DXGI_FORMAT_R10G10B10_6E4_A2_FLOAT: + case XBOX_DXGI_FORMAT_R10G10B10_SNORM_A2_UNORM: + return true; + + default: + return false; + } +} + + //------------------------------------------------------------------------------------- // Returns bits-per-pixel for a given DXGI format, or 0 on failure //------------------------------------------------------------------------------------- @@ -347,15 +580,17 @@ size_t BitsPerPixel( DXGI_FORMAT fmt ) case DXGI_FORMAT_AYUV: case DXGI_FORMAT_Y410: case DXGI_FORMAT_YUY2: - case 116 /* DXGI_FORMAT_R10G10B10_7E3_A2_FLOAT */: - case 117 /* DXGI_FORMAT_R10G10B10_6E4_A2_FLOAT */: + case XBOX_DXGI_FORMAT_R10G10B10_7E3_A2_FLOAT: + case XBOX_DXGI_FORMAT_R10G10B10_6E4_A2_FLOAT: + case XBOX_DXGI_FORMAT_R10G10B10_SNORM_A2_UNORM: return 32; case DXGI_FORMAT_P010: case DXGI_FORMAT_P016: - case 118 /* DXGI_FORMAT_D16_UNORM_S8_UINT */: - case 119 /* DXGI_FORMAT_R16_UNORM_X8_TYPELESS */: - case 120 /* DXGI_FORMAT_X16_TYPELESS_G8_UINT */: + case XBOX_DXGI_FORMAT_D16_UNORM_S8_UINT: + case XBOX_DXGI_FORMAT_R16_UNORM_X8_TYPELESS: + case XBOX_DXGI_FORMAT_X16_TYPELESS_G8_UINT: + case WIN10_DXGI_FORMAT_V408: return 24; case DXGI_FORMAT_R8G8_TYPELESS: @@ -374,6 +609,8 @@ size_t BitsPerPixel( DXGI_FORMAT fmt ) case DXGI_FORMAT_B5G5R5A1_UNORM: case DXGI_FORMAT_A8P8: case DXGI_FORMAT_B4G4R4A4_UNORM: + case WIN10_DXGI_FORMAT_P208: + case WIN10_DXGI_FORMAT_V208: return 16; case DXGI_FORMAT_NV12: @@ -390,6 +627,7 @@ size_t BitsPerPixel( DXGI_FORMAT fmt ) case DXGI_FORMAT_AI44: case DXGI_FORMAT_IA44: case DXGI_FORMAT_P8: + case XBOX_DXGI_FORMAT_R4G4_UNORM: return 8; case DXGI_FORMAT_R1_UNORM: @@ -489,6 +727,9 @@ size_t BitsPerColor( DXGI_FORMAT fmt ) case DXGI_FORMAT_Y416: case DXGI_FORMAT_P016: case DXGI_FORMAT_Y216: + case XBOX_DXGI_FORMAT_D16_UNORM_S8_UINT: + case XBOX_DXGI_FORMAT_R16_UNORM_X8_TYPELESS: + case XBOX_DXGI_FORMAT_X16_TYPELESS_G8_UINT: return 16; case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: @@ -504,6 +745,9 @@ size_t BitsPerColor( DXGI_FORMAT fmt ) case DXGI_FORMAT_Y410: case DXGI_FORMAT_P010: case DXGI_FORMAT_Y210: + case XBOX_DXGI_FORMAT_R10G10B10_7E3_A2_FLOAT: + case XBOX_DXGI_FORMAT_R10G10B10_6E4_A2_FLOAT: + case XBOX_DXGI_FORMAT_R10G10B10_SNORM_A2_UNORM: return 10; case DXGI_FORMAT_R8G8B8A8_TYPELESS: @@ -542,6 +786,9 @@ size_t BitsPerColor( DXGI_FORMAT fmt ) case DXGI_FORMAT_420_OPAQUE: case DXGI_FORMAT_YUY2: case DXGI_FORMAT_NV11: + case WIN10_DXGI_FORMAT_P208: + case WIN10_DXGI_FORMAT_V208: + case WIN10_DXGI_FORMAT_V408: return 8; case DXGI_FORMAT_BC7_TYPELESS: @@ -565,22 +812,12 @@ size_t BitsPerColor( DXGI_FORMAT fmt ) return 5; case DXGI_FORMAT_B4G4R4A4_UNORM: + case XBOX_DXGI_FORMAT_R4G4_UNORM: return 4; case DXGI_FORMAT_R1_UNORM: return 1; - case 116 /* DXGI_FORMAT_R10G10B10_7E3_A2_FLOAT */: - case 117 /* DXGI_FORMAT_R10G10B10_6E4_A2_FLOAT */: - // These are Xbox One platform specific types - return 10; - - case 118 /* DXGI_FORMAT_D16_UNORM_S8_UINT */: - case 119 /* DXGI_FORMAT_R16_UNORM_X8_TYPELESS */: - case 120 /* DXGI_FORMAT_X16_TYPELESS_G8_UINT */: - // These are Xbox One platform specific types - return 16; - case DXGI_FORMAT_AI44: case DXGI_FORMAT_IA44: case DXGI_FORMAT_P8: @@ -601,95 +838,220 @@ _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) ); - - if ( IsCompressed(fmt) ) + switch( static_cast(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( 1, (width + 3) / 4 ); - size_t nbh = std::max( 1, (height + 3) / 4 ); - rowPitch = nbw * bpb; + 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: + assert(IsCompressed(fmt)); + { + size_t nbw = std::max( 1, (width + 3) / 4 ); + size_t nbh = std::max( 1, (height + 3) / 4 ); + rowPitch = nbw * 8; - slicePitch = rowPitch * nbh; - } - else if ( IsPacked(fmt) ) - { - size_t bpe = ( fmt == DXGI_FORMAT_Y210 || fmt == DXGI_FORMAT_Y216 ) ? 8 : 4; - rowPitch = ( ( width + 1 ) >> 1 ) * bpe; + slicePitch = rowPitch * nbh; + } + 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: + assert(IsCompressed(fmt)); + { + size_t nbw = std::max( 1, (width + 3) / 4 ); + size_t nbh = std::max( 1, (height + 3) / 4 ); + rowPitch = nbw * 16; + + slicePitch = rowPitch * nbh; + } + break; + + case DXGI_FORMAT_R8G8_B8G8_UNORM: + case DXGI_FORMAT_G8R8_G8B8_UNORM: + case DXGI_FORMAT_YUY2: + assert(IsPacked(fmt)); + rowPitch = ( ( width + 1 ) >> 1 ) * 4; slicePitch = rowPitch * height; - } - else if ( fmt == DXGI_FORMAT_NV11 ) - { - rowPitch = ( ( width + 3 ) >> 2 ) * 4; + break; - // Direct3D makes this simplifying assumption, although it is larger than the 4:1:1 data - slicePitch = rowPitch * height * 2; - } - else if ( IsPlanar(fmt) ) - { - size_t bpe = ( fmt == DXGI_FORMAT_P010 || fmt == DXGI_FORMAT_P016 - || fmt == DXGI_FORMAT(118 /* DXGI_FORMAT_D16_UNORM_S8_UINT */) - || fmt == DXGI_FORMAT(119 /* DXGI_FORMAT_R16_UNORM_X8_TYPELESS */) - || fmt == DXGI_FORMAT(120 /* DXGI_FORMAT_X16_TYPELESS_G8_UINT */) ) ? 4 : 2; - rowPitch = ( ( width + 1 ) >> 1 ) * bpe; + case DXGI_FORMAT_Y210: + case DXGI_FORMAT_Y216: + assert(IsPacked(fmt)); + rowPitch = ( ( width + 1 ) >> 1 ) * 8; + slicePitch = rowPitch * height; + break; + case DXGI_FORMAT_NV12: + case DXGI_FORMAT_420_OPAQUE: + assert(IsPlanar(fmt)); + rowPitch = ( ( width + 1 ) >> 1 ) * 2; slicePitch = rowPitch * ( height + ( ( height + 1 ) >> 1 ) ); + break; + + case DXGI_FORMAT_P010: + case DXGI_FORMAT_P016: + case XBOX_DXGI_FORMAT_D16_UNORM_S8_UINT: + case XBOX_DXGI_FORMAT_R16_UNORM_X8_TYPELESS: + case XBOX_DXGI_FORMAT_X16_TYPELESS_G8_UINT: + assert(IsPlanar(fmt)); + rowPitch = ( ( width + 1 ) >> 1 ) * 4; + slicePitch = rowPitch * ( height + ( ( height + 1 ) >> 1 ) ); + break; + + case DXGI_FORMAT_NV11: + assert(IsPlanar(fmt)); + rowPitch = ( ( width + 3 ) >> 2 ) * 4; + slicePitch = rowPitch * height * 2; + break; + + case WIN10_DXGI_FORMAT_P208: + assert(IsPlanar(fmt)); + rowPitch = ( ( width + 1 ) >> 1 ) * 2; + slicePitch = rowPitch * height * 2; + break; + + case WIN10_DXGI_FORMAT_V208: + assert(IsPlanar(fmt)); + rowPitch = width; + slicePitch = rowPitch * ( height + ( ( ( height + 1 ) >> 1 ) * 2 ) ); + break; + + case WIN10_DXGI_FORMAT_V408: + assert(IsPlanar(fmt)); + rowPitch = width; + slicePitch = rowPitch * ( height + ( ( height >> 1 ) * 4 ) ); + break; + + default: + assert( IsValid(fmt) ); + assert( !IsCompressed(fmt) && !IsPacked(fmt) && !IsPlanar(fmt) ); + { + + 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 | CP_FLAGS_PARAGRAPH | CP_FLAGS_YMM | CP_FLAGS_ZMM | CP_FLAGS_PAGE4K ) ) + { + if ( flags & CP_FLAGS_PAGE4K ) + { + rowPitch = ( ( width * bpp + 32767 ) / 32768 ) * 4096; + slicePitch = rowPitch * height; + } + else if ( flags & CP_FLAGS_ZMM ) + { + rowPitch = ( ( width * bpp + 511 ) / 512 ) * 64; + slicePitch = rowPitch * height; + } + else if ( flags & CP_FLAGS_YMM ) + { + rowPitch = ( ( width * bpp + 255 ) / 256) * 32; + slicePitch = rowPitch * height; + } + else if ( flags & CP_FLAGS_PARAGRAPH ) + { + rowPitch = ( ( width * bpp + 127 ) / 128 ) * 16; + slicePitch = rowPitch * height; + } + else // DWORD alignment + { + // 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 + { + // Default byte alignment + rowPitch = ( width * bpp + 7 ) / 8; + slicePitch = rowPitch * height; + } + } + break; } - else +} + + +//------------------------------------------------------------------------------------- +_Use_decl_annotations_ +size_t ComputeScanlines(DXGI_FORMAT fmt, size_t height) +{ + switch ( static_cast(fmt) ) { - size_t bpp; + 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_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_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: + assert(IsCompressed(fmt)); + return std::max( 1, (height + 3) / 4 ); - 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 ); + case DXGI_FORMAT_NV11: + case WIN10_DXGI_FORMAT_P208: + assert(IsPlanar(fmt)); + return height * 2; - if ( flags & ( CP_FLAGS_LEGACY_DWORD | CP_FLAGS_PARAGRAPH | CP_FLAGS_YMM | CP_FLAGS_ZMM | CP_FLAGS_PAGE4K ) ) - { - if ( flags & CP_FLAGS_PAGE4K ) - { - rowPitch = ( ( width * bpp + 32767 ) / 32768 ) * 4096; - slicePitch = rowPitch * height; - } - else if ( flags & CP_FLAGS_ZMM ) - { - rowPitch = ( ( width * bpp + 511 ) / 512 ) * 64; - slicePitch = rowPitch * height; - } - else if ( flags & CP_FLAGS_YMM ) - { - rowPitch = ( ( width * bpp + 255 ) / 256) * 32; - slicePitch = rowPitch * height; - } - else if ( flags & CP_FLAGS_PARAGRAPH ) - { - rowPitch = ( ( width * bpp + 127 ) / 128 ) * 16; - slicePitch = rowPitch * height; - } - else // DWORD alignment - { - // 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 - { - // Default byte alignment - rowPitch = ( width * bpp + 7 ) / 8; - slicePitch = rowPitch * height; - } + case WIN10_DXGI_FORMAT_V208: + assert(IsPlanar(fmt)); + return height + ( ( (height + 1) >> 1 ) * 2 ); + + case WIN10_DXGI_FORMAT_V408: + assert(IsPlanar(fmt)); + return height + ( (height >> 1) * 4 ); + + case DXGI_FORMAT_NV12: + case DXGI_FORMAT_P010: + case DXGI_FORMAT_P016: + case DXGI_FORMAT_420_OPAQUE: + case XBOX_DXGI_FORMAT_D16_UNORM_S8_UINT: + case XBOX_DXGI_FORMAT_R16_UNORM_X8_TYPELESS: + case XBOX_DXGI_FORMAT_X16_TYPELESS_G8_UINT: + assert(IsPlanar(fmt)); + return height + ( ( height + 1 ) >> 1 ); + + default: + assert( IsValid(fmt) ); + assert( !IsCompressed(fmt) && !IsPlanar(fmt) ); + return height; } } @@ -735,7 +1097,7 @@ DXGI_FORMAT MakeSRGB( DXGI_FORMAT fmt ) _Use_decl_annotations_ DXGI_FORMAT MakeTypeless( DXGI_FORMAT fmt ) { - switch( fmt ) + switch( static_cast( fmt ) ) { case DXGI_FORMAT_R32G32B32A32_FLOAT: case DXGI_FORMAT_R32G32B32A32_UINT: @@ -761,6 +1123,9 @@ DXGI_FORMAT MakeTypeless( DXGI_FORMAT fmt ) case DXGI_FORMAT_R10G10B10A2_UNORM: case DXGI_FORMAT_R10G10B10A2_UINT: + case XBOX_DXGI_FORMAT_R10G10B10_7E3_A2_FLOAT: + case XBOX_DXGI_FORMAT_R10G10B10_6E4_A2_FLOAT: + case XBOX_DXGI_FORMAT_R10G10B10_SNORM_A2_UNORM: return DXGI_FORMAT_R10G10B10A2_TYPELESS; case DXGI_FORMAT_R8G8B8A8_UNORM: @@ -801,6 +1166,7 @@ DXGI_FORMAT MakeTypeless( DXGI_FORMAT fmt ) case DXGI_FORMAT_R8_UINT: case DXGI_FORMAT_R8_SNORM: case DXGI_FORMAT_R8_SINT: + case XBOX_DXGI_FORMAT_R4G4_UNORM: return DXGI_FORMAT_R8_TYPELESS; case DXGI_FORMAT_BC1_UNORM: