From 0678c2b5f9c2ab739bcfc3960397ee7274386133 Mon Sep 17 00:00:00 2001 From: walbourn_cp Date: Sat, 15 Jun 2013 11:55:07 -0700 Subject: [PATCH] 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 --- DirectXTex/DirectXTexMipmaps.cpp | 48 ++++++++++++++++++++++++++++++-- DirectXTex/DirectXTexResize.cpp | 25 ++++++++++++++++- 2 files changed, 69 insertions(+), 4 deletions(-) diff --git a/DirectXTex/DirectXTexMipmaps.cpp b/DirectXTex/DirectXTexMipmaps.cpp index 379a662..356a270 100644 --- a/DirectXTex/DirectXTexMipmaps.cpp +++ b/DirectXTex/DirectXTexMipmaps.cpp @@ -1245,7 +1245,30 @@ static HRESULT _Generate2DMipsTriangleFilter( _In_ size_t levels, _In_ DWORD fil if ( !rowAcc->remaining ) { - if ( !_StoreScanlineLinear( pDest + (dest->rowPitch * v), dest->rowPitch, dest->format, rowAcc->scanline.get(), dest->width, filter ) ) + XMVECTOR* pAccSrc = rowAcc->scanline.get(); + if ( !pAccSrc ) + return E_POINTER; + + switch( dest->format ) + { + case DXGI_FORMAT_R10G10B10A2_UNORM: + case DXGI_FORMAT_R10G10B10A2_UINT: + { + // Need to slightly bias results for floating-point error accumulation which can + // be visible with harshly quantized values + static const XMVECTORF32 Bias = { 0.f, 0.f, 0.f, 0.1f }; + + XMVECTOR* ptr = pAccSrc; + for( size_t i=0; i < dest->width; ++i, ++ptr ) + { + *ptr = XMVectorAdd( *ptr, Bias ); + } + } + break; + } + + // This performs any required clamping + if ( !_StoreScanlineLinear( pDest + (dest->rowPitch * v), dest->rowPitch, dest->format, pAccSrc, dest->width, filter ) ) return E_FAIL; // 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 for( size_t h = 0; h < nheight; ++h ) { + switch( dest->format ) + { + case DXGI_FORMAT_R10G10B10A2_UNORM: + case DXGI_FORMAT_R10G10B10A2_UINT: + { + // Need to slightly bias results for floating-point error accumulation which can + // be visible with harshly quantized values + static const XMVECTORF32 Bias = { 0.f, 0.f, 0.f, 0.1f }; + + XMVECTOR* ptr = pAccSrc; + for( size_t i=0; i < dest->width; ++i, ++ptr ) + { + *ptr = XMVectorAdd( *ptr, Bias ); + } + } + break; + } + + // This performs any required clamping if ( !_StoreScanlineLinear( pDest, dest->rowPitch, dest->format, pAccSrc, dest->width, filter ) ) return E_FAIL; @@ -2845,7 +2887,7 @@ HRESULT GenerateMipMaps3D( const Image* baseImages, size_t depth, DWORD filter, if ( !filter_select ) { // Default filter choice - filter_select = ( ispow2(width) && ispow2(height) && ispow2(depth) ) ? TEX_FILTER_BOX : TEX_FILTER_LINEAR; + filter_select = ( ispow2(width) && ispow2(height) && ispow2(depth) ) ? TEX_FILTER_BOX : TEX_FILTER_TRIANGLE; } switch( filter_select ) @@ -2953,7 +2995,7 @@ HRESULT GenerateMipMaps3D( const Image* srcImages, size_t nimages, const TexMeta if ( !filter_select ) { // Default filter choice - filter_select = ( ispow2(metadata.width) && ispow2(metadata.height) && ispow2(metadata.depth) ) ? TEX_FILTER_BOX : TEX_FILTER_LINEAR; + filter_select = ( ispow2(metadata.width) && ispow2(metadata.height) && ispow2(metadata.depth) ) ? TEX_FILTER_BOX : TEX_FILTER_TRIANGLE; } switch( filter_select ) diff --git a/DirectXTex/DirectXTexResize.cpp b/DirectXTex/DirectXTexResize.cpp index 14e9f4b..f4eb82a 100644 --- a/DirectXTex/DirectXTexResize.cpp +++ b/DirectXTex/DirectXTexResize.cpp @@ -723,7 +723,30 @@ static HRESULT _ResizeTriangleFilter( _In_ const Image& srcImage, _In_ DWORD fil if ( !rowAcc->remaining ) { - if ( !_StoreScanlineLinear( pDest + (destImage.rowPitch * v), destImage.rowPitch, destImage.format, rowAcc->scanline.get(), destImage.width, filter ) ) + XMVECTOR* pAccSrc = rowAcc->scanline.get(); + if ( !pAccSrc ) + return E_POINTER; + + switch( destImage.format ) + { + case DXGI_FORMAT_R10G10B10A2_UNORM: + case DXGI_FORMAT_R10G10B10A2_UINT: + { + // Need to slightly bias results for floating-point error accumulation which can + // be visible with harshly quantized values + static const XMVECTORF32 Bias = { 0.f, 0.f, 0.f, 0.1f }; + + XMVECTOR* ptr = pAccSrc; + for( size_t i=0; i < destImage.width; ++i, ++ptr ) + { + *ptr = XMVectorAdd( *ptr, Bias ); + } + } + break; + } + + // This performs any required clamping + if ( !_StoreScanlineLinear( pDest + (destImage.rowPitch * v), destImage.rowPitch, destImage.format, pAccSrc, destImage.width, filter ) ) return E_FAIL; // Put row on freelist to reuse it's allocated scanline