Skip to content

Commit 0678c2b

Browse files
walbourn_cpwalbourn_cp
walbourn_cp
authored and
walbourn_cp
committed
DirectxTex: Need to slightly bias results floating-point error introduced by TRIANGLE filter
- Avoids problem with harshly quantized formats like 2-bit alpha - Defaults to TRIANGLE filter for non-pow-2 volume maps
1 parent 190e230 commit 0678c2b

File tree

2 files changed

+69
-4
lines changed

2 files changed

+69
-4
lines changed

DirectXTex/DirectXTexMipmaps.cpp

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1245,7 +1245,30 @@ static HRESULT _Generate2DMipsTriangleFilter( _In_ size_t levels, _In_ DWORD fil
12451245

12461246
if ( !rowAcc->remaining )
12471247
{
1248-
if ( !_StoreScanlineLinear( pDest + (dest->rowPitch * v), dest->rowPitch, dest->format, rowAcc->scanline.get(), dest->width, filter ) )
1248+
XMVECTOR* pAccSrc = rowAcc->scanline.get();
1249+
if ( !pAccSrc )
1250+
return E_POINTER;
1251+
1252+
switch( dest->format )
1253+
{
1254+
case DXGI_FORMAT_R10G10B10A2_UNORM:
1255+
case DXGI_FORMAT_R10G10B10A2_UINT:
1256+
{
1257+
// Need to slightly bias results for floating-point error accumulation which can
1258+
// be visible with harshly quantized values
1259+
static const XMVECTORF32 Bias = { 0.f, 0.f, 0.f, 0.1f };
1260+
1261+
XMVECTOR* ptr = pAccSrc;
1262+
for( size_t i=0; i < dest->width; ++i, ++ptr )
1263+
{
1264+
*ptr = XMVectorAdd( *ptr, Bias );
1265+
}
1266+
}
1267+
break;
1268+
}
1269+
1270+
// This performs any required clamping
1271+
if ( !_StoreScanlineLinear( pDest + (dest->rowPitch * v), dest->rowPitch, dest->format, pAccSrc, dest->width, filter ) )
12491272
return E_FAIL;
12501273

12511274
// Put row on freelist to reuse it's allocated scanline
@@ -2402,6 +2425,25 @@ static HRESULT _Generate3DMipsTriangleFilter( _In_ size_t depth, _In_ size_t lev
24022425

24032426
for( size_t h = 0; h < nheight; ++h )
24042427
{
2428+
switch( dest->format )
2429+
{
2430+
case DXGI_FORMAT_R10G10B10A2_UNORM:
2431+
case DXGI_FORMAT_R10G10B10A2_UINT:
2432+
{
2433+
// Need to slightly bias results for floating-point error accumulation which can
2434+
// be visible with harshly quantized values
2435+
static const XMVECTORF32 Bias = { 0.f, 0.f, 0.f, 0.1f };
2436+
2437+
XMVECTOR* ptr = pAccSrc;
2438+
for( size_t i=0; i < dest->width; ++i, ++ptr )
2439+
{
2440+
*ptr = XMVectorAdd( *ptr, Bias );
2441+
}
2442+
}
2443+
break;
2444+
}
2445+
2446+
// This performs any required clamping
24052447
if ( !_StoreScanlineLinear( pDest, dest->rowPitch, dest->format, pAccSrc, dest->width, filter ) )
24062448
return E_FAIL;
24072449

@@ -2845,7 +2887,7 @@ HRESULT GenerateMipMaps3D( const Image* baseImages, size_t depth, DWORD filter,
28452887
if ( !filter_select )
28462888
{
28472889
// Default filter choice
2848-
filter_select = ( ispow2(width) && ispow2(height) && ispow2(depth) ) ? TEX_FILTER_BOX : TEX_FILTER_LINEAR;
2890+
filter_select = ( ispow2(width) && ispow2(height) && ispow2(depth) ) ? TEX_FILTER_BOX : TEX_FILTER_TRIANGLE;
28492891
}
28502892

28512893
switch( filter_select )
@@ -2953,7 +2995,7 @@ HRESULT GenerateMipMaps3D( const Image* srcImages, size_t nimages, const TexMeta
29532995
if ( !filter_select )
29542996
{
29552997
// Default filter choice
2956-
filter_select = ( ispow2(metadata.width) && ispow2(metadata.height) && ispow2(metadata.depth) ) ? TEX_FILTER_BOX : TEX_FILTER_LINEAR;
2998+
filter_select = ( ispow2(metadata.width) && ispow2(metadata.height) && ispow2(metadata.depth) ) ? TEX_FILTER_BOX : TEX_FILTER_TRIANGLE;
29572999
}
29583000

29593001
switch( filter_select )

DirectXTex/DirectXTexResize.cpp

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -723,7 +723,30 @@ static HRESULT _ResizeTriangleFilter( _In_ const Image& srcImage, _In_ DWORD fil
723723

724724
if ( !rowAcc->remaining )
725725
{
726-
if ( !_StoreScanlineLinear( pDest + (destImage.rowPitch * v), destImage.rowPitch, destImage.format, rowAcc->scanline.get(), destImage.width, filter ) )
726+
XMVECTOR* pAccSrc = rowAcc->scanline.get();
727+
if ( !pAccSrc )
728+
return E_POINTER;
729+
730+
switch( destImage.format )
731+
{
732+
case DXGI_FORMAT_R10G10B10A2_UNORM:
733+
case DXGI_FORMAT_R10G10B10A2_UINT:
734+
{
735+
// Need to slightly bias results for floating-point error accumulation which can
736+
// be visible with harshly quantized values
737+
static const XMVECTORF32 Bias = { 0.f, 0.f, 0.f, 0.1f };
738+
739+
XMVECTOR* ptr = pAccSrc;
740+
for( size_t i=0; i < destImage.width; ++i, ++ptr )
741+
{
742+
*ptr = XMVectorAdd( *ptr, Bias );
743+
}
744+
}
745+
break;
746+
}
747+
748+
// This performs any required clamping
749+
if ( !_StoreScanlineLinear( pDest + (destImage.rowPitch * v), destImage.rowPitch, destImage.format, pAccSrc, destImage.width, filter ) )
727750
return E_FAIL;
728751

729752
// Put row on freelist to reuse it's allocated scanline

0 commit comments

Comments
 (0)