mirror of
https://github.com/microsoft/DirectXTex.git
synced 2025-07-16 15:00:14 +02:00
DirectXTex: Improved format conversions
- depth/stencil conversions incl fix for stencil data handling - alpha only conversions - fixed bug with half-precision (float16) format conversions - fixed bug with RGB -> 1 channel conversion for non-UNORM sources
This commit is contained in:
parent
91951178e0
commit
367db3de30
@ -178,6 +178,8 @@ namespace
|
|||||||
namespace DirectX
|
namespace DirectX
|
||||||
{
|
{
|
||||||
static const XMVECTORF32 g_Grayscale = { 0.2125f, 0.7154f, 0.0721f, 0.0f };
|
static const XMVECTORF32 g_Grayscale = { 0.2125f, 0.7154f, 0.0721f, 0.0f };
|
||||||
|
static const XMVECTORF32 g_HalfMin = { -65504.f, -65504.f, -65504.f, -65504.f };
|
||||||
|
static const XMVECTORF32 g_HalfMax = { 65504.f, 65504.f, 65504.f, 65504.f };
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------
|
||||||
// Copies an image row with optional clearing of alpha value to 1.0
|
// Copies an image row with optional clearing of alpha value to 1.0
|
||||||
@ -1221,7 +1223,7 @@ _Use_decl_annotations_ bool _LoadScanline( XMVECTOR* pDestination, size_t count,
|
|||||||
case DXGI_FORMAT_B5G6R5_UNORM:
|
case DXGI_FORMAT_B5G6R5_UNORM:
|
||||||
if ( size >= sizeof(XMU565) )
|
if ( size >= sizeof(XMU565) )
|
||||||
{
|
{
|
||||||
static XMVECTORF32 s_Scale = { 1.f/31.f, 1.f/63.f, 1.f/31.f, 1.f };
|
static const XMVECTORF32 s_Scale = { 1.f/31.f, 1.f/63.f, 1.f/31.f, 1.f };
|
||||||
const XMU565 * __restrict sPtr = reinterpret_cast<const XMU565*>(pSource);
|
const XMU565 * __restrict sPtr = reinterpret_cast<const XMU565*>(pSource);
|
||||||
for( size_t icount = 0; icount < ( size - sizeof(XMU565) + 1 ); icount += sizeof(XMU565) )
|
for( size_t icount = 0; icount < ( size - sizeof(XMU565) + 1 ); icount += sizeof(XMU565) )
|
||||||
{
|
{
|
||||||
@ -1238,7 +1240,7 @@ _Use_decl_annotations_ bool _LoadScanline( XMVECTOR* pDestination, size_t count,
|
|||||||
case DXGI_FORMAT_B5G5R5A1_UNORM:
|
case DXGI_FORMAT_B5G5R5A1_UNORM:
|
||||||
if ( size >= sizeof(XMU555) )
|
if ( size >= sizeof(XMU555) )
|
||||||
{
|
{
|
||||||
static XMVECTORF32 s_Scale = { 1.f/31.f, 1.f/31.f, 1.f/31.f, 1.f };
|
static const XMVECTORF32 s_Scale = { 1.f/31.f, 1.f/31.f, 1.f/31.f, 1.f };
|
||||||
const XMU555 * __restrict sPtr = reinterpret_cast<const XMU555*>(pSource);
|
const XMU555 * __restrict sPtr = reinterpret_cast<const XMU555*>(pSource);
|
||||||
for( size_t icount = 0; icount < ( size - sizeof(XMU555) + 1 ); icount += sizeof(XMU555) )
|
for( size_t icount = 0; icount < ( size - sizeof(XMU555) + 1 ); icount += sizeof(XMU555) )
|
||||||
{
|
{
|
||||||
@ -1505,7 +1507,7 @@ _Use_decl_annotations_ bool _LoadScanline( XMVECTOR* pDestination, size_t count,
|
|||||||
case DXGI_FORMAT_B4G4R4A4_UNORM:
|
case DXGI_FORMAT_B4G4R4A4_UNORM:
|
||||||
if ( size >= sizeof(XMUNIBBLE4) )
|
if ( size >= sizeof(XMUNIBBLE4) )
|
||||||
{
|
{
|
||||||
static XMVECTORF32 s_Scale = { 1.f/15.f, 1.f/15.f, 1.f/15.f, 1.f/15.f };
|
static const XMVECTORF32 s_Scale = { 1.f/15.f, 1.f/15.f, 1.f/15.f, 1.f/15.f };
|
||||||
const XMUNIBBLE4 * __restrict sPtr = reinterpret_cast<const XMUNIBBLE4*>(pSource);
|
const XMUNIBBLE4 * __restrict sPtr = reinterpret_cast<const XMUNIBBLE4*>(pSource);
|
||||||
for( size_t icount = 0; icount < ( size - sizeof(XMUNIBBLE4) + 1 ); icount += sizeof(XMUNIBBLE4) )
|
for( size_t icount = 0; icount < ( size - sizeof(XMUNIBBLE4) + 1 ); icount += sizeof(XMUNIBBLE4) )
|
||||||
{
|
{
|
||||||
@ -1629,7 +1631,19 @@ bool _StoreScanline( LPVOID pDestination, size_t size, DXGI_FORMAT format,
|
|||||||
STORE_SCANLINE( XMINT3, XMStoreSInt3 )
|
STORE_SCANLINE( XMINT3, XMStoreSInt3 )
|
||||||
|
|
||||||
case DXGI_FORMAT_R16G16B16A16_FLOAT:
|
case DXGI_FORMAT_R16G16B16A16_FLOAT:
|
||||||
STORE_SCANLINE( XMHALF4, XMStoreHalf4 )
|
if ( size >= sizeof(XMHALF4) )
|
||||||
|
{
|
||||||
|
XMHALF4* __restrict dPtr = reinterpret_cast<XMHALF4*>(pDestination);
|
||||||
|
for( size_t icount = 0; icount < ( size - sizeof(XMHALF4) + 1 ); icount += sizeof(XMHALF4) )
|
||||||
|
{
|
||||||
|
if ( sPtr >= ePtr ) break;
|
||||||
|
XMVECTOR v = *sPtr++;
|
||||||
|
v = XMVectorClamp( v, g_HalfMin, g_HalfMax );
|
||||||
|
XMStoreHalf4( dPtr++, v );
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
|
||||||
case DXGI_FORMAT_R16G16B16A16_UNORM:
|
case DXGI_FORMAT_R16G16B16A16_UNORM:
|
||||||
STORE_SCANLINE( XMUSHORTN4, XMStoreUShortN4 )
|
STORE_SCANLINE( XMUSHORTN4, XMStoreUShortN4 )
|
||||||
@ -1729,7 +1743,19 @@ bool _StoreScanline( LPVOID pDestination, size_t size, DXGI_FORMAT format,
|
|||||||
STORE_SCANLINE( XMBYTE4, XMStoreByte4 )
|
STORE_SCANLINE( XMBYTE4, XMStoreByte4 )
|
||||||
|
|
||||||
case DXGI_FORMAT_R16G16_FLOAT:
|
case DXGI_FORMAT_R16G16_FLOAT:
|
||||||
STORE_SCANLINE( XMHALF2, XMStoreHalf2 )
|
if ( size >= sizeof(XMHALF2) )
|
||||||
|
{
|
||||||
|
XMHALF2* __restrict dPtr = reinterpret_cast<XMHALF2*>(pDestination);
|
||||||
|
for( size_t icount = 0; icount < ( size - sizeof(XMHALF2) + 1 ); icount += sizeof(XMHALF2) )
|
||||||
|
{
|
||||||
|
if ( sPtr >= ePtr ) break;
|
||||||
|
XMVECTOR v = *sPtr++;
|
||||||
|
v = XMVectorClamp( v, g_HalfMin, g_HalfMax );
|
||||||
|
XMStoreHalf2( dPtr++, v );
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
|
||||||
case DXGI_FORMAT_R16G16_UNORM:
|
case DXGI_FORMAT_R16G16_UNORM:
|
||||||
STORE_SCANLINE( XMUSHORTN2, XMStoreUShortN2 )
|
STORE_SCANLINE( XMUSHORTN2, XMStoreUShortN2 )
|
||||||
@ -1823,6 +1849,7 @@ bool _StoreScanline( LPVOID pDestination, size_t size, DXGI_FORMAT format,
|
|||||||
{
|
{
|
||||||
if ( sPtr >= ePtr ) break;
|
if ( sPtr >= ePtr ) break;
|
||||||
float v = XMVectorGetX( *sPtr++ );
|
float v = XMVectorGetX( *sPtr++ );
|
||||||
|
v = std::max<float>( std::min<float>( v, 65504.f ), -65504.f );
|
||||||
*(dPtr++) = XMConvertFloatToHalf(v);
|
*(dPtr++) = XMConvertFloatToHalf(v);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -2071,7 +2098,7 @@ bool _StoreScanline( LPVOID pDestination, size_t size, DXGI_FORMAT format,
|
|||||||
case DXGI_FORMAT_B5G6R5_UNORM:
|
case DXGI_FORMAT_B5G6R5_UNORM:
|
||||||
if ( size >= sizeof(XMU565) )
|
if ( size >= sizeof(XMU565) )
|
||||||
{
|
{
|
||||||
static XMVECTORF32 s_Scale = { 31.f, 63.f, 31.f, 1.f };
|
static const XMVECTORF32 s_Scale = { 31.f, 63.f, 31.f, 1.f };
|
||||||
XMU565 * __restrict dPtr = reinterpret_cast<XMU565*>(pDestination);
|
XMU565 * __restrict dPtr = reinterpret_cast<XMU565*>(pDestination);
|
||||||
for( size_t icount = 0; icount < ( size - sizeof(XMU565) + 1 ); icount += sizeof(XMU565) )
|
for( size_t icount = 0; icount < ( size - sizeof(XMU565) + 1 ); icount += sizeof(XMU565) )
|
||||||
{
|
{
|
||||||
@ -2087,7 +2114,7 @@ bool _StoreScanline( LPVOID pDestination, size_t size, DXGI_FORMAT format,
|
|||||||
case DXGI_FORMAT_B5G5R5A1_UNORM:
|
case DXGI_FORMAT_B5G5R5A1_UNORM:
|
||||||
if ( size >= sizeof(XMU555) )
|
if ( size >= sizeof(XMU555) )
|
||||||
{
|
{
|
||||||
static XMVECTORF32 s_Scale = { 31.f, 31.f, 31.f, 1.f };
|
static const XMVECTORF32 s_Scale = { 31.f, 31.f, 31.f, 1.f };
|
||||||
XMU555 * __restrict dPtr = reinterpret_cast<XMU555*>(pDestination);
|
XMU555 * __restrict dPtr = reinterpret_cast<XMU555*>(pDestination);
|
||||||
for( size_t icount = 0; icount < ( size - sizeof(XMU555) + 1 ); icount += sizeof(XMU555) )
|
for( size_t icount = 0; icount < ( size - sizeof(XMU555) + 1 ); icount += sizeof(XMU555) )
|
||||||
{
|
{
|
||||||
@ -2373,7 +2400,7 @@ bool _StoreScanline( LPVOID pDestination, size_t size, DXGI_FORMAT format,
|
|||||||
case DXGI_FORMAT_B4G4R4A4_UNORM:
|
case DXGI_FORMAT_B4G4R4A4_UNORM:
|
||||||
if ( size >= sizeof(XMUNIBBLE4) )
|
if ( size >= sizeof(XMUNIBBLE4) )
|
||||||
{
|
{
|
||||||
static XMVECTORF32 s_Scale = { 15.f, 15.f, 15.f, 15.f };
|
static const XMVECTORF32 s_Scale = { 15.f, 15.f, 15.f, 15.f };
|
||||||
XMUNIBBLE4 * __restrict dPtr = reinterpret_cast<XMUNIBBLE4*>(pDestination);
|
XMUNIBBLE4 * __restrict dPtr = reinterpret_cast<XMUNIBBLE4*>(pDestination);
|
||||||
for( size_t icount = 0; icount < ( size - sizeof(XMUNIBBLE4) + 1 ); icount += sizeof(XMUNIBBLE4) )
|
for( size_t icount = 0; icount < ( size - sizeof(XMUNIBBLE4) + 1 ); icount += sizeof(XMUNIBBLE4) )
|
||||||
{
|
{
|
||||||
@ -2643,7 +2670,7 @@ static inline XMVECTOR XMColorRGBToSRGB( FXMVECTOR rgb )
|
|||||||
|
|
||||||
_Use_decl_annotations_
|
_Use_decl_annotations_
|
||||||
bool _StoreScanlineLinear( LPVOID pDestination, size_t size, DXGI_FORMAT format,
|
bool _StoreScanlineLinear( LPVOID pDestination, size_t size, DXGI_FORMAT format,
|
||||||
XMVECTOR* pSource, size_t count, DWORD flags )
|
XMVECTOR* pSource, size_t count, DWORD flags, float threshold )
|
||||||
{
|
{
|
||||||
assert( pDestination && size > 0 );
|
assert( pDestination && size > 0 );
|
||||||
assert( pSource && count > 0 && (((uintptr_t)pSource & 0xF) == 0) );
|
assert( pSource && count > 0 && (((uintptr_t)pSource & 0xF) == 0) );
|
||||||
@ -2700,7 +2727,7 @@ bool _StoreScanlineLinear( LPVOID pDestination, size_t size, DXGI_FORMAT format,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return _StoreScanline( pDestination, size, format, pSource, count );
|
return _StoreScanline( pDestination, size, format, pSource, count, threshold );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -3016,9 +3043,276 @@ void _ConvertScanline( XMVECTOR* pBuffer, size_t count, DXGI_FORMAT outFormat, D
|
|||||||
|
|
||||||
// Handle conversion special cases
|
// Handle conversion special cases
|
||||||
DWORD diffFlags = in->flags ^ out->flags;
|
DWORD diffFlags = in->flags ^ out->flags;
|
||||||
if ( diffFlags != 0)
|
if ( diffFlags != 0 )
|
||||||
{
|
{
|
||||||
if ( out->flags & CONVF_UNORM )
|
static const XMVECTORF32 s_two = { 2.0f, 2.0f, 2.0f, 2.0f };
|
||||||
|
|
||||||
|
if ( diffFlags & CONVF_DEPTH )
|
||||||
|
{
|
||||||
|
if ( in->flags & CONVF_DEPTH )
|
||||||
|
{
|
||||||
|
// CONVF_DEPTH -> !CONVF_DEPTH
|
||||||
|
if ( in->flags & CONVF_STENCIL )
|
||||||
|
{
|
||||||
|
// Stencil -> Alpha
|
||||||
|
static const XMVECTORF32 S = { 1.f, 1.f, 1.f, 255.f };
|
||||||
|
|
||||||
|
if( out->flags & CONVF_UNORM )
|
||||||
|
{
|
||||||
|
// UINT -> UNORM
|
||||||
|
XMVECTOR* ptr = pBuffer;
|
||||||
|
for( size_t i=0; i < count; ++i )
|
||||||
|
{
|
||||||
|
XMVECTOR v = *ptr;
|
||||||
|
XMVECTOR v1 = XMVectorSplatY( v );
|
||||||
|
v1 = XMVectorClamp( v1, g_XMZero, S );
|
||||||
|
v1 = XMVectorDivide( v1, S );
|
||||||
|
v = XMVectorSelect( v1, v, g_XMSelect1110 );
|
||||||
|
*ptr++ = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( out->flags & CONVF_SNORM )
|
||||||
|
{
|
||||||
|
// UINT -> SNORM
|
||||||
|
XMVECTOR* ptr = pBuffer;
|
||||||
|
for( size_t i=0; i < count; ++i )
|
||||||
|
{
|
||||||
|
XMVECTOR v = *ptr;
|
||||||
|
XMVECTOR v1 = XMVectorSplatY( v );
|
||||||
|
v1 = XMVectorClamp( v1, g_XMZero, S );
|
||||||
|
v1 = XMVectorDivide( v1, S );
|
||||||
|
v1 = XMVectorMultiplyAdd( v1, s_two, g_XMNegativeOne );
|
||||||
|
v = XMVectorSelect( v1, v, g_XMSelect1110 );
|
||||||
|
*ptr++ = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
XMVECTOR* ptr = pBuffer;
|
||||||
|
for( size_t i=0; i < count; ++i )
|
||||||
|
{
|
||||||
|
XMVECTOR v = *ptr;
|
||||||
|
XMVECTOR v1 = XMVectorSplatY( v );
|
||||||
|
v = XMVectorSelect( v1, v, g_XMSelect1110 );
|
||||||
|
*ptr++ = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Depth -> RGB
|
||||||
|
if ( ( out->flags & CONVF_UNORM ) && ( in->flags & CONVF_FLOAT ) )
|
||||||
|
{
|
||||||
|
// Depth FLOAT -> UNORM
|
||||||
|
XMVECTOR* ptr = pBuffer;
|
||||||
|
for( size_t i=0; i < count; ++i )
|
||||||
|
{
|
||||||
|
XMVECTOR v = *ptr;
|
||||||
|
XMVECTOR v1 = XMVectorSaturate( v );
|
||||||
|
v1 = XMVectorSplatX( v1 );
|
||||||
|
v = XMVectorSelect( v, v1, g_XMSelect1110 );
|
||||||
|
*ptr++ = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( out->flags & CONVF_SNORM )
|
||||||
|
{
|
||||||
|
if ( in->flags & CONVF_UNORM )
|
||||||
|
{
|
||||||
|
// Depth UNORM -> SNORM
|
||||||
|
XMVECTOR* ptr = pBuffer;
|
||||||
|
for( size_t i=0; i < count; ++i )
|
||||||
|
{
|
||||||
|
XMVECTOR v = *ptr;
|
||||||
|
XMVECTOR v1 = XMVectorMultiplyAdd( v, s_two, g_XMNegativeOne );
|
||||||
|
v1 = XMVectorSplatX( v1 );
|
||||||
|
v = XMVectorSelect( v, v1, g_XMSelect1110 );
|
||||||
|
*ptr++ = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Depth FLOAT -> SNORM
|
||||||
|
XMVECTOR* ptr = pBuffer;
|
||||||
|
for( size_t i=0; i < count; ++i )
|
||||||
|
{
|
||||||
|
XMVECTOR v = *ptr;
|
||||||
|
XMVECTOR v1 = XMVectorClamp( v, g_XMNegativeOne, g_XMOne );
|
||||||
|
v1 = XMVectorSplatX( v1 );
|
||||||
|
v = XMVectorSelect( v, v1, g_XMSelect1110 );
|
||||||
|
*ptr++ = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
XMVECTOR* ptr = pBuffer;
|
||||||
|
for( size_t i=0; i < count; ++i )
|
||||||
|
{
|
||||||
|
XMVECTOR v = *ptr;
|
||||||
|
XMVECTOR v1 = XMVectorSplatX( v );
|
||||||
|
v = XMVectorSelect( v, v1, g_XMSelect1110 );
|
||||||
|
*ptr++ = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// !CONVF_DEPTH -> CONVF_DEPTH
|
||||||
|
|
||||||
|
// RGB -> Depth (red channel)
|
||||||
|
switch( flags & ( TEX_FILTER_RGB_COPY_RED | TEX_FILTER_RGB_COPY_GREEN | TEX_FILTER_RGB_COPY_BLUE ) )
|
||||||
|
{
|
||||||
|
case TEX_FILTER_RGB_COPY_GREEN:
|
||||||
|
{
|
||||||
|
XMVECTOR* ptr = pBuffer;
|
||||||
|
for( size_t i=0; i < count; ++i )
|
||||||
|
{
|
||||||
|
XMVECTOR v = *ptr;
|
||||||
|
XMVECTOR v1 = XMVectorSplatY( v );
|
||||||
|
v = XMVectorSelect( v, v1, g_XMSelect1000 );
|
||||||
|
*ptr++ = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TEX_FILTER_RGB_COPY_BLUE:
|
||||||
|
{
|
||||||
|
XMVECTOR* ptr = pBuffer;
|
||||||
|
for( size_t i=0; i < count; ++i )
|
||||||
|
{
|
||||||
|
XMVECTOR v = *ptr;
|
||||||
|
XMVECTOR v1 = XMVectorSplatZ( v );
|
||||||
|
v = XMVectorSelect( v, v1, g_XMSelect1000 );
|
||||||
|
*ptr++ = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if ( (in->flags & CONVF_UNORM) && ( (in->flags & CONVF_RGB_MASK) == (CONVF_R|CONVF_G|CONVF_B) ) )
|
||||||
|
{
|
||||||
|
XMVECTOR* ptr = pBuffer;
|
||||||
|
for( size_t i=0; i < count; ++i )
|
||||||
|
{
|
||||||
|
XMVECTOR v = *ptr;
|
||||||
|
XMVECTOR v1 = XMVector3Dot( v, g_Grayscale );
|
||||||
|
v = XMVectorSelect( v, v1, g_XMSelect1000 );
|
||||||
|
*ptr++ = v;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// fall-through
|
||||||
|
|
||||||
|
case TEX_FILTER_RGB_COPY_RED:
|
||||||
|
{
|
||||||
|
XMVECTOR* ptr = pBuffer;
|
||||||
|
for( size_t i=0; i < count; ++i )
|
||||||
|
{
|
||||||
|
XMVECTOR v = *ptr;
|
||||||
|
XMVECTOR v1 = XMVectorSplatX( v );
|
||||||
|
v = XMVectorSelect( v, v1, g_XMSelect1000 );
|
||||||
|
*ptr++ = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finialize type conversion for depth (red channel)
|
||||||
|
if ( out->flags & CONVF_UNORM )
|
||||||
|
{
|
||||||
|
if ( in->flags & CONVF_SNORM )
|
||||||
|
{
|
||||||
|
// SNORM -> UNORM
|
||||||
|
XMVECTOR* ptr = pBuffer;
|
||||||
|
for( size_t i=0; i < count; ++i )
|
||||||
|
{
|
||||||
|
XMVECTOR v = *ptr;
|
||||||
|
XMVECTOR v1 = XMVectorMultiplyAdd( v, g_XMOneHalf, g_XMOneHalf );
|
||||||
|
v = XMVectorSelect( v, v1, g_XMSelect1000 );
|
||||||
|
*ptr++ = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( in->flags & CONVF_FLOAT )
|
||||||
|
{
|
||||||
|
// FLOAT -> UNORM
|
||||||
|
XMVECTOR* ptr = pBuffer;
|
||||||
|
for( size_t i=0; i < count; ++i )
|
||||||
|
{
|
||||||
|
XMVECTOR v = *ptr;
|
||||||
|
XMVECTOR v1 = XMVectorSaturate( v );
|
||||||
|
v = XMVectorSelect( v, v1, g_XMSelect1000 );
|
||||||
|
*ptr++ = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( out->flags & CONVF_STENCIL )
|
||||||
|
{
|
||||||
|
// Alpha -> Stencil (green channel)
|
||||||
|
static const XMVECTORU32 select0100 = { XM_SELECT_0, XM_SELECT_1, XM_SELECT_0, XM_SELECT_0 };
|
||||||
|
static const XMVECTORF32 S = { 255.f, 255.f, 255.f, 255.f };
|
||||||
|
|
||||||
|
if ( in->flags & CONVF_UNORM )
|
||||||
|
{
|
||||||
|
// UNORM -> UINT
|
||||||
|
XMVECTOR* ptr = pBuffer;
|
||||||
|
for( size_t i=0; i < count; ++i )
|
||||||
|
{
|
||||||
|
XMVECTOR v = *ptr;
|
||||||
|
XMVECTOR v1 = XMVectorMultiply( v, S );
|
||||||
|
v1 = XMVectorSplatW( v1 );
|
||||||
|
v = XMVectorSelect( v, v1, select0100 );
|
||||||
|
*ptr++ = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( in->flags & CONVF_SNORM )
|
||||||
|
{
|
||||||
|
// SNORM -> UINT
|
||||||
|
XMVECTOR* ptr = pBuffer;
|
||||||
|
for( size_t i=0; i < count; ++i )
|
||||||
|
{
|
||||||
|
XMVECTOR v = *ptr;
|
||||||
|
XMVECTOR v1 = XMVectorMultiplyAdd( v, g_XMOneHalf, g_XMOneHalf );
|
||||||
|
v1 = XMVectorMultiply( v1, S );
|
||||||
|
v1 = XMVectorSplatW( v1 );
|
||||||
|
v = XMVectorSelect( v, v1, select0100 );
|
||||||
|
*ptr++ = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
XMVECTOR* ptr = pBuffer;
|
||||||
|
for( size_t i=0; i < count; ++i )
|
||||||
|
{
|
||||||
|
XMVECTOR v = *ptr;
|
||||||
|
XMVECTOR v1 = XMVectorSplatW( v );
|
||||||
|
v = XMVectorSelect( v, v1, select0100 );
|
||||||
|
*ptr++ = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( out->flags & CONVF_DEPTH )
|
||||||
|
{
|
||||||
|
// CONVF_DEPTH -> CONVF_DEPTH
|
||||||
|
if ( diffFlags & CONVF_FLOAT )
|
||||||
|
{
|
||||||
|
if ( in->flags & CONVF_FLOAT )
|
||||||
|
{
|
||||||
|
// FLOAT -> UNORM depth, preserve stencil
|
||||||
|
XMVECTOR* ptr = pBuffer;
|
||||||
|
for( size_t i=0; i < count; ++i )
|
||||||
|
{
|
||||||
|
XMVECTOR v = *ptr;
|
||||||
|
XMVECTOR v1 = XMVectorSaturate( v );
|
||||||
|
v = XMVectorSelect( v, v1, g_XMSelect1000 );
|
||||||
|
*ptr++ = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( out->flags & CONVF_UNORM )
|
||||||
{
|
{
|
||||||
if ( in->flags & CONVF_SNORM )
|
if ( in->flags & CONVF_SNORM )
|
||||||
{
|
{
|
||||||
@ -3046,12 +3340,11 @@ void _ConvertScanline( XMVECTOR* pBuffer, size_t count, DXGI_FORMAT outFormat, D
|
|||||||
if ( in->flags & CONVF_UNORM )
|
if ( in->flags & CONVF_UNORM )
|
||||||
{
|
{
|
||||||
// UNORM -> SNORM
|
// UNORM -> SNORM
|
||||||
static XMVECTORF32 two = { 2.0f, 2.0f, 2.0f, 2.0f };
|
|
||||||
XMVECTOR* ptr = pBuffer;
|
XMVECTOR* ptr = pBuffer;
|
||||||
for( size_t i=0; i < count; ++i )
|
for( size_t i=0; i < count; ++i )
|
||||||
{
|
{
|
||||||
XMVECTOR v = *ptr;
|
XMVECTOR v = *ptr;
|
||||||
*ptr++ = XMVectorMultiplyAdd( v, two, g_XMNegativeOne );
|
*ptr++ = XMVectorMultiplyAdd( v, s_two, g_XMNegativeOne );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( in->flags & CONVF_FLOAT )
|
else if ( in->flags & CONVF_FLOAT )
|
||||||
@ -3073,11 +3366,54 @@ void _ConvertScanline( XMVECTOR* pBuffer, size_t count, DXGI_FORMAT outFormat, D
|
|||||||
if ( ((out->flags & CONVF_RGBA_MASK) == CONVF_A) && !(in->flags & CONVF_A) )
|
if ( ((out->flags & CONVF_RGBA_MASK) == CONVF_A) && !(in->flags & CONVF_A) )
|
||||||
{
|
{
|
||||||
// !CONVF_A -> A format
|
// !CONVF_A -> A format
|
||||||
XMVECTOR* ptr = pBuffer;
|
switch( flags & ( TEX_FILTER_RGB_COPY_RED | TEX_FILTER_RGB_COPY_GREEN | TEX_FILTER_RGB_COPY_BLUE ) )
|
||||||
for( size_t i=0; i < count; ++i )
|
|
||||||
{
|
{
|
||||||
XMVECTOR v = *ptr;
|
case TEX_FILTER_RGB_COPY_GREEN:
|
||||||
*ptr++ = XMVectorSplatX( v );
|
{
|
||||||
|
XMVECTOR* ptr = pBuffer;
|
||||||
|
for( size_t i=0; i < count; ++i )
|
||||||
|
{
|
||||||
|
XMVECTOR v = *ptr;
|
||||||
|
*ptr++ = XMVectorSplatY( v );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TEX_FILTER_RGB_COPY_BLUE:
|
||||||
|
{
|
||||||
|
XMVECTOR* ptr = pBuffer;
|
||||||
|
for( size_t i=0; i < count; ++i )
|
||||||
|
{
|
||||||
|
XMVECTOR v = *ptr;
|
||||||
|
*ptr++ = XMVectorSplatZ( v );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if ( (in->flags & CONVF_UNORM) && ( (in->flags & CONVF_RGB_MASK) == (CONVF_R|CONVF_G|CONVF_B) ) )
|
||||||
|
{
|
||||||
|
XMVECTOR* ptr = pBuffer;
|
||||||
|
for( size_t i=0; i < count; ++i )
|
||||||
|
{
|
||||||
|
XMVECTOR v = *ptr;
|
||||||
|
*ptr++ = XMVector3Dot( v, g_Grayscale );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// fall-through
|
||||||
|
|
||||||
|
case TEX_FILTER_RGB_COPY_RED:
|
||||||
|
{
|
||||||
|
XMVECTOR* ptr = pBuffer;
|
||||||
|
for( size_t i=0; i < count; ++i )
|
||||||
|
{
|
||||||
|
XMVECTOR v = *ptr;
|
||||||
|
*ptr++ = XMVectorSplatX( v );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( ((in->flags & CONVF_RGBA_MASK) == CONVF_A) && !(out->flags & CONVF_A) )
|
else if ( ((in->flags & CONVF_RGBA_MASK) == CONVF_A) && !(out->flags & CONVF_A) )
|
||||||
@ -3122,10 +3458,6 @@ void _ConvertScanline( XMVECTOR* pBuffer, size_t count, DXGI_FORMAT outFormat, D
|
|||||||
// RGB format -> R format
|
// RGB format -> R format
|
||||||
switch( flags & ( TEX_FILTER_RGB_COPY_RED | TEX_FILTER_RGB_COPY_GREEN | TEX_FILTER_RGB_COPY_BLUE ) )
|
switch( flags & ( TEX_FILTER_RGB_COPY_RED | TEX_FILTER_RGB_COPY_GREEN | TEX_FILTER_RGB_COPY_BLUE ) )
|
||||||
{
|
{
|
||||||
case TEX_FILTER_RGB_COPY_RED:
|
|
||||||
// Leave data unchanged and the store will handle this...
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TEX_FILTER_RGB_COPY_GREEN:
|
case TEX_FILTER_RGB_COPY_GREEN:
|
||||||
{
|
{
|
||||||
XMVECTOR* ptr = pBuffer;
|
XMVECTOR* ptr = pBuffer;
|
||||||
@ -3151,6 +3483,7 @@ void _ConvertScanline( XMVECTOR* pBuffer, size_t count, DXGI_FORMAT outFormat, D
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
if ( in->flags & CONVF_UNORM )
|
||||||
{
|
{
|
||||||
XMVECTOR* ptr = pBuffer;
|
XMVECTOR* ptr = pBuffer;
|
||||||
for( size_t i=0; i < count; ++i )
|
for( size_t i=0; i < count; ++i )
|
||||||
@ -3159,7 +3492,13 @@ void _ConvertScanline( XMVECTOR* pBuffer, size_t count, DXGI_FORMAT outFormat, D
|
|||||||
XMVECTOR v1 = XMVector3Dot( v, g_Grayscale );
|
XMVECTOR v1 = XMVector3Dot( v, g_Grayscale );
|
||||||
*ptr++ = XMVectorSelect( v, v1, g_XMSelect1110 );
|
*ptr++ = XMVectorSelect( v, v1, g_XMSelect1110 );
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fall-through
|
||||||
|
|
||||||
|
case TEX_FILTER_RGB_COPY_RED:
|
||||||
|
// Leave data unchanged and the store will handle this...
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -182,7 +182,7 @@ namespace DirectX
|
|||||||
|
|
||||||
_Success_(return != false)
|
_Success_(return != false)
|
||||||
bool __cdecl _StoreScanlineLinear( LPVOID pDestination, _In_ size_t size, _In_ DXGI_FORMAT format,
|
bool __cdecl _StoreScanlineLinear( LPVOID pDestination, _In_ size_t size, _In_ DXGI_FORMAT format,
|
||||||
_Inout_updates_all_(count) XMVECTOR* pSource, _In_ size_t count, _In_ DWORD flags );
|
_Inout_updates_all_(count) XMVECTOR* pSource, _In_ size_t count, _In_ DWORD flags, _In_ float threshold = 0 );
|
||||||
|
|
||||||
_Success_(return != false)
|
_Success_(return != false)
|
||||||
bool __cdecl _StoreScanlineDither( LPVOID pDestination, _In_ size_t size, _In_ DXGI_FORMAT format,
|
bool __cdecl _StoreScanlineDither( LPVOID pDestination, _In_ size_t size, _In_ DXGI_FORMAT format,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user