mirror of
https://github.com/microsoft/DirectXTex.git
synced 2025-07-14 14:10:13 +02:00
DDSTextureLoader/ScreenGrab: Updated with support for Direct3D 11 video formats including legacy 'YUY2' DDS files
This commit is contained in:
parent
c43f736184
commit
9f13dd26f9
@ -300,6 +300,9 @@ static size_t BitsPerPixel( _In_ 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:
|
||||
@ -337,8 +340,15 @@ static size_t BitsPerPixel( _In_ 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:
|
||||
return 32;
|
||||
|
||||
case DXGI_FORMAT_P010:
|
||||
case DXGI_FORMAT_P016:
|
||||
return 24;
|
||||
|
||||
case DXGI_FORMAT_R8G8_TYPELESS:
|
||||
case DXGI_FORMAT_R8G8_UNORM:
|
||||
case DXGI_FORMAT_R8G8_UINT:
|
||||
@ -353,15 +363,24 @@ static size_t BitsPerPixel( _In_ 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:
|
||||
@ -392,6 +411,21 @@ static size_t BitsPerPixel( _In_ DXGI_FORMAT fmt )
|
||||
case DXGI_FORMAT_BC7_UNORM_SRGB:
|
||||
return 8;
|
||||
|
||||
#if defined(_XBOX_ONE) && defined(_TITLE)
|
||||
|
||||
case DXGI_FORMAT_R10G10B10_7E3_A2_FLOAT:
|
||||
case DXGI_FORMAT_R10G10B10_6E4_A2_FLOAT:
|
||||
return 32;
|
||||
|
||||
#if MONOLITHIC
|
||||
case DXGI_FORMAT_D16_UNORM_S8_UINT:
|
||||
case DXGI_FORMAT_R16_UNORM_X8_TYPELESS:
|
||||
case DXGI_FORMAT_X16_TYPELESS_G8_UINT:
|
||||
return 24;
|
||||
#endif
|
||||
|
||||
#endif // _XBOX_ONE && _TITLE
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@ -414,7 +448,8 @@ static void GetSurfaceInfo( _In_ size_t width,
|
||||
|
||||
bool bc = false;
|
||||
bool packed = false;
|
||||
size_t bcnumBytesPerBlock = 0;
|
||||
bool planar = false;
|
||||
size_t bpe = 0;
|
||||
switch (fmt)
|
||||
{
|
||||
case DXGI_FORMAT_BC1_TYPELESS:
|
||||
@ -424,7 +459,7 @@ static void GetSurfaceInfo( _In_ size_t width,
|
||||
case DXGI_FORMAT_BC4_UNORM:
|
||||
case DXGI_FORMAT_BC4_SNORM:
|
||||
bc=true;
|
||||
bcnumBytesPerBlock = 8;
|
||||
bpe = 8;
|
||||
break;
|
||||
|
||||
case DXGI_FORMAT_BC2_TYPELESS:
|
||||
@ -443,13 +478,44 @@ static void GetSurfaceInfo( _In_ size_t width,
|
||||
case DXGI_FORMAT_BC7_UNORM:
|
||||
case DXGI_FORMAT_BC7_UNORM_SRGB:
|
||||
bc = true;
|
||||
bcnumBytesPerBlock = 16;
|
||||
bpe = 16;
|
||||
break;
|
||||
|
||||
case DXGI_FORMAT_R8G8_B8G8_UNORM:
|
||||
case DXGI_FORMAT_G8R8_G8B8_UNORM:
|
||||
case DXGI_FORMAT_YUY2:
|
||||
packed = true;
|
||||
bpe = 4;
|
||||
break;
|
||||
|
||||
case DXGI_FORMAT_Y210:
|
||||
case DXGI_FORMAT_Y216:
|
||||
packed = true;
|
||||
bpe = 8;
|
||||
break;
|
||||
|
||||
case DXGI_FORMAT_NV12:
|
||||
case DXGI_FORMAT_420_OPAQUE:
|
||||
planar = true;
|
||||
bpe = 2;
|
||||
break;
|
||||
|
||||
case DXGI_FORMAT_P010:
|
||||
case DXGI_FORMAT_P016:
|
||||
planar = true;
|
||||
bpe = 4;
|
||||
break;
|
||||
|
||||
#if defined(_XBOX_ONE) && defined(_TITLE) && MONOLITHIC
|
||||
|
||||
case DXGI_FORMAT_D16_UNORM_S8_UINT:
|
||||
case DXGI_FORMAT_R16_UNORM_X8_TYPELESS:
|
||||
case DXGI_FORMAT_X16_TYPELESS_G8_UINT:
|
||||
planar = true;
|
||||
bpe = 4;
|
||||
break;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
if (bc)
|
||||
@ -464,22 +530,36 @@ static void GetSurfaceInfo( _In_ size_t width,
|
||||
{
|
||||
numBlocksHigh = std::max<size_t>( 1, (height + 3) / 4 );
|
||||
}
|
||||
rowBytes = numBlocksWide * bcnumBytesPerBlock;
|
||||
rowBytes = numBlocksWide * bpe;
|
||||
numRows = numBlocksHigh;
|
||||
numBytes = rowBytes * numBlocksHigh;
|
||||
}
|
||||
else if (packed)
|
||||
{
|
||||
rowBytes = ( ( width + 1 ) >> 1 ) * 4;
|
||||
rowBytes = ( ( width + 1 ) >> 1 ) * bpe;
|
||||
numRows = height;
|
||||
numBytes = rowBytes * height;
|
||||
}
|
||||
else if ( fmt == DXGI_FORMAT_NV11 )
|
||||
{
|
||||
rowBytes = ( ( width + 1 ) >> 1 ) * 2;
|
||||
numBytes = rowBytes * ( ( height + 1 ) >> 1 ) * 4;
|
||||
numRows = height * 2; // Direct3D makes this simplifying assumption, although it is larger than the 4:1:1 data
|
||||
}
|
||||
else if (planar)
|
||||
{
|
||||
rowBytes = ( ( width + 1 ) >> 1 ) * bpe;
|
||||
numBytes = ( rowBytes * height ) + ( ( rowBytes * height + 1 ) >> 1 );
|
||||
numRows = height + ( ( height + 1 ) >> 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t bpp = BitsPerPixel( fmt );
|
||||
rowBytes = ( width * bpp + 7 ) / 8; // round up to nearest byte
|
||||
numRows = height;
|
||||
numBytes = rowBytes * height;
|
||||
}
|
||||
|
||||
numBytes = rowBytes * numRows;
|
||||
if (outNumBytes)
|
||||
{
|
||||
*outNumBytes = numBytes;
|
||||
@ -671,6 +751,11 @@ static DXGI_FORMAT GetDXGIFormat( const DDS_PIXELFORMAT& ddpf )
|
||||
return DXGI_FORMAT_G8R8_G8B8_UNORM;
|
||||
}
|
||||
|
||||
if (MAKEFOURCC('Y','U','Y','2') == ddpf.fourCC)
|
||||
{
|
||||
return DXGI_FORMAT_YUY2;
|
||||
}
|
||||
|
||||
// Check for D3DFORMAT enums being set here
|
||||
switch( ddpf.fourCC )
|
||||
{
|
||||
@ -764,7 +849,6 @@ static HRESULT FillInitData( _In_ size_t width,
|
||||
|
||||
size_t NumBytes = 0;
|
||||
size_t RowBytes = 0;
|
||||
size_t NumRows = 0;
|
||||
const uint8_t* pSrcBits = bitData;
|
||||
const uint8_t* pEndBits = bitData + bitSize;
|
||||
|
||||
@ -781,7 +865,7 @@ static HRESULT FillInitData( _In_ size_t width,
|
||||
format,
|
||||
&NumBytes,
|
||||
&RowBytes,
|
||||
&NumRows
|
||||
nullptr
|
||||
);
|
||||
|
||||
if ( (mipCount <= 1) || !maxsize || (w <= maxsize && h <= maxsize && d <= maxsize) )
|
||||
@ -1114,10 +1198,20 @@ static HRESULT CreateTextureFromDDS( _In_ ID3D11Device* d3dDevice,
|
||||
return HRESULT_FROM_WIN32( ERROR_INVALID_DATA );
|
||||
}
|
||||
|
||||
switch( d3d10ext->dxgiFormat )
|
||||
{
|
||||
case DXGI_FORMAT_AI44:
|
||||
case DXGI_FORMAT_IA44:
|
||||
case DXGI_FORMAT_P8:
|
||||
case DXGI_FORMAT_A8P8:
|
||||
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
|
||||
|
||||
default:
|
||||
if ( BitsPerPixel( d3d10ext->dxgiFormat ) == 0 )
|
||||
{
|
||||
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
|
||||
}
|
||||
}
|
||||
|
||||
format = d3d10ext->dxgiFormat;
|
||||
|
||||
|
@ -146,6 +146,9 @@ static const DDS_PIXELFORMAT DDSPF_R8G8_B8G8 =
|
||||
static const DDS_PIXELFORMAT DDSPF_G8R8_G8B8 =
|
||||
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('G','R','G','B'), 0, 0, 0, 0, 0 };
|
||||
|
||||
static const DDS_PIXELFORMAT DDSPF_YUY2 =
|
||||
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('Y','U','Y','2'), 0, 0, 0, 0, 0 };
|
||||
|
||||
static const DDS_PIXELFORMAT DDSPF_A8R8G8B8 =
|
||||
{ sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 };
|
||||
|
||||
@ -226,6 +229,9 @@ static size_t BitsPerPixel( _In_ 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:
|
||||
@ -263,8 +269,15 @@ static size_t BitsPerPixel( _In_ 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:
|
||||
return 32;
|
||||
|
||||
case DXGI_FORMAT_P010:
|
||||
case DXGI_FORMAT_P016:
|
||||
return 24;
|
||||
|
||||
case DXGI_FORMAT_R8G8_TYPELESS:
|
||||
case DXGI_FORMAT_R8G8_UNORM:
|
||||
case DXGI_FORMAT_R8G8_UINT:
|
||||
@ -279,15 +292,24 @@ static size_t BitsPerPixel( _In_ 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:
|
||||
@ -318,6 +340,21 @@ static size_t BitsPerPixel( _In_ DXGI_FORMAT fmt )
|
||||
case DXGI_FORMAT_BC7_UNORM_SRGB:
|
||||
return 8;
|
||||
|
||||
#if defined(_XBOX_ONE) && defined(_TITLE)
|
||||
|
||||
case DXGI_FORMAT_R10G10B10_7E3_A2_FLOAT:
|
||||
case DXGI_FORMAT_R10G10B10_6E4_A2_FLOAT:
|
||||
return 32;
|
||||
|
||||
#if MONOLITHIC
|
||||
case DXGI_FORMAT_D16_UNORM_S8_UINT:
|
||||
case DXGI_FORMAT_R16_UNORM_X8_TYPELESS:
|
||||
case DXGI_FORMAT_X16_TYPELESS_G8_UINT:
|
||||
return 24;
|
||||
#endif
|
||||
|
||||
#endif // _XBOX_ONE && _TITLE
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@ -376,7 +413,8 @@ static void GetSurfaceInfo( _In_ size_t width,
|
||||
|
||||
bool bc = false;
|
||||
bool packed = false;
|
||||
size_t bcnumBytesPerBlock = 0;
|
||||
bool planar = false;
|
||||
size_t bpe = 0;
|
||||
switch (fmt)
|
||||
{
|
||||
case DXGI_FORMAT_BC1_TYPELESS:
|
||||
@ -386,7 +424,7 @@ static void GetSurfaceInfo( _In_ size_t width,
|
||||
case DXGI_FORMAT_BC4_UNORM:
|
||||
case DXGI_FORMAT_BC4_SNORM:
|
||||
bc=true;
|
||||
bcnumBytesPerBlock = 8;
|
||||
bpe = 8;
|
||||
break;
|
||||
|
||||
case DXGI_FORMAT_BC2_TYPELESS:
|
||||
@ -405,13 +443,44 @@ static void GetSurfaceInfo( _In_ size_t width,
|
||||
case DXGI_FORMAT_BC7_UNORM:
|
||||
case DXGI_FORMAT_BC7_UNORM_SRGB:
|
||||
bc = true;
|
||||
bcnumBytesPerBlock = 16;
|
||||
bpe = 16;
|
||||
break;
|
||||
|
||||
case DXGI_FORMAT_R8G8_B8G8_UNORM:
|
||||
case DXGI_FORMAT_G8R8_G8B8_UNORM:
|
||||
case DXGI_FORMAT_YUY2:
|
||||
packed = true;
|
||||
bpe = 4;
|
||||
break;
|
||||
|
||||
case DXGI_FORMAT_Y210:
|
||||
case DXGI_FORMAT_Y216:
|
||||
packed = true;
|
||||
bpe = 8;
|
||||
break;
|
||||
|
||||
case DXGI_FORMAT_NV12:
|
||||
case DXGI_FORMAT_420_OPAQUE:
|
||||
planar = true;
|
||||
bpe = 2;
|
||||
break;
|
||||
|
||||
case DXGI_FORMAT_P010:
|
||||
case DXGI_FORMAT_P016:
|
||||
planar = true;
|
||||
bpe = 4;
|
||||
break;
|
||||
|
||||
#if defined(_XBOX_ONE) && defined(_TITLE) && MONOLITHIC
|
||||
|
||||
case DXGI_FORMAT_D16_UNORM_S8_UINT:
|
||||
case DXGI_FORMAT_R16_UNORM_X8_TYPELESS:
|
||||
case DXGI_FORMAT_X16_TYPELESS_G8_UINT:
|
||||
planar = true;
|
||||
bpe = 4;
|
||||
break;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
if (bc)
|
||||
@ -426,22 +495,36 @@ static void GetSurfaceInfo( _In_ size_t width,
|
||||
{
|
||||
numBlocksHigh = std::max<size_t>( 1, (height + 3) / 4 );
|
||||
}
|
||||
rowBytes = numBlocksWide * bcnumBytesPerBlock;
|
||||
rowBytes = numBlocksWide * bpe;
|
||||
numRows = numBlocksHigh;
|
||||
numBytes = rowBytes * numBlocksHigh;
|
||||
}
|
||||
else if (packed)
|
||||
{
|
||||
rowBytes = ( ( width + 1 ) >> 1 ) * 4;
|
||||
rowBytes = ( ( width + 1 ) >> 1 ) * bpe;
|
||||
numRows = height;
|
||||
numBytes = rowBytes * height;
|
||||
}
|
||||
else if ( fmt == DXGI_FORMAT_NV11 )
|
||||
{
|
||||
rowBytes = ( ( width + 1 ) >> 1 ) * 2;
|
||||
numBytes = rowBytes * ( ( height + 1 ) >> 1 ) * 4;
|
||||
numRows = height * 2; // Direct3D makes this simplifying assumption, although it is larger than the 4:1:1 data
|
||||
}
|
||||
else if (planar)
|
||||
{
|
||||
rowBytes = ( ( width + 1 ) >> 1 ) * bpe;
|
||||
numBytes = ( rowBytes * height ) + ( ( rowBytes * height + 1 ) >> 1 );
|
||||
numRows = height + ( ( height + 1 ) >> 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t bpp = BitsPerPixel( fmt );
|
||||
rowBytes = ( width * bpp + 7 ) / 8; // round up to nearest byte
|
||||
numRows = height;
|
||||
numBytes = rowBytes * height;
|
||||
}
|
||||
|
||||
numBytes = rowBytes * numRows;
|
||||
if (outNumBytes)
|
||||
{
|
||||
*outNumBytes = numBytes;
|
||||
@ -710,7 +793,8 @@ HRESULT DirectX::SaveDDSTextureToFile( _In_ ID3D11DeviceContext* pContext,
|
||||
case DXGI_FORMAT_B5G5R5A1_UNORM: memcpy_s( &header->ddspf, sizeof(header->ddspf), &DDSPF_A1R5G5B5, sizeof(DDS_PIXELFORMAT) ); break;
|
||||
case DXGI_FORMAT_B8G8R8A8_UNORM: memcpy_s( &header->ddspf, sizeof(header->ddspf), &DDSPF_A8R8G8B8, sizeof(DDS_PIXELFORMAT) ); break; // DXGI 1.1
|
||||
case DXGI_FORMAT_B8G8R8X8_UNORM: memcpy_s( &header->ddspf, sizeof(header->ddspf), &DDSPF_X8R8G8B8, sizeof(DDS_PIXELFORMAT) ); break; // DXGI 1.1
|
||||
case DXGI_FORMAT_B4G4R4A4_UNORM: memcpy_s( &header->ddspf, sizeof(header->ddspf), &DDSPF_A4R4G4B4, sizeof(DDS_PIXELFORMAT) ); break;
|
||||
case DXGI_FORMAT_YUY2: memcpy_s( &header->ddspf, sizeof(header->ddspf), &DDSPF_YUY2, sizeof(DDS_PIXELFORMAT) ); break; // DXGI 1.2
|
||||
case DXGI_FORMAT_B4G4R4A4_UNORM: memcpy_s( &header->ddspf, sizeof(header->ddspf), &DDSPF_A4R4G4B4, sizeof(DDS_PIXELFORMAT) ); break; // DXGI 1.2
|
||||
|
||||
// Legacy D3DX formats using D3DFMT enum value as FourCC
|
||||
case DXGI_FORMAT_R32G32B32A32_FLOAT: header->ddspf.size = sizeof(DDS_PIXELFORMAT); header->ddspf.flags = DDS_FOURCC; header->ddspf.fourCC = 116; break; // D3DFMT_A32B32G32R32F
|
||||
@ -722,6 +806,12 @@ HRESULT DirectX::SaveDDSTextureToFile( _In_ ID3D11DeviceContext* pContext,
|
||||
case DXGI_FORMAT_R32_FLOAT: header->ddspf.size = sizeof(DDS_PIXELFORMAT); header->ddspf.flags = DDS_FOURCC; header->ddspf.fourCC = 114; break; // D3DFMT_R32F
|
||||
case DXGI_FORMAT_R16_FLOAT: header->ddspf.size = sizeof(DDS_PIXELFORMAT); header->ddspf.flags = DDS_FOURCC; header->ddspf.fourCC = 111; break; // D3DFMT_R16F
|
||||
|
||||
case DXGI_FORMAT_AI44:
|
||||
case DXGI_FORMAT_IA44:
|
||||
case DXGI_FORMAT_P8:
|
||||
case DXGI_FORMAT_A8P8:
|
||||
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
|
||||
|
||||
default:
|
||||
memcpy_s( &header->ddspf, sizeof(header->ddspf), &DDSPF_DX10, sizeof(DDS_PIXELFORMAT) );
|
||||
|
||||
@ -767,9 +857,9 @@ HRESULT DirectX::SaveDDSTextureToFile( _In_ ID3D11DeviceContext* pContext,
|
||||
|
||||
uint8_t* dptr = pixels.get();
|
||||
|
||||
size_t msize = std::min<size_t>( rowPitch, mapped.RowPitch );
|
||||
for( size_t h = 0; h < rowCount; ++h )
|
||||
{
|
||||
size_t msize = std::min<size_t>( rowPitch, mapped.RowPitch );
|
||||
memcpy_s( dptr, rowPitch, sptr, msize );
|
||||
sptr += mapped.RowPitch;
|
||||
dptr += rowPitch;
|
||||
|
Loading…
x
Reference in New Issue
Block a user