DirectXTex: Support for Direct3D 11 video and Xbox One extended formats

- New APIs: IsPlanar, IsPalettized, IsDepthStencil, ConvertToSinglePlane
This commit is contained in:
walbourn_cp 2014-02-14 13:33:01 -08:00
parent b67a8ef792
commit 5336f904da
17 changed files with 1491 additions and 129 deletions

View File

@ -100,6 +100,9 @@ extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_R8G8_B8G8 =
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_G8R8_G8B8 =
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('G','R','G','B'), 0, 0, 0, 0, 0 };
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_YUY2 =
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('Y','U','Y','2'), 0, 0, 0, 0, 0 };
extern __declspec(selectany) const DDS_PIXELFORMAT DDSPF_A8R8G8B8 =
{ sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 };

View File

@ -37,7 +37,7 @@
#include <ocidl.h>
#define DIRECTX_TEX_VERSION 120
#define DIRECTX_TEX_VERSION 130
namespace DirectX
{
@ -48,6 +48,9 @@ namespace DirectX
bool IsCompressed( _In_ DXGI_FORMAT fmt );
bool IsPacked( _In_ DXGI_FORMAT fmt );
bool IsVideo( _In_ DXGI_FORMAT fmt );
bool IsPlanar( _In_ DXGI_FORMAT fmt );
bool IsPalettized( _In_ DXGI_FORMAT fmt );
bool IsDepthStencil(_In_ DXGI_FORMAT fmt );
bool IsSRGB( _In_ DXGI_FORMAT fmt );
bool IsTypeless( _In_ DXGI_FORMAT fmt, _In_ bool partialTypeless = true );
@ -437,6 +440,11 @@ namespace DirectX
_In_ DXGI_FORMAT format, _In_ DWORD filter, _In_ float threshold, _Out_ ScratchImage& result );
// Convert the image to a new format
HRESULT ConvertToSinglePlane( _In_ const Image& srcImage, _Out_ ScratchImage& image );
HRESULT ConvertToSinglePlane( _In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata,
_Out_ ScratchImage& image );
// Converts the image from a planar format to an equivalent non-planar format
HRESULT GenerateMipMaps( _In_ const Image& baseImage, _In_ DWORD filter, _In_ size_t levels,
_Inout_ ScratchImage& mipChain, _In_ bool allow1D = false );
HRESULT GenerateMipMaps( _In_reads_(nimages) const Image* srcImages, _In_ size_t nimages, _In_ const TexMetadata& metadata,

View File

@ -24,7 +24,7 @@
_Use_decl_annotations_
inline bool IsValid( DXGI_FORMAT fmt )
{
return ( static_cast<size_t>(fmt) >= 1 && static_cast<size_t>(fmt) <= 115 );
return ( static_cast<size_t>(fmt) >= 1 && static_cast<size_t>(fmt) <= 120 );
}
_Use_decl_annotations_
@ -63,9 +63,58 @@ inline bool IsCompressed( DXGI_FORMAT fmt )
_Use_decl_annotations_
inline bool IsPacked( DXGI_FORMAT fmt )
{
return ( (fmt == DXGI_FORMAT_R8G8_B8G8_UNORM) || (fmt == DXGI_FORMAT_G8R8_G8B8_UNORM) );
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 IsPlanar( DXGI_FORMAT fmt )
{
switch ( static_cast<int>(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 IsPalettized( DXGI_FORMAT fmt )
{
switch( fmt )
{
case DXGI_FORMAT_AI44:
case DXGI_FORMAT_IA44:
case DXGI_FORMAT_P8:
case DXGI_FORMAT_A8P8:
return true;
default:
return false;
}
}
_Use_decl_annotations_
inline bool IsVideo( DXGI_FORMAT fmt )
@ -83,7 +132,6 @@ inline bool IsVideo( DXGI_FORMAT fmt )
case DXGI_FORMAT_Y216:
case DXGI_FORMAT_NV11:
// These video formats can be used with the 3D pipeline through special view mappings
return true;
case DXGI_FORMAT_420_OPAQUE:
case DXGI_FORMAT_AI44:
@ -98,6 +146,29 @@ inline bool IsVideo( DXGI_FORMAT fmt )
}
}
_Use_decl_annotations_
inline bool IsDepthStencil( DXGI_FORMAT fmt )
{
switch( static_cast<int>(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 IsSRGB( DXGI_FORMAT fmt )
{
@ -120,7 +191,7 @@ inline bool IsSRGB( DXGI_FORMAT fmt )
_Use_decl_annotations_
inline bool IsTypeless( DXGI_FORMAT fmt, bool partialTypeless )
{
switch( fmt )
switch( static_cast<int>(fmt) )
{
case DXGI_FORMAT_R32G32B32A32_TYPELESS:
case DXGI_FORMAT_R32G32B32_TYPELESS:
@ -152,6 +223,11 @@ inline bool IsTypeless( DXGI_FORMAT fmt, bool partialTypeless )
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;
}
@ -160,7 +236,7 @@ inline bool IsTypeless( DXGI_FORMAT fmt, bool partialTypeless )
_Use_decl_annotations_
inline bool HasAlpha( DXGI_FORMAT fmt )
{
switch( fmt )
switch( static_cast<int>(fmt) )
{
case DXGI_FORMAT_R32G32B32A32_TYPELESS:
case DXGI_FORMAT_R32G32B32A32_FLOAT:
@ -199,9 +275,20 @@ inline bool HasAlpha( DXGI_FORMAT fmt )
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;
}
@ -210,32 +297,21 @@ inline bool HasAlpha( DXGI_FORMAT fmt )
_Use_decl_annotations_
inline size_t ComputeScanlines( DXGI_FORMAT fmt, size_t height )
{
switch ( fmt )
if ( IsCompressed(fmt) )
{
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:
return std::max<size_t>( 1, (height + 3) / 4 );
default:
}
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;
}
}

View File

@ -147,6 +147,7 @@ static HRESULT _CompressBC( _In_ const Image& image, _In_ const Image& result, _
{
for( size_t s = pw; s < 4; ++s )
{
#pragma prefast(suppress: 26000, "PREFAST false positive")
temp[ (t << 2) | s ] = temp[ (t << 2) | uSrc[s] ];
}
}
@ -158,6 +159,7 @@ static HRESULT _CompressBC( _In_ const Image& image, _In_ const Image& result, _
{
for( size_t s = 0; s < 4; ++s )
{
#pragma prefast(suppress: 26000, "PREFAST false positive")
temp[ (t << 2) | s ] = temp[ (uSrc[t] << 2) | s ];
}
}
@ -561,9 +563,13 @@ bool _IsAlphaAllOpaqueBC( _In_ const Image& cImage )
_Use_decl_annotations_
HRESULT Compress( const Image& srcImage, DXGI_FORMAT format, DWORD compress, float alphaRef, ScratchImage& image )
{
if ( IsCompressed(srcImage.format) || !IsCompressed(format) || IsTypeless(format) )
if ( IsCompressed(srcImage.format) || !IsCompressed(format) )
return E_INVALIDARG;
if ( IsTypeless(format)
|| IsTypeless(srcImage.format) || IsPlanar(srcImage.format) || IsPalettized(srcImage.format) )
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
// Create compressed image
HRESULT hr = image.Initialize2D( format, srcImage.width, srcImage.height, 1, 1 );
if ( FAILED(hr) )
@ -603,9 +609,13 @@ HRESULT Compress( const Image* srcImages, size_t nimages, const TexMetadata& met
if ( !srcImages || !nimages )
return E_INVALIDARG;
if ( !IsCompressed(format) || IsTypeless(format) )
if ( IsCompressed(metadata.format) || !IsCompressed(format) )
return E_INVALIDARG;
if ( IsTypeless(format)
|| IsTypeless(metadata.format) || IsPlanar(metadata.format) || IsPalettized(metadata.format) )
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
cImages.Release();
TexMetadata mdata2 = metadata;
@ -676,7 +686,7 @@ HRESULT Compress( const Image* srcImages, size_t nimages, const TexMetadata& met
_Use_decl_annotations_
HRESULT Decompress( const Image& cImage, DXGI_FORMAT format, ScratchImage& image )
{
if ( IsCompressed(format) || IsTypeless(format) )
if ( !IsCompressed(cImage.format) || IsCompressed(format) )
return E_INVALIDARG;
if ( format == DXGI_FORMAT_UNKNOWN )
@ -689,8 +699,14 @@ HRESULT Decompress( const Image& cImage, DXGI_FORMAT format, ScratchImage& image
return E_INVALIDARG;
}
}
else if ( !IsCompressed(cImage.format) || !IsValid(format) )
return E_INVALIDARG;
else
{
if ( !IsValid(format) )
return E_INVALIDARG;
if ( IsTypeless(format) || IsPlanar(format) || IsPalettized(format) )
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
}
// Create decompressed image
HRESULT hr = image.Initialize2D( format, cImage.width, cImage.height, 1, 1 );
@ -719,7 +735,7 @@ HRESULT Decompress( const Image* cImages, size_t nimages, const TexMetadata& met
if ( !cImages || !nimages )
return E_INVALIDARG;
if ( IsCompressed(format) || IsTypeless(format) )
if ( !IsCompressed(metadata.format) || IsCompressed(format) )
return E_INVALIDARG;
if ( format == DXGI_FORMAT_UNKNOWN )
@ -732,8 +748,14 @@ HRESULT Decompress( const Image* cImages, size_t nimages, const TexMetadata& met
return E_FAIL;
}
}
else if ( !IsValid(format) )
return E_INVALIDARG;
else
{
if ( !IsValid(format) )
return E_INVALIDARG;
if ( IsTypeless(format) || IsPlanar(format) || IsPalettized(format) )
HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
}
images.Release();

View File

@ -200,9 +200,13 @@ inline static HRESULT _GPUCompress( _In_ GPUCompressBC* gpubc, _In_ const Image&
_Use_decl_annotations_
HRESULT Compress( ID3D11Device* pDevice, const Image& srcImage, DXGI_FORMAT format, DWORD compress, ScratchImage& image )
{
if ( !pDevice || IsCompressed(srcImage.format) || !IsCompressed(format) || IsTypeless(format) )
if ( !pDevice || IsCompressed(srcImage.format) || !IsCompressed(format) )
return E_INVALIDARG;
if ( IsTypeless(format)
|| IsTypeless(srcImage.format) || IsPlanar(srcImage.format) || IsPalettized(srcImage.format) )
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
// Setup GPU compressor
std::unique_ptr<GPUCompressBC> gpubc( new (std::nothrow) GPUCompressBC );
if ( !gpubc )
@ -242,9 +246,13 @@ HRESULT Compress( ID3D11Device* pDevice, const Image* srcImages, size_t nimages,
if ( !pDevice || !srcImages || !nimages )
return E_INVALIDARG;
if ( !IsCompressed(format) || IsTypeless(format) )
if ( IsCompressed(metadata.format) || !IsCompressed(format) )
return E_INVALIDARG;
if ( IsTypeless(format)
|| IsTypeless(metadata.format) || IsPlanar(metadata.format) || IsPalettized(metadata.format) )
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
cImages.Release();
// Setup GPU compressor

File diff suppressed because it is too large Load Diff

View File

@ -55,6 +55,11 @@ static HRESULT _Capture( _In_ ID3D11DeviceContext* pContext, _In_ ID3D11Resource
}
size_t lines = ComputeScanlines( metadata.format, height );
if ( !lines )
{
pContext->Unmap( pSource, dindex );
return E_UNEXPECTED;
}
for( size_t slice = 0; slice < depth; ++slice )
{
@ -124,6 +129,11 @@ static HRESULT _Capture( _In_ ID3D11DeviceContext* pContext, _In_ ID3D11Resource
}
size_t lines = ComputeScanlines( metadata.format, height );
if ( !lines )
{
pContext->Unmap( pSource, dindex );
return E_UNEXPECTED;
}
auto sptr = reinterpret_cast<const uint8_t*>( mapped.pData );
uint8_t* dptr = img->pixels;
@ -168,9 +178,6 @@ bool IsSupportedTexture( ID3D11Device* pDevice, const TexMetadata& metadata )
if ( !IsValid( fmt ) )
return false;
if ( IsVideo(fmt) )
return false;
switch( fmt )
{
case DXGI_FORMAT_BC4_TYPELESS:

View File

@ -123,6 +123,9 @@ const LegacyDDS g_LegacyDDSMap[] =
| CONV_FLAGS_4444, { sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 16, 0x0f00, 0x00f0, 0x000f, 0x0000 } }, // D3DFMT_X4R4G4B4 (uses DXGI 1.2 format)
{ DXGI_FORMAT_B4G4R4A4_UNORM, CONV_FLAGS_EXPAND
| CONV_FLAGS_44, { sizeof(DDS_PIXELFORMAT), DDS_LUMINANCE, 0, 8, 0x0f, 0x00, 0x00, 0xf0 } }, // D3DFMT_A4L4 (uses DXGI 1.2 format)
{ DXGI_FORMAT_YUY2, CONV_FLAGS_NONE, DDSPF_YUY2 }, // D3DFMT_YUY2 (uses DXGI 1.2 format)
{ DXGI_FORMAT_YUY2, CONV_FLAGS_SWIZZLE, { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('U','Y','V','Y'), 0, 0, 0, 0, 0 } }, // D3DFMT_UYVY (uses DXGI 1.2 format)
};
// Note that many common DDS reader/writers (including D3DX) swap the
@ -134,8 +137,6 @@ const LegacyDDS g_LegacyDDSMap[] =
// We do not support the following legacy Direct3D 9 formats:
// BumpDuDv D3DFMT_V8U8, D3DFMT_Q8W8V8U8, D3DFMT_V16U16, D3DFMT_A2W10V10U10
// BumpLuminance D3DFMT_L6V5U5, D3DFMT_X8L8V8U8
// FourCC "UYVY" D3DFMT_UYVY
// FourCC "YUY2" D3DFMT_YUY2
// FourCC 117 D3DFMT_CxV8U8
// ZBuffer D3DFMT_D16_LOCKABLE
// FourCC 82 D3DFMT_D32F_LOCKABLE
@ -248,9 +249,9 @@ static HRESULT _DecodeDDSHeader( _In_reads_bytes_(size) LPCVOID pSource, size_t
}
metadata.format = d3d10ext->dxgiFormat;
if ( !IsValid( metadata.format ) )
if ( !IsValid( metadata.format ) || IsPalettized( metadata.format ) )
{
return HRESULT_FROM_WIN32( ERROR_INVALID_DATA );
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
}
static_assert( TEX_MISC_TEXTURECUBE == DDS_RESOURCE_MISC_TEXTURECUBE, "DDS header mismatch");
@ -440,7 +441,11 @@ _Use_decl_annotations_
HRESULT _EncodeDDSHeader( const TexMetadata& metadata, DWORD flags,
LPVOID pDestination, size_t maxsize, size_t& required )
{
assert( IsValid( metadata.format ) && !IsVideo( metadata.format ) );
if ( !IsValid( metadata.format ) )
return E_INVALIDARG;
if ( IsPalettized( metadata.format ) )
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
if ( metadata.arraySize > 1 )
{
@ -480,7 +485,8 @@ HRESULT _EncodeDDSHeader( const TexMetadata& metadata, DWORD flags,
case DXGI_FORMAT_B5G5R5A1_UNORM: memcpy_s( &ddpf, sizeof(ddpf), &DDSPF_A1R5G5B5, sizeof(DDS_PIXELFORMAT) ); break;
case DXGI_FORMAT_B8G8R8A8_UNORM: memcpy_s( &ddpf, sizeof(ddpf), &DDSPF_A8R8G8B8, sizeof(DDS_PIXELFORMAT) ); break; // DXGI 1.1
case DXGI_FORMAT_B8G8R8X8_UNORM: memcpy_s( &ddpf, sizeof(ddpf), &DDSPF_X8R8G8B8, sizeof(DDS_PIXELFORMAT) ); break; // DXGI 1.1
case DXGI_FORMAT_B4G4R4A4_UNORM: memcpy_s( &ddpf, sizeof(ddpf), &DDSPF_A4R4G4B4, sizeof(DDS_PIXELFORMAT) ); break;
case DXGI_FORMAT_B4G4R4A4_UNORM: memcpy_s( &ddpf, sizeof(ddpf), &DDSPF_A4R4G4B4, sizeof(DDS_PIXELFORMAT) ); break; // DXGI 1.2
case DXGI_FORMAT_YUY2: memcpy_s( &ddpf, sizeof(ddpf), &DDSPF_YUY2, sizeof(DDS_PIXELFORMAT) ); break; // DXGI 1.2
// Legacy D3DX formats using D3DFMT enum value as FourCC
case DXGI_FORMAT_R32G32B32A32_FLOAT:
@ -723,7 +729,7 @@ static bool _LegacyExpandScanline( _Out_writes_bytes_(outSize) LPVOID pDestinati
{
assert( pDestination && outSize > 0 );
assert( pSource && inSize > 0 );
assert( IsValid(outFormat) && !IsVideo(outFormat) );
assert( IsValid(outFormat) && !IsPlanar(outFormat) && !IsPalettized(outFormat) );
switch( inFormat )
{
@ -1101,6 +1107,20 @@ static HRESULT _CopyImage( _In_reads_bytes_(size) const void* pPixels, _In_ size
size_t csize = std::min<size_t>( images[ index ].slicePitch, timages[ index ].slicePitch );
memcpy_s( pDest, images[ index ].slicePitch, pSrc, csize );
}
else if ( IsPlanar( metadata.format ) )
{
size_t count = ComputeScanlines( metadata.format, images[ index ].height );
if ( !count )
return E_UNEXPECTED;
size_t csize = std::min<size_t>( dpitch, spitch );
for( size_t h = 0; h < count; ++h )
{
memcpy_s( pDest, dpitch, pSrc, csize );
pSrc += spitch;
pDest += dpitch;
}
}
else
{
for( size_t h = 0; h < images[ index ].height; ++h )
@ -1175,6 +1195,11 @@ static HRESULT _CopyImage( _In_reads_bytes_(size) const void* pPixels, _In_ size
size_t csize = std::min<size_t>( images[ index ].slicePitch, timages[ index ].slicePitch );
memcpy_s( pDest, images[ index ].slicePitch, pSrc, csize );
}
else if ( IsPlanar( metadata.format ) )
{
// Direct3D does not support any planar formats for Texture3D
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
}
else
{
for( size_t h = 0; h < images[ index ].height; ++h )
@ -1237,6 +1262,9 @@ static HRESULT _CopyImageInPlace( DWORD convFlags, _In_ const ScratchImage& imag
const TexMetadata& metadata = image.GetMetadata();
if ( IsPlanar( metadata.format ) )
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
DWORD tflags = (convFlags & CONV_FLAGS_NOALPHA) ? TEXP_SCANLINE_SETALPHA : 0;
if ( convFlags & CONV_FLAGS_SWIZZLE )
tflags |= TEXP_SCANLINE_LEGACY;

View File

@ -256,9 +256,12 @@ ScratchImage& ScratchImage::operator= (ScratchImage&& moveFrom)
_Use_decl_annotations_
HRESULT ScratchImage::Initialize( const TexMetadata& mdata )
{
if ( !IsValid(mdata.format) || IsVideo(mdata.format) )
if ( !IsValid(mdata.format) )
return E_INVALIDARG;
if ( IsPalettized(mdata.format) )
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
size_t mipLevels = mdata.mipLevels;
switch( mdata.dimension )
@ -267,6 +270,9 @@ HRESULT ScratchImage::Initialize( const TexMetadata& mdata )
if ( !mdata.width || mdata.height != 1 || mdata.depth != 1 || !mdata.arraySize )
return E_INVALIDARG;
if ( IsVideo(mdata.format) )
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
if ( !_CalculateMipLevels(mdata.width,1,mipLevels) )
return E_INVALIDARG;
break;
@ -279,6 +285,9 @@ HRESULT ScratchImage::Initialize( const TexMetadata& mdata )
{
if ( (mdata.arraySize % 6) != 0 )
return E_INVALIDARG;
if ( IsVideo(mdata.format) )
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
}
if ( !_CalculateMipLevels(mdata.width,mdata.height,mipLevels) )
@ -288,6 +297,9 @@ HRESULT ScratchImage::Initialize( const TexMetadata& mdata )
case TEX_DIMENSION_TEXTURE3D:
if ( !mdata.width || !mdata.height || !mdata.depth || mdata.arraySize != 1 )
return E_INVALIDARG;
if ( IsVideo(mdata.format) || IsPlanar(mdata.format) || IsDepthStencil(mdata.format) )
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
if ( !_CalculateMipLevels3D(mdata.width,mdata.height,mdata.depth,mipLevels) )
return E_INVALIDARG;
@ -338,9 +350,12 @@ HRESULT ScratchImage::Initialize( const TexMetadata& mdata )
_Use_decl_annotations_
HRESULT ScratchImage::Initialize1D( DXGI_FORMAT fmt, size_t length, size_t arraySize, size_t mipLevels )
{
if ( !IsValid(fmt) || IsVideo(fmt) || !length || !arraySize )
if ( !length || !arraySize )
return E_INVALIDARG;
if ( IsVideo(fmt) )
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
// 1D is a special case of the 2D case
HRESULT hr = Initialize2D( fmt, length, 1, arraySize, mipLevels );
if ( FAILED(hr) )
@ -354,9 +369,12 @@ HRESULT ScratchImage::Initialize1D( DXGI_FORMAT fmt, size_t length, size_t array
_Use_decl_annotations_
HRESULT ScratchImage::Initialize2D( DXGI_FORMAT fmt, size_t width, size_t height, size_t arraySize, size_t mipLevels )
{
if ( !IsValid(fmt) || IsVideo(fmt) || !width || !height || !arraySize )
if ( !IsValid(fmt) || !width || !height || !arraySize )
return E_INVALIDARG;
if ( IsPalettized(fmt) )
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
if ( !_CalculateMipLevels(width,height,mipLevels) )
return E_INVALIDARG;
@ -401,9 +419,12 @@ HRESULT ScratchImage::Initialize2D( DXGI_FORMAT fmt, size_t width, size_t height
_Use_decl_annotations_
HRESULT ScratchImage::Initialize3D( DXGI_FORMAT fmt, size_t width, size_t height, size_t depth, size_t mipLevels )
{
if ( !IsValid(fmt) || IsVideo(fmt) || !width || !height || !depth )
if ( !IsValid(fmt) || !width || !height || !depth )
return E_INVALIDARG;
if ( IsVideo(fmt) || IsPlanar(fmt) || IsDepthStencil(fmt) )
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
if ( !_CalculateMipLevels3D(width,height,depth,mipLevels) )
return E_INVALIDARG;
@ -451,8 +472,11 @@ HRESULT ScratchImage::Initialize3D( DXGI_FORMAT fmt, size_t width, size_t height
_Use_decl_annotations_
HRESULT ScratchImage::InitializeCube( DXGI_FORMAT fmt, size_t width, size_t height, size_t nCubes, size_t mipLevels )
{
if ( !IsValid(fmt) || IsVideo(fmt) || !width || !height || !nCubes )
if ( !width || !height || !nCubes )
return E_INVALIDARG;
if ( IsVideo(fmt) )
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
// A DirectX11 cubemap is just a 2D texture array that is a multiple of 6 for each cube
HRESULT hr = Initialize2D( fmt, width, height, nCubes * 6, mipLevels );
@ -474,6 +498,10 @@ HRESULT ScratchImage::InitializeFromImage( const Image& srcImage, bool allow1D )
if ( FAILED(hr) )
return hr;
size_t rowCount = ComputeScanlines( srcImage.format, srcImage.height );
if ( !rowCount )
return E_UNEXPECTED;
const uint8_t* sptr = reinterpret_cast<const uint8_t*>( srcImage.pixels );
if ( !sptr )
return E_POINTER;
@ -482,11 +510,16 @@ HRESULT ScratchImage::InitializeFromImage( const Image& srcImage, bool allow1D )
if ( !dptr )
return E_POINTER;
for( size_t y = 0; y < srcImage.height; ++y )
size_t spitch = srcImage.rowPitch;
size_t dpitch = _image[0].rowPitch;
size_t size = std::min<size_t>( dpitch, spitch );
for( size_t y = 0; y < rowCount; ++y )
{
_CopyScanline( dptr, _image[0].rowPitch, sptr, srcImage.rowPitch, srcImage.format, TEXP_SCANLINE_NONE );
sptr += srcImage.rowPitch;
dptr += _image[0].rowPitch;
memcpy_s( dptr, dpitch, sptr, size );
sptr += spitch;
dptr += dpitch;
}
return S_OK;
@ -521,6 +554,10 @@ HRESULT ScratchImage::InitializeArrayFromImages( const Image* images, size_t nIm
if ( FAILED(hr) )
return hr;
size_t rowCount = ComputeScanlines( format, height );
if ( !rowCount )
return E_UNEXPECTED;
for( size_t index=0; index < nImages; ++index )
{
auto sptr = reinterpret_cast<const uint8_t*>( images[index].pixels );
@ -532,11 +569,16 @@ HRESULT ScratchImage::InitializeArrayFromImages( const Image* images, size_t nIm
if ( !dptr )
return E_POINTER;
for( size_t y = 0; y < height; ++y )
size_t spitch = images[index].rowPitch;
size_t dpitch = _image[index].rowPitch;
size_t size = std::min<size_t>( dpitch, spitch );
for( size_t y = 0; y < rowCount; ++y )
{
_CopyScanline( dptr, _image[index].rowPitch, sptr, images[index].rowPitch, format, TEXP_SCANLINE_NONE );
sptr += images[index].rowPitch;
dptr += _image[index].rowPitch;
memcpy_s( dptr, dpitch, sptr, size );
sptr += spitch;
dptr += dpitch;
}
}
@ -553,6 +595,9 @@ HRESULT ScratchImage::InitializeCubeFromImages( const Image* images, size_t nIma
if ( ( nImages % 6 ) != 0 )
return E_INVALIDARG;
if ( IsVideo(images[0].format) || IsPalettized(images[0].format) )
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
HRESULT hr = InitializeArrayFromImages( images, nImages, false );
if ( FAILED(hr) )
return hr;
@ -588,6 +633,10 @@ HRESULT ScratchImage::Initialize3DFromImages( const Image* images, size_t depth
if ( FAILED(hr) )
return hr;
size_t rowCount = ComputeScanlines( format, height );
if ( !rowCount )
return E_UNEXPECTED;
for( size_t slice=0; slice < depth; ++slice )
{
auto sptr = reinterpret_cast<const uint8_t*>( images[slice].pixels );
@ -599,11 +648,16 @@ HRESULT ScratchImage::Initialize3DFromImages( const Image* images, size_t depth
if ( !dptr )
return E_POINTER;
for( size_t y = 0; y < height; ++y )
size_t spitch = images[slice].rowPitch;
size_t dpitch = _image[slice].rowPitch;
size_t size = std::min<size_t>( dpitch, spitch );
for( size_t y = 0; y < rowCount; ++y )
{
_CopyScanline( dptr, _image[slice].rowPitch, sptr, images[slice].rowPitch, format, TEXP_SCANLINE_NONE );
sptr += images[slice].rowPitch;
dptr += _image[slice].rowPitch;
memcpy_s( dptr, dpitch, sptr, size );
sptr += spitch;
dptr += dpitch;
}
}
@ -636,12 +690,13 @@ bool ScratchImage::OverrideFormat( DXGI_FORMAT f )
if ( !_image )
return false;
if ( !IsValid( f ) || IsVideo( f ) )
if ( !IsValid( f ) || IsPlanar( f ) || IsPalettized( f ) )
return false;
if ( ( BitsPerPixel( f ) != BitsPerPixel( _metadata.format ) )
|| ( IsCompressed( f ) != IsCompressed( _metadata.format ) )
|| ( IsPacked( f ) != IsPacked( _metadata.format ) ) )
|| ( IsPacked( f ) != IsPacked( _metadata.format ) )
|| ( IsVideo( f ) != IsVideo( _metadata.format ) ) )
{
// Can't change the effective pitch of the format this way
return false;

View File

@ -2489,7 +2489,7 @@ HRESULT GenerateMipMaps( const Image& baseImage, DWORD filter, size_t levels, Sc
if ( !_CalculateMipLevels(baseImage.width, baseImage.height, levels) )
return E_INVALIDARG;
if ( IsCompressed( baseImage.format ) || IsVideo( baseImage.format ) )
if ( IsCompressed(baseImage.format) || IsTypeless(baseImage.format) || IsPlanar(baseImage.format) || IsPalettized(baseImage.format) )
{
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
}
@ -2515,9 +2515,9 @@ HRESULT GenerateMipMaps( const Image& baseImage, DWORD filter, size_t levels, Sc
if ( _DXGIToWIC( baseImage.format, pfGUID, true ) )
{
// Case 1: Base image format is supported by Windows Imaging Component
HRESULT hr = (baseImage.height > 1 || !allow1D)
? mipChain.Initialize2D( baseImage.format, baseImage.width, baseImage.height, 1, levels )
: mipChain.Initialize1D( baseImage.format, baseImage.width, 1, levels );
hr = (baseImage.height > 1 || !allow1D)
? mipChain.Initialize2D( baseImage.format, baseImage.width, baseImage.height, 1, levels )
: mipChain.Initialize1D( baseImage.format, baseImage.width, 1, levels );
if ( FAILED(hr) )
return hr;
@ -2528,7 +2528,7 @@ HRESULT GenerateMipMaps( const Image& baseImage, DWORD filter, size_t levels, Sc
// Case 2: Base image format is not supported by WIC, so we have to convert, generate, and convert back
assert( baseImage.format != DXGI_FORMAT_R32G32B32A32_FLOAT );
ScratchImage temp;
HRESULT hr = _ConvertToR32G32B32A32( baseImage, temp );
hr = _ConvertToR32G32B32A32( baseImage, temp );
if ( FAILED(hr) )
return hr;
@ -2645,7 +2645,7 @@ HRESULT GenerateMipMaps( const Image* srcImages, size_t nimages, const TexMetada
return E_INVALIDARG;
if ( metadata.IsVolumemap()
|| IsCompressed( metadata.format ) || IsVideo( metadata.format ) )
|| IsCompressed(metadata.format) || IsTypeless(metadata.format) || IsPlanar(metadata.format) || IsPalettized(metadata.format) )
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
if ( !_CalculateMipLevels(metadata.width, metadata.height, levels) )
@ -2697,7 +2697,7 @@ HRESULT GenerateMipMaps( const Image* srcImages, size_t nimages, const TexMetada
// Case 1: Base image format is supported by Windows Imaging Component
TexMetadata mdata2 = metadata;
mdata2.mipLevels = levels;
HRESULT hr = mipChain.Initialize( mdata2 );
hr = mipChain.Initialize( mdata2 );
if ( FAILED(hr) )
return hr;
@ -2722,7 +2722,7 @@ HRESULT GenerateMipMaps( const Image* srcImages, size_t nimages, const TexMetada
mdata2.mipLevels = levels;
mdata2.format = DXGI_FORMAT_R32G32B32A32_FLOAT;
ScratchImage tMipChain;
HRESULT hr = tMipChain.Initialize( mdata2 );
hr = tMipChain.Initialize( mdata2 );
if ( FAILED(hr) )
return hr;
@ -2869,11 +2869,8 @@ HRESULT GenerateMipMaps3D( const Image* baseImages, size_t depth, DWORD filter,
}
}
if ( IsCompressed( format ) )
{
// We don't support generating mipmaps from compressed images, as those should be generated before compression
if ( IsCompressed(format) || IsTypeless(format) || IsPlanar(format) || IsPalettized(format) )
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
}
static_assert( TEX_FILTER_POINT == 0x100000, "TEX_FILTER_ flag values don't match TEX_FILTER_MASK" );
@ -2954,7 +2951,7 @@ HRESULT GenerateMipMaps3D( const Image* srcImages, size_t nimages, const TexMeta
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
if ( !metadata.IsVolumemap()
|| IsCompressed( metadata.format ) || IsVideo( metadata.format ) )
|| IsCompressed(metadata.format) || IsTypeless(metadata.format) || IsPlanar(metadata.format) || IsPalettized(metadata.format) )
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
if ( !_CalculateMipLevels3D(metadata.width, metadata.height, metadata.depth, levels) )

View File

@ -176,7 +176,9 @@ HRESULT CopyRectangle( const Image& srcImage, const Rect& srcRect, const Image&
if ( !srcImage.pixels || !dstImage.pixels )
return E_POINTER;
if ( IsCompressed( srcImage.format ) || IsCompressed( dstImage.format ) )
if ( IsCompressed( srcImage.format ) || IsCompressed( dstImage.format )
|| IsPlanar( srcImage.format ) || IsPlanar( dstImage.format )
|| IsPalettized( srcImage.format ) || IsPalettized( dstImage.format ) )
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
// Validate rectangle/offset
@ -284,6 +286,10 @@ HRESULT ComputeMSE( const Image& image1, const Image& image2, float& mse, float*
if ( image1.width != image2.width || image1.height != image2.height )
return E_INVALIDARG;
if ( IsPlanar( image1.format ) || IsPlanar( image2.format )
|| IsPalettized( image1.format ) || IsPalettized( image2.format ) )
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
if ( IsCompressed(image1.format) )
{
if ( IsCompressed(image2.format) )

View File

@ -79,14 +79,12 @@ static HRESULT _ComputeNMap( _In_ const Image& srcImage, _In_ DWORD flags, _In_
if ( !srcImage.pixels || !normalMap.pixels )
return E_INVALIDARG;
assert( !IsCompressed(format) && !IsTypeless( format ) );
const DWORD convFlags = _GetConvertFlags( format );
if ( !convFlags )
return E_FAIL;
if ( !( convFlags & (CONVF_UNORM | CONVF_SNORM | CONVF_FLOAT) ) )
HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
const size_t width = srcImage.width;
const size_t height = srcImage.height;
@ -257,7 +255,7 @@ _Use_decl_annotations_
HRESULT ComputeNormalMap( const Image& srcImage, DWORD flags, float amplitude,
DXGI_FORMAT format, ScratchImage& normalMap )
{
if ( !srcImage.pixels || !IsValid(format) || IsCompressed( format ) || IsTypeless( format ) )
if ( !srcImage.pixels || !IsValid(format) )
return E_INVALIDARG;
static_assert( CNMAP_CHANNEL_RED == 0x1, "CNMAP_CHANNEL_ flag values don't match mask" );
@ -275,7 +273,10 @@ HRESULT ComputeNormalMap( const Image& srcImage, DWORD flags, float amplitude,
return E_INVALIDARG;
}
if ( IsCompressed( srcImage.format ) || IsTypeless( srcImage.format ) )
if ( IsCompressed(format) || IsCompressed(srcImage.format)
|| IsTypeless(format) || IsTypeless(srcImage.format)
|| IsPlanar(format) || IsPlanar(srcImage.format)
|| IsPalettized(format) || IsPalettized(srcImage.format) )
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
// Setup target image
@ -306,11 +307,14 @@ _Use_decl_annotations_
HRESULT ComputeNormalMap( const Image* srcImages, size_t nimages, const TexMetadata& metadata,
DWORD flags, float amplitude, DXGI_FORMAT format, ScratchImage& normalMaps )
{
if ( !srcImages || !nimages )
if ( !srcImages || !nimages || !IsValid(format) )
return E_INVALIDARG;
if ( !IsValid(format) || IsCompressed(format) || IsTypeless(format) )
return E_INVALIDARG;
if ( IsCompressed(format) || IsCompressed(metadata.format)
|| IsTypeless(format) || IsTypeless(metadata.format)
|| IsPlanar(format) || IsPlanar(metadata.format)
|| IsPalettized(format) || IsPalettized(metadata.format) )
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
static_assert( CNMAP_CHANNEL_RED == 0x1, "CNMAP_CHANNEL_ flag values don't match mask" );
switch( flags & 0xf )

View File

@ -141,6 +141,7 @@ namespace DirectX
CONVF_XR = 0x200,
CONVF_PACKED = 0x400,
CONVF_BC = 0x800,
CONVF_YUV = 0x1000,
CONVF_R = 0x10000,
CONVF_G = 0x20000,
CONVF_B = 0x40000,

View File

@ -114,7 +114,8 @@ HRESULT PremultiplyAlpha( const Image& srcImage, DWORD flags, ScratchImage& imag
return E_POINTER;
if ( IsCompressed(srcImage.format)
|| IsVideo(srcImage.format)
|| IsPlanar(srcImage.format)
|| IsPalettized(srcImage.format)
|| IsTypeless(srcImage.format)
|| !HasAlpha(srcImage.format) )
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
@ -156,7 +157,8 @@ HRESULT PremultiplyAlpha( const Image* srcImages, size_t nimages, const TexMetad
return E_INVALIDARG;
if ( IsCompressed(metadata.format)
|| IsVideo(metadata.format)
|| IsPlanar(metadata.format)
|| IsPalettized(metadata.format)
|| IsTypeless(metadata.format)
|| !HasAlpha(metadata.format) )
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );

View File

@ -738,8 +738,6 @@ static HRESULT _CopyPixels( _In_reads_bytes_(size) LPCVOID pSource, size_t size,
//-------------------------------------------------------------------------------------
static HRESULT _EncodeTGAHeader( _In_ const Image& image, _Out_ TGA_HEADER& header, _Inout_ DWORD& convFlags )
{
assert( IsValid( image.format ) && !IsVideo( image.format ) );
memset( &header, 0, sizeof(TGA_HEADER) );
if ( (image.width > 0xFFFF)

View File

@ -276,7 +276,7 @@ REFGUID GetWICCodec( WICCodecs codec )
_Use_decl_annotations_
size_t BitsPerPixel( DXGI_FORMAT fmt )
{
switch( fmt )
switch( static_cast<int>(fmt) )
{
case DXGI_FORMAT_R32G32B32A32_TYPELESS:
case DXGI_FORMAT_R32G32B32A32_FLOAT:
@ -304,6 +304,9 @@ size_t BitsPerPixel( DXGI_FORMAT 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_Y416:
case DXGI_FORMAT_Y210:
case DXGI_FORMAT_Y216:
return 64;
case DXGI_FORMAT_R10G10B10A2_TYPELESS:
@ -341,8 +344,20 @@ size_t BitsPerPixel( DXGI_FORMAT fmt )
case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
case DXGI_FORMAT_B8G8R8X8_TYPELESS:
case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
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 */:
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 */:
return 24;
case DXGI_FORMAT_R8G8_TYPELESS:
case DXGI_FORMAT_R8G8_UNORM:
case DXGI_FORMAT_R8G8_UINT:
@ -357,14 +372,24 @@ size_t BitsPerPixel( DXGI_FORMAT fmt )
case DXGI_FORMAT_R16_SINT:
case DXGI_FORMAT_B5G6R5_UNORM:
case DXGI_FORMAT_B5G5R5A1_UNORM:
case DXGI_FORMAT_A8P8:
case DXGI_FORMAT_B4G4R4A4_UNORM:
return 16;
case DXGI_FORMAT_NV12:
case DXGI_FORMAT_420_OPAQUE:
case DXGI_FORMAT_NV11:
return 12;
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_AI44:
case DXGI_FORMAT_IA44:
case DXGI_FORMAT_P8:
return 8;
case DXGI_FORMAT_R1_UNORM:
@ -395,11 +420,6 @@ size_t BitsPerPixel( DXGI_FORMAT fmt )
case DXGI_FORMAT_BC7_UNORM_SRGB:
return 8;
case DXGI_FORMAT_B4G4R4A4_UNORM:
return 16;
// We don't support the video formats ( see IsVideo function )
default:
return 0;
}
@ -413,7 +433,7 @@ size_t BitsPerPixel( DXGI_FORMAT fmt )
_Use_decl_annotations_
size_t BitsPerColor( DXGI_FORMAT fmt )
{
switch( fmt )
switch( static_cast<int>(fmt) )
{
case DXGI_FORMAT_R32G32B32A32_TYPELESS:
case DXGI_FORMAT_R32G32B32A32_FLOAT:
@ -466,6 +486,9 @@ size_t BitsPerColor( DXGI_FORMAT fmt )
case DXGI_FORMAT_BC6H_TYPELESS:
case DXGI_FORMAT_BC6H_UF16:
case DXGI_FORMAT_BC6H_SF16:
case DXGI_FORMAT_Y416:
case DXGI_FORMAT_P016:
case DXGI_FORMAT_Y216:
return 16;
case DXGI_FORMAT_R9G9B9E5_SHAREDEXP:
@ -478,6 +501,9 @@ size_t BitsPerColor( DXGI_FORMAT fmt )
case DXGI_FORMAT_R10G10B10A2_UNORM:
case DXGI_FORMAT_R10G10B10A2_UINT:
case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM:
case DXGI_FORMAT_Y410:
case DXGI_FORMAT_P010:
case DXGI_FORMAT_Y210:
return 10;
case DXGI_FORMAT_R8G8B8A8_TYPELESS:
@ -511,6 +537,11 @@ size_t BitsPerColor( DXGI_FORMAT fmt )
case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
case DXGI_FORMAT_B8G8R8X8_TYPELESS:
case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
case DXGI_FORMAT_AYUV:
case DXGI_FORMAT_NV12:
case DXGI_FORMAT_420_OPAQUE:
case DXGI_FORMAT_YUY2:
case DXGI_FORMAT_NV11:
return 8;
case DXGI_FORMAT_BC7_TYPELESS:
@ -536,11 +567,26 @@ size_t BitsPerColor( DXGI_FORMAT fmt )
case DXGI_FORMAT_B4G4R4A4_UNORM:
return 4;
// We don't support the video formats ( see IsVideo function )
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:
case DXGI_FORMAT_A8P8:
// Palettized formats return 0 for this function
default:
return 0;
}
@ -555,7 +601,7 @@ _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) );
assert( IsValid(fmt) );
if ( IsCompressed(fmt) )
{
@ -573,10 +619,28 @@ void ComputePitch( DXGI_FORMAT fmt, size_t width, size_t height,
}
else if ( IsPacked(fmt) )
{
rowPitch = ( ( width + 1 ) >> 1) * 4;
size_t bpe = ( fmt == DXGI_FORMAT_Y210 || fmt == DXGI_FORMAT_Y216 ) ? 8 : 4;
rowPitch = ( ( width + 1 ) >> 1 ) * bpe;
slicePitch = rowPitch * height;
}
else if ( fmt == DXGI_FORMAT_NV11 )
{
rowPitch = ( ( width + 3 ) >> 2 ) * 4;
// 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;
slicePitch = rowPitch * ( height + ( ( height + 1 ) >> 1 ) );
}
else
{
size_t bpp;

View File

@ -180,6 +180,18 @@ SValue g_pFormats[] =
DEFFMT(BC7_UNORM_SRGB),
// DXGI 1.2 formats
DEFFMT(AYUV),
DEFFMT(Y410),
DEFFMT(Y416),
DEFFMT(NV12),
DEFFMT(P010),
DEFFMT(P016),
DEFFMT(420_OPAQUE),
DEFFMT(YUY2),
DEFFMT(Y210),
DEFFMT(Y216),
DEFFMT(NV11),
// No support for legacy paletted video formats (AI44, IA44, P8, A8P8)
DEFFMT(B4G4R4A4_UNORM),
{ nullptr, DXGI_FORMAT_UNKNOWN }
@ -897,7 +909,6 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
PrintInfo( info );
size_t tMips = ( !mipLevels && info.mipLevels > 1 ) ? info.mipLevels : mipLevels;
DXGI_FORMAT tformat = ( format == DXGI_FORMAT_UNKNOWN ) ? info.format : format;
bool sizewarn = false;
@ -933,6 +944,49 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
wprintf( L" as");
fflush(stdout);
// --- Planar ------------------------------------------------------------------
if ( IsPlanar( info.format ) )
{
const Image* img = image->GetImage(0,0,0);
assert( img );
size_t nimg = image->GetImageCount();
ScratchImage *timage = new ScratchImage;
if ( !timage )
{
wprintf( L" ERROR: Memory allocation failed\n" );
delete image;
goto LError;
}
hr = ConvertToSinglePlane( img, nimg, info, *timage );
if ( FAILED(hr) )
{
wprintf( L" FAILED [converttosingeplane] (%x)\n", hr);
delete timage;
delete image;
continue;
}
const TexMetadata& tinfo = timage->GetMetadata();
info.format = tinfo.format;
assert( info.width == tinfo.width );
assert( info.height == tinfo.height );
assert( info.depth == tinfo.depth );
assert( info.arraySize == tinfo.arraySize );
assert( info.mipLevels == tinfo.mipLevels );
assert( info.miscFlags == tinfo.miscFlags );
assert( info.miscFlags2 == tinfo.miscFlags2 );
assert( info.dimension == tinfo.dimension );
delete image;
image = timage;
}
DXGI_FORMAT tformat = ( format == DXGI_FORMAT_UNKNOWN ) ? info.format : format;
// --- Decompress --------------------------------------------------------------
if ( IsCompressed( info.format ) )
{