DirectXTex: Convert threshold parameter was not being used correctly

Convert needs to use non-WIC paths for -sepalpha cases
This commit is contained in:
walbourn_cp 2013-06-07 18:07:08 -07:00
parent 76bd58ecb0
commit 0a6e75fe5a
3 changed files with 40 additions and 26 deletions

View File

@ -890,10 +890,10 @@ bool _LoadScanline( XMVECTOR* pDestination, size_t count,
return false; return false;
case DXGI_FORMAT_R8_SNORM: case DXGI_FORMAT_R8_SNORM:
if ( size >= sizeof(char) ) if ( size >= sizeof(int8_t) )
{ {
const char * __restrict sPtr = reinterpret_cast<const char*>(pSource); const int8_t * __restrict sPtr = reinterpret_cast<const int8_t*>(pSource);
for( size_t icount = 0; icount < size; icount += sizeof(char) ) for( size_t icount = 0; icount < size; icount += sizeof(int8_t) )
{ {
if ( dPtr >= ePtr ) break; if ( dPtr >= ePtr ) break;
*(dPtr++) = XMVectorSet( static_cast<float>(*sPtr++) / 127.f, 0.f, 0.f, 1.f ); *(dPtr++) = XMVectorSet( static_cast<float>(*sPtr++) / 127.f, 0.f, 0.f, 1.f );
@ -903,10 +903,10 @@ bool _LoadScanline( XMVECTOR* pDestination, size_t count,
return false; return false;
case DXGI_FORMAT_R8_SINT: case DXGI_FORMAT_R8_SINT:
if ( size >= sizeof(char) ) if ( size >= sizeof(int8_t) )
{ {
const char * __restrict sPtr = reinterpret_cast<const char*>(pSource); const int8_t * __restrict sPtr = reinterpret_cast<const int8_t*>(pSource);
for( size_t icount = 0; icount < size; icount += sizeof(char) ) for( size_t icount = 0; icount < size; icount += sizeof(int8_t) )
{ {
if ( dPtr >= ePtr ) break; if ( dPtr >= ePtr ) break;
*(dPtr++) = XMVectorSet( static_cast<float>(*sPtr++), 0.f, 0.f, 1.f ); *(dPtr++) = XMVectorSet( static_cast<float>(*sPtr++), 0.f, 0.f, 1.f );
@ -1093,6 +1093,10 @@ bool _LoadScanline( XMVECTOR* pDestination, size_t count,
} }
} }
#undef LOAD_SCANLINE
#undef LOAD_SCANLINE3
#undef LOAD_SCANLINE2
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Stores an image row from standard RGBA XMVECTOR (aligned) array // Stores an image row from standard RGBA XMVECTOR (aligned) array
@ -1111,7 +1115,7 @@ bool _LoadScanline( XMVECTOR* pDestination, size_t count,
_Use_decl_annotations_ _Use_decl_annotations_
bool _StoreScanline( LPVOID pDestination, size_t size, DXGI_FORMAT format, bool _StoreScanline( LPVOID pDestination, size_t size, DXGI_FORMAT format,
const XMVECTOR* pSource, size_t count ) const XMVECTOR* pSource, size_t count, 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) );
@ -1333,10 +1337,10 @@ bool _StoreScanline( LPVOID pDestination, size_t size, DXGI_FORMAT format,
case DXGI_FORMAT_D16_UNORM: case DXGI_FORMAT_D16_UNORM:
case DXGI_FORMAT_R16_UNORM: case DXGI_FORMAT_R16_UNORM:
if ( size >= sizeof(int16_t) ) if ( size >= sizeof(uint16_t) )
{ {
int16_t * __restrict dPtr = reinterpret_cast<int16_t*>(pDestination); uint16_t * __restrict dPtr = reinterpret_cast<uint16_t*>(pDestination);
for( size_t icount = 0; icount < size; icount += sizeof(int16_t) ) for( size_t icount = 0; icount < size; icount += sizeof(uint16_t) )
{ {
if ( sPtr >= ePtr ) break; if ( sPtr >= ePtr ) break;
float v = XMVectorGetX( *sPtr++ ); float v = XMVectorGetX( *sPtr++ );
@ -1417,29 +1421,29 @@ bool _StoreScanline( LPVOID pDestination, size_t size, DXGI_FORMAT format,
return true; return true;
case DXGI_FORMAT_R8_SNORM: case DXGI_FORMAT_R8_SNORM:
if ( size >= sizeof(char) ) if ( size >= sizeof(int8_t) )
{ {
char * __restrict dPtr = reinterpret_cast<char*>(pDestination); int8_t * __restrict dPtr = reinterpret_cast<int8_t*>(pDestination);
for( size_t icount = 0; icount < size; icount += sizeof(char) ) for( size_t icount = 0; icount < size; icount += sizeof(int8_t) )
{ {
if ( sPtr >= ePtr ) break; if ( sPtr >= ePtr ) break;
float v = XMVectorGetX( *sPtr++ ); float v = XMVectorGetX( *sPtr++ );
v = std::max<float>( std::min<float>( v, 1.f ), -1.f ); v = std::max<float>( std::min<float>( v, 1.f ), -1.f );
*(dPtr++) = static_cast<char>( v * 127.f ); *(dPtr++) = static_cast<int8_t>( v * 127.f );
} }
} }
return true; return true;
case DXGI_FORMAT_R8_SINT: case DXGI_FORMAT_R8_SINT:
if ( size >= sizeof(char) ) if ( size >= sizeof(int8_t) )
{ {
char * __restrict dPtr = reinterpret_cast<char*>(pDestination); int8_t * __restrict dPtr = reinterpret_cast<int8_t*>(pDestination);
for( size_t icount = 0; icount < size; icount += sizeof(char) ) for( size_t icount = 0; icount < size; icount += sizeof(int8_t) )
{ {
if ( sPtr >= ePtr ) break; if ( sPtr >= ePtr ) break;
float v = XMVectorGetX( *sPtr++ ); float v = XMVectorGetX( *sPtr++ );
v = std::max<float>( std::min<float>( v, 127.f ), -127.f ); v = std::max<float>( std::min<float>( v, 127.f ), -127.f );
*(dPtr++) = static_cast<char>( v ); *(dPtr++) = static_cast<int8_t>( v );
} }
} }
return true; return true;
@ -1578,7 +1582,9 @@ bool _StoreScanline( LPVOID pDestination, size_t size, DXGI_FORMAT format,
if ( sPtr >= ePtr ) break; if ( sPtr >= ePtr ) break;
XMVECTOR v = XMVectorSwizzle<2, 1, 0, 3>( *sPtr++ ); XMVECTOR v = XMVectorSwizzle<2, 1, 0, 3>( *sPtr++ );
v = XMVectorMultiply( v, s_Scale ); v = XMVectorMultiply( v, s_Scale );
XMStoreU555( dPtr++, v ); XMStoreU555( dPtr, v );
dPtr->w = ( XMVectorGetW( v ) > threshold ) ? 1 : 0;
++dPtr;
} }
} }
return true; return true;
@ -1635,6 +1641,8 @@ bool _StoreScanline( LPVOID pDestination, size_t size, DXGI_FORMAT format,
} }
} }
#undef STORE_SCANLINE
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Convert DXGI image to/from GUID_WICPixelFormat128bppRGBAFloat (no range conversions) // Convert DXGI image to/from GUID_WICPixelFormat128bppRGBAFloat (no range conversions)
@ -2516,6 +2524,12 @@ static inline bool _UseWICConversion( _In_ DWORD filter, _In_ DXGI_FORMAT sforma
return true; return true;
} }
if ( filter & TEX_FILTER_SEPARATE_ALPHA )
{
// Alpha is not premultiplied, so use non-WIC code paths
return false;
}
// Check for special cases // Check for special cases
switch ( sformat ) switch ( sformat )
{ {
@ -2620,7 +2634,7 @@ static HRESULT _ConvertUsingWIC( _In_ const Image& srcImage, _In_ const WICPixel
if ( FAILED(hr) ) if ( FAILED(hr) )
return hr; return hr;
hr = FC->Initialize( source.Get(), targetGUID, _GetWICDither( filter ), 0, threshold, WICBitmapPaletteTypeCustom ); hr = FC->Initialize( source.Get(), targetGUID, _GetWICDither( filter ), 0, threshold * 100.f, WICBitmapPaletteTypeCustom );
if ( FAILED(hr) ) if ( FAILED(hr) )
return hr; return hr;
@ -2635,7 +2649,7 @@ static HRESULT _ConvertUsingWIC( _In_ const Image& srcImage, _In_ const WICPixel
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Convert the source image (not using WIC) // Convert the source image (not using WIC)
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
static HRESULT _Convert( _In_ const Image& srcImage, _In_ DWORD filter, _In_ const Image& destImage ) static HRESULT _Convert( _In_ const Image& srcImage, _In_ DWORD filter, _In_ const Image& destImage, _In_ float threshold )
{ {
assert( srcImage.width == destImage.width ); assert( srcImage.width == destImage.width );
assert( srcImage.height == destImage.height ); assert( srcImage.height == destImage.height );
@ -2656,7 +2670,7 @@ static HRESULT _Convert( _In_ const Image& srcImage, _In_ DWORD filter, _In_ con
_ConvertScanline( scanline.get(), srcImage.width, destImage.format, srcImage.format, filter ); _ConvertScanline( scanline.get(), srcImage.width, destImage.format, srcImage.format, filter );
if ( !_StoreScanline( pDest, destImage.rowPitch, destImage.format, scanline.get(), srcImage.width ) ) if ( !_StoreScanline( pDest, destImage.rowPitch, destImage.format, scanline.get(), srcImage.width, threshold ) )
return E_FAIL; return E_FAIL;
pSrc += srcImage.rowPitch; pSrc += srcImage.rowPitch;
@ -2711,7 +2725,7 @@ HRESULT Convert( const Image& srcImage, DXGI_FORMAT format, DWORD filter, float
} }
else else
{ {
hr = _Convert( srcImage, filter, *rimage ); hr = _Convert( srcImage, filter, *rimage, threshold );
} }
if ( FAILED(hr) ) if ( FAILED(hr) )
@ -2795,7 +2809,7 @@ HRESULT Convert( const Image* srcImages, size_t nimages, const TexMetadata& meta
} }
else else
{ {
hr = _Convert( src, filter, dst ); hr = _Convert( src, filter, dst, threshold );
} }
if ( FAILED(hr) ) if ( FAILED(hr) )

View File

@ -191,7 +191,7 @@ namespace DirectX
_Success_(return != false) _Success_(return != false)
bool _StoreScanline( LPVOID pDestination, _In_ size_t size, _In_ DXGI_FORMAT format, bool _StoreScanline( LPVOID pDestination, _In_ size_t size, _In_ DXGI_FORMAT format,
_In_reads_(count) const XMVECTOR* pSource, _In_ size_t count); _In_reads_(count) const XMVECTOR* pSource, _In_ size_t count, _In_ float threshold = 0 );
_Success_(return != false) _Success_(return != false)
bool _StoreScanlineLinear( LPVOID pDestination, _In_ size_t size, _In_ DXGI_FORMAT format, bool _StoreScanlineLinear( LPVOID pDestination, _In_ size_t size, _In_ DXGI_FORMAT format,

View File

@ -826,7 +826,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
goto LError; goto LError;
} }
hr = Convert( image->GetImages(), image->GetImageCount(), image->GetMetadata(), tformat, dwFilter | dwSRGB, 0.5f, *timage ); hr = Convert( image->GetImages(), image->GetImageCount(), image->GetMetadata(), tformat, dwFilter | dwFilterOpts | dwSRGB, 0.5f, *timage );
if ( FAILED(hr) ) if ( FAILED(hr) )
{ {
wprintf( L" FAILED [convert] (%x)\n", hr); wprintf( L" FAILED [convert] (%x)\n", hr);