DirectXTex: Support for Direct3D 11 video and Xbox One extended formats
- New APIs: IsPlanar, IsPalettized, IsDepthStencil, ConvertToSinglePlane
This commit is contained in:
parent
b67a8ef792
commit
5336f904da
@ -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 };
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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
@ -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:
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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) )
|
||||
|
@ -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) )
|
||||
|
@ -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 )
|
||||
|
@ -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,
|
||||
|
@ -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 );
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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 ) )
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user