@@ -192,6 +192,30 @@ namespace
192192 const XMVECTORF32 g_HalfMin = { { { -65504 .f , -65504 .f , -65504 .f , -65504 .f } } };
193193 const XMVECTORF32 g_HalfMax = { { { 65504 .f , 65504 .f , 65504 .f , 65504 .f } } };
194194 const XMVECTORF32 g_8BitBias = { { { 0 .5f / 255 .f , 0 .5f / 255 .f , 0 .5f / 255 .f , 0 .5f / 255 .f } } };
195+
196+ inline void SanitizeFloat16 (XMVECTOR& v, DWORD flags)
197+ {
198+ // Convert NaNs to 0.0f
199+ if (!(flags & TEX_FILTER_FLOAT_KEEP_NANS))
200+ v = XMVectorSelect (XMVectorZero (), v, XMVectorIsNaN (v));
201+
202+ if (!(flags & TEX_FILTER_FLOAT_SATURATE_TO_INF))
203+ v = XMVectorClamp (v, g_HalfMin, g_HalfMax);
204+ }
205+
206+ inline void SanitizeFloat16 (float & v, DWORD flags)
207+ {
208+ if (std::isnan (v))
209+ {
210+ if (!(flags & TEX_FILTER_FLOAT_KEEP_NANS))
211+ v = 0 .0f ;
212+ }
213+ else
214+ {
215+ if (!(flags & TEX_FILTER_FLOAT_SATURATE_TO_INF))
216+ v = std::min (std::max (v, -65504 .f ), 65504 .f );
217+ }
218+ }
195219}
196220
197221// -------------------------------------------------------------------------------------
@@ -1609,7 +1633,8 @@ bool DirectX::_StoreScanline(
16091633 DXGI_FORMAT format,
16101634 const XMVECTOR* pSource,
16111635 size_t count,
1612- float threshold)
1636+ float threshold,
1637+ DWORD flags)
16131638{
16141639 assert (pDestination && size > 0 );
16151640 assert (pSource && count > 0 && (((uintptr_t )pSource & 0xF ) == 0 ));
@@ -1649,7 +1674,7 @@ bool DirectX::_StoreScanline(
16491674 {
16501675 if (sPtr >= ePtr) break ;
16511676 XMVECTOR v = *sPtr ++;
1652- v = XMVectorClamp (v, g_HalfMin, g_HalfMax );
1677+ SanitizeFloat16 (v, flags );
16531678 XMStoreHalf4 (dPtr++, v);
16541679 }
16551680 return true ;
@@ -1743,7 +1768,7 @@ bool DirectX::_StoreScanline(
17431768 {
17441769 if (sPtr >= ePtr) break ;
17451770 XMVECTOR v = *sPtr ++;
1746- v = XMVectorClamp (v, g_HalfMin, g_HalfMax );
1771+ SanitizeFloat16 (v, flags );
17471772 XMStoreHalf2 (dPtr++, v);
17481773 }
17491774 return true ;
@@ -1842,7 +1867,7 @@ bool DirectX::_StoreScanline(
18421867 {
18431868 if (sPtr >= ePtr) break ;
18441869 float v = XMVectorGetX (*sPtr ++);
1845- v = std::max< float >(std::min< float >( v, 65504 . f ), - 65504 . f );
1870+ SanitizeFloat16 ( v, flags );
18461871 *(dPtr++) = XMConvertFloatToHalf (v);
18471872 }
18481873 return true ;
@@ -2699,7 +2724,7 @@ bool DirectX::_StoreScanlineLinear(
26992724 }
27002725 }
27012726
2702- return _StoreScanline (pDestination, size, format, pSource, count, threshold);
2727+ return _StoreScanline (pDestination, size, format, pSource, count, threshold, flags );
27032728}
27042729
27052730
@@ -4542,7 +4567,7 @@ namespace
45424567
45434568 _ConvertScanline (scanline.get (), width, destImage.format , srcImage.format , filter);
45444569
4545- if (!_StoreScanline (pDest, destImage.rowPitch , destImage.format , scanline.get (), width, threshold))
4570+ if (!_StoreScanline (pDest, destImage.rowPitch , destImage.format , scanline.get (), width, threshold, filter ))
45464571 return E_FAIL;
45474572
45484573 pSrc += srcImage.rowPitch ;
0 commit comments