mirror of
https://github.com/microsoft/DirectXTex
synced 2024-11-22 04:20:07 +00:00
DirectXTex: sRGB correct filtering for mipmap generation
This commit is contained in:
parent
0853752b5d
commit
a9c0c4320e
@ -1862,6 +1862,75 @@ static inline XMVECTOR _TableEncodeGamma22( FXMVECTOR v )
|
||||
return XMLoadFloat4( (XMFLOAT4*)f );
|
||||
}
|
||||
|
||||
_Use_decl_annotations_
|
||||
bool _StoreScanlineLinear( LPVOID pDestination, size_t size, DXGI_FORMAT format,
|
||||
XMVECTOR* pSource, size_t count, DWORD flags )
|
||||
{
|
||||
assert( pDestination && size > 0 );
|
||||
assert( pSource && count > 0 && (((uintptr_t)pSource & 0xF) == 0) );
|
||||
assert( IsValid(format) && !IsVideo(format) && !IsTypeless(format) && !IsCompressed(format) );
|
||||
|
||||
switch ( format )
|
||||
{
|
||||
case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
|
||||
case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
|
||||
case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
|
||||
flags |= TEX_FILTER_SRGB;
|
||||
break;
|
||||
|
||||
case DXGI_FORMAT_R32G32B32A32_FLOAT:
|
||||
case DXGI_FORMAT_R32G32B32_FLOAT:
|
||||
case DXGI_FORMAT_R16G16B16A16_FLOAT:
|
||||
case DXGI_FORMAT_R16G16B16A16_UNORM:
|
||||
case DXGI_FORMAT_R32G32_FLOAT:
|
||||
case DXGI_FORMAT_R10G10B10A2_UNORM:
|
||||
case DXGI_FORMAT_R11G11B10_FLOAT:
|
||||
case DXGI_FORMAT_R8G8B8A8_UNORM:
|
||||
case DXGI_FORMAT_R16G16_FLOAT:
|
||||
case DXGI_FORMAT_R16G16_UNORM:
|
||||
case DXGI_FORMAT_R32_FLOAT:
|
||||
case DXGI_FORMAT_R8G8_UNORM:
|
||||
case DXGI_FORMAT_R16_FLOAT:
|
||||
case DXGI_FORMAT_R16_UNORM:
|
||||
case DXGI_FORMAT_R8_UNORM:
|
||||
case DXGI_FORMAT_R9G9B9E5_SHAREDEXP:
|
||||
case DXGI_FORMAT_R8G8_B8G8_UNORM:
|
||||
case DXGI_FORMAT_G8R8_G8B8_UNORM:
|
||||
case DXGI_FORMAT_B5G6R5_UNORM:
|
||||
case DXGI_FORMAT_B5G5R5A1_UNORM:
|
||||
case DXGI_FORMAT_B8G8R8A8_UNORM:
|
||||
case DXGI_FORMAT_B8G8R8X8_UNORM:
|
||||
#ifdef DXGI_1_2_FORMATS
|
||||
case DXGI_FORMAT_B4G4R4A4_UNORM:
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
// can't treat A8, XR, Depth, SNORM, UINT, or SINT as sRGB
|
||||
flags &= ~TEX_FILTER_SRGB;
|
||||
break;
|
||||
}
|
||||
|
||||
// sRGB output processing (RGB -> sRGB)
|
||||
if ( flags & TEX_FILTER_SRGB_OUT )
|
||||
{
|
||||
// To avoid the need for another temporary scanline buffer, we allow this function to overwrite the source buffer in-place
|
||||
// Given the intended usage in the filtering routines, this is not a problem.
|
||||
XMVECTOR* ptr = pSource;
|
||||
for( size_t i=0; i < count; ++i )
|
||||
{
|
||||
// rgb = rgb^(1/2.2); a=a
|
||||
XMVECTOR v = *ptr;
|
||||
XMVECTOR v1 = _TableEncodeGamma22( v );
|
||||
// Use table instead of XMVectorPow( v, [1/2.2f 1/2.2f 1/2.2f 1]).
|
||||
// Note table lookup will also saturate the result
|
||||
*ptr++ = XMVectorSelect( v, v1, g_XMSelect1110 );
|
||||
}
|
||||
}
|
||||
|
||||
return _StoreScanline( pDestination, size, format, pSource, count );
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
// sRGB -> RGB
|
||||
@ -1902,7 +1971,6 @@ static const uint32_t g_fDecodeGamma22[] =
|
||||
0x3f795b20, 0x3f7a7651, 0x3f7b91a2, 0x3f7cad0e, 0x3f7dc896, 0x3f7ee43c, 0x3f800000, 0x3f800000
|
||||
};
|
||||
|
||||
|
||||
#pragma prefast(suppress : 25000, "FXMVECTOR is 16 bytes")
|
||||
static inline XMVECTOR _TableDecodeGamma22( FXMVECTOR v )
|
||||
{
|
||||
@ -1925,6 +1993,78 @@ static inline XMVECTOR _TableDecodeGamma22( FXMVECTOR v )
|
||||
return XMLoadFloat4( (XMFLOAT4*)f );
|
||||
}
|
||||
|
||||
_Use_decl_annotations_
|
||||
bool _LoadScanlineLinear( XMVECTOR* pDestination, size_t count,
|
||||
LPCVOID pSource, size_t size, DXGI_FORMAT format, DWORD flags )
|
||||
{
|
||||
assert( pDestination && count > 0 && (((uintptr_t)pDestination & 0xF) == 0) );
|
||||
assert( pSource && size > 0 );
|
||||
assert( IsValid(format) && !IsVideo(format) && !IsTypeless(format,false) && !IsCompressed(format) );
|
||||
|
||||
switch ( format )
|
||||
{
|
||||
case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
|
||||
case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
|
||||
case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
|
||||
flags |= TEX_FILTER_SRGB;
|
||||
break;
|
||||
|
||||
case DXGI_FORMAT_R32G32B32A32_FLOAT:
|
||||
case DXGI_FORMAT_R32G32B32_FLOAT:
|
||||
case DXGI_FORMAT_R16G16B16A16_FLOAT:
|
||||
case DXGI_FORMAT_R16G16B16A16_UNORM:
|
||||
case DXGI_FORMAT_R32G32_FLOAT:
|
||||
case DXGI_FORMAT_R10G10B10A2_UNORM:
|
||||
case DXGI_FORMAT_R11G11B10_FLOAT:
|
||||
case DXGI_FORMAT_R8G8B8A8_UNORM:
|
||||
case DXGI_FORMAT_R16G16_FLOAT:
|
||||
case DXGI_FORMAT_R16G16_UNORM:
|
||||
case DXGI_FORMAT_R32_FLOAT:
|
||||
case DXGI_FORMAT_R8G8_UNORM:
|
||||
case DXGI_FORMAT_R16_FLOAT:
|
||||
case DXGI_FORMAT_R16_UNORM:
|
||||
case DXGI_FORMAT_R8_UNORM:
|
||||
case DXGI_FORMAT_R9G9B9E5_SHAREDEXP:
|
||||
case DXGI_FORMAT_R8G8_B8G8_UNORM:
|
||||
case DXGI_FORMAT_G8R8_G8B8_UNORM:
|
||||
case DXGI_FORMAT_B5G6R5_UNORM:
|
||||
case DXGI_FORMAT_B5G5R5A1_UNORM:
|
||||
case DXGI_FORMAT_B8G8R8A8_UNORM:
|
||||
case DXGI_FORMAT_B8G8R8X8_UNORM:
|
||||
#ifdef DXGI_1_2_FORMATS
|
||||
case DXGI_FORMAT_B4G4R4A4_UNORM:
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
// can't treat A8, XR, Depth, SNORM, UINT, or SINT as sRGB
|
||||
flags &= ~TEX_FILTER_SRGB;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( _LoadScanline( pDestination, count, pSource, size, format ) )
|
||||
{
|
||||
// sRGB input processing (sRGB -> RGB)
|
||||
if ( flags & TEX_FILTER_SRGB_IN )
|
||||
{
|
||||
XMVECTOR* ptr = pDestination;
|
||||
for( size_t i=0; i < count; ++i )
|
||||
{
|
||||
// rgb = rgb^(2.2); a=a
|
||||
XMVECTOR v = *ptr;
|
||||
// Use table instead of XMVectorPow( v, [2.2f 2.2f 2.2f 1]).
|
||||
// Note table lookup will also saturate the result
|
||||
XMVECTOR v1 = _TableDecodeGamma22( v );
|
||||
*ptr++ = XMVectorSelect( v, v1, g_XMSelect1110 );
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
// Convert scanline based on source/target formats
|
||||
@ -2083,11 +2223,41 @@ void _ConvertScanline( XMVECTOR* pBuffer, size_t count, DXGI_FORMAT outFormat, D
|
||||
assert( _GetConvertFlags( outFormat ) == out->flags );
|
||||
|
||||
// Handle SRGB filtering modes
|
||||
if ( IsSRGB( inFormat ) )
|
||||
switch ( inFormat )
|
||||
{
|
||||
case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
|
||||
case DXGI_FORMAT_BC1_UNORM_SRGB:
|
||||
case DXGI_FORMAT_BC2_UNORM_SRGB:
|
||||
case DXGI_FORMAT_BC3_UNORM_SRGB:
|
||||
case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
|
||||
case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
|
||||
case DXGI_FORMAT_BC7_UNORM_SRGB:
|
||||
flags |= TEX_FILTER_SRGB_IN;
|
||||
break;
|
||||
|
||||
if ( IsSRGB( outFormat ) )
|
||||
case DXGI_FORMAT_A8_UNORM:
|
||||
case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM:
|
||||
flags &= ~TEX_FILTER_SRGB_IN;
|
||||
break;
|
||||
}
|
||||
|
||||
switch ( outFormat )
|
||||
{
|
||||
case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
|
||||
case DXGI_FORMAT_BC1_UNORM_SRGB:
|
||||
case DXGI_FORMAT_BC2_UNORM_SRGB:
|
||||
case DXGI_FORMAT_BC3_UNORM_SRGB:
|
||||
case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
|
||||
case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
|
||||
case DXGI_FORMAT_BC7_UNORM_SRGB:
|
||||
flags |= TEX_FILTER_SRGB_OUT;
|
||||
break;
|
||||
|
||||
case DXGI_FORMAT_A8_UNORM:
|
||||
case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM:
|
||||
flags &= ~TEX_FILTER_SRGB_OUT;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( (flags & (TEX_FILTER_SRGB_IN|TEX_FILTER_SRGB_OUT)) == (TEX_FILTER_SRGB_IN|TEX_FILTER_SRGB_OUT) )
|
||||
{
|
||||
@ -2097,7 +2267,7 @@ void _ConvertScanline( XMVECTOR* pBuffer, size_t count, DXGI_FORMAT outFormat, D
|
||||
// sRGB input processing (sRGB -> RGB)
|
||||
if ( flags & TEX_FILTER_SRGB_IN )
|
||||
{
|
||||
if ( (in->flags & CONVF_FLOAT) || (in->flags & CONVF_UNORM) )
|
||||
if ( !(in->flags & CONVF_DEPTH) && ( (in->flags & CONVF_FLOAT) || (in->flags & CONVF_UNORM) ) )
|
||||
{
|
||||
XMVECTOR* ptr = pBuffer;
|
||||
for( size_t i=0; i < count; ++i )
|
||||
@ -2302,7 +2472,7 @@ void _ConvertScanline( XMVECTOR* pBuffer, size_t count, DXGI_FORMAT outFormat, D
|
||||
// sRGB output processing (RGB -> sRGB)
|
||||
if ( flags & TEX_FILTER_SRGB_OUT )
|
||||
{
|
||||
if ( (out->flags & CONVF_FLOAT) || (out->flags & CONVF_UNORM) )
|
||||
if ( !(out->flags & CONVF_DEPTH) && ( (out->flags & CONVF_FLOAT) || (out->flags & CONVF_UNORM) ) )
|
||||
{
|
||||
XMVECTOR* ptr = pBuffer;
|
||||
for( size_t i=0; i < count; ++i )
|
||||
|
@ -380,6 +380,12 @@ static bool _UseWICFiltering( _In_ DXGI_FORMAT format, _In_ DWORD filter )
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( IsSRGB(format) || (filter & TEX_FILTER_SRGB) )
|
||||
{
|
||||
// Use non-WIC code paths for sRGB correct filtering
|
||||
return false;
|
||||
}
|
||||
|
||||
static_assert( TEX_FILTER_POINT == 0x100000, "TEX_FILTER_ flag values don't match TEX_FILTER_MASK" );
|
||||
|
||||
switch ( filter & TEX_FILTER_MASK )
|
||||
@ -680,7 +686,7 @@ static HRESULT _Generate2DMipsPointFilter( _In_ size_t levels, _In_ const Scratc
|
||||
|
||||
|
||||
//--- 2D Box Filter ---
|
||||
static HRESULT _Generate2DMipsBoxFilter( _In_ size_t levels, _In_ const ScratchImage& mipChain, _In_ size_t item )
|
||||
static HRESULT _Generate2DMipsBoxFilter( _In_ size_t levels, _In_ DWORD filter, _In_ const ScratchImage& mipChain, _In_ size_t item )
|
||||
{
|
||||
if ( !mipChain.GetImages() )
|
||||
return E_INVALIDARG;
|
||||
@ -744,13 +750,13 @@ static HRESULT _Generate2DMipsBoxFilter( _In_ size_t levels, _In_ const ScratchI
|
||||
|
||||
for( size_t y = 0; y < nheight; ++y )
|
||||
{
|
||||
if ( !_LoadScanline( urow0, width, pSrc, rowPitch, src->format ) )
|
||||
if ( !_LoadScanlineLinear( urow0, width, pSrc, rowPitch, src->format, filter ) )
|
||||
return E_FAIL;
|
||||
pSrc += rowPitch;
|
||||
|
||||
if ( urow0 != urow1 )
|
||||
{
|
||||
if ( !_LoadScanline( urow1, width, pSrc, rowPitch, src->format ) )
|
||||
if ( !_LoadScanlineLinear( urow1, width, pSrc, rowPitch, src->format, filter ) )
|
||||
return E_FAIL;
|
||||
pSrc += rowPitch;
|
||||
}
|
||||
@ -762,7 +768,7 @@ static HRESULT _Generate2DMipsBoxFilter( _In_ size_t levels, _In_ const ScratchI
|
||||
AVERAGE4( target[ x ], urow0[ x2 ], urow1[ x2 ], urow2[ x2 ], urow3[ x2 ] );
|
||||
}
|
||||
|
||||
if ( !_StoreScanline( pDest, dest->rowPitch, dest->format, target, nwidth ) )
|
||||
if ( !_StoreScanlineLinear( pDest, dest->rowPitch, dest->format, target, nwidth, filter ) )
|
||||
return E_FAIL;
|
||||
pDest += dest->rowPitch;
|
||||
}
|
||||
@ -847,7 +853,7 @@ static HRESULT _Generate2DMipsLinearFilter( _In_ size_t levels, _In_ DWORD filte
|
||||
{
|
||||
u0 = toY.u0;
|
||||
|
||||
if ( !_LoadScanline( row0, width, pSrc + (rowPitch * u0), rowPitch, src->format ) )
|
||||
if ( !_LoadScanlineLinear( row0, width, pSrc + (rowPitch * u0), rowPitch, src->format, filter ) )
|
||||
return E_FAIL;
|
||||
}
|
||||
else
|
||||
@ -863,7 +869,7 @@ static HRESULT _Generate2DMipsLinearFilter( _In_ size_t levels, _In_ DWORD filte
|
||||
{
|
||||
u1 = toY.u1;
|
||||
|
||||
if ( !_LoadScanline( row1, width, pSrc + (rowPitch * u1), rowPitch, src->format ) )
|
||||
if ( !_LoadScanlineLinear( row1, width, pSrc + (rowPitch * u1), rowPitch, src->format, filter ) )
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
@ -874,7 +880,7 @@ static HRESULT _Generate2DMipsLinearFilter( _In_ size_t levels, _In_ DWORD filte
|
||||
BILINEAR_INTERPOLATE( target[x], toX, toY, row0, row1 );
|
||||
}
|
||||
|
||||
if ( !_StoreScanline( pDest, dest->rowPitch, dest->format, target, nwidth ) )
|
||||
if ( !_StoreScanlineLinear( pDest, dest->rowPitch, dest->format, target, nwidth, filter ) )
|
||||
return E_FAIL;
|
||||
pDest += dest->rowPitch;
|
||||
}
|
||||
@ -966,7 +972,7 @@ static HRESULT _Generate2DMipsCubicFilter( _In_ size_t levels, _In_ DWORD filter
|
||||
{
|
||||
u0 = toY.u0;
|
||||
|
||||
if ( !_LoadScanline( row0, width, pSrc + (rowPitch * u0), rowPitch, src->format ) )
|
||||
if ( !_LoadScanlineLinear( row0, width, pSrc + (rowPitch * u0), rowPitch, src->format, filter ) )
|
||||
return E_FAIL;
|
||||
}
|
||||
else if ( toY.u0 == u1 )
|
||||
@ -999,7 +1005,7 @@ static HRESULT _Generate2DMipsCubicFilter( _In_ size_t levels, _In_ DWORD filter
|
||||
{
|
||||
u1 = toY.u1;
|
||||
|
||||
if ( !_LoadScanline( row1, width, pSrc + (rowPitch * u1), rowPitch, src->format ) )
|
||||
if ( !_LoadScanlineLinear( row1, width, pSrc + (rowPitch * u1), rowPitch, src->format, filter ) )
|
||||
return E_FAIL;
|
||||
}
|
||||
else if ( toY.u1 == u2 )
|
||||
@ -1025,7 +1031,7 @@ static HRESULT _Generate2DMipsCubicFilter( _In_ size_t levels, _In_ DWORD filter
|
||||
{
|
||||
u2 = toY.u2;
|
||||
|
||||
if ( !_LoadScanline( row2, width, pSrc + (rowPitch * u2), rowPitch, src->format ) )
|
||||
if ( !_LoadScanlineLinear( row2, width, pSrc + (rowPitch * u2), rowPitch, src->format, filter ) )
|
||||
return E_FAIL;
|
||||
}
|
||||
else
|
||||
@ -1042,7 +1048,7 @@ static HRESULT _Generate2DMipsCubicFilter( _In_ size_t levels, _In_ DWORD filter
|
||||
{
|
||||
u3 = toY.u3;
|
||||
|
||||
if ( !_LoadScanline( row3, width, pSrc + (rowPitch * u3), rowPitch, src->format ) )
|
||||
if ( !_LoadScanlineLinear( row3, width, pSrc + (rowPitch * u3), rowPitch, src->format, filter ) )
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
@ -1060,7 +1066,7 @@ static HRESULT _Generate2DMipsCubicFilter( _In_ size_t levels, _In_ DWORD filter
|
||||
CUBIC_INTERPOLATE( target[x], toY.x, C0, C1, C2, C3 );
|
||||
}
|
||||
|
||||
if ( !_StoreScanline( pDest, dest->rowPitch, dest->format, target, nwidth ) )
|
||||
if ( !_StoreScanlineLinear( pDest, dest->rowPitch, dest->format, target, nwidth, filter ) )
|
||||
return E_FAIL;
|
||||
pDest += dest->rowPitch;
|
||||
}
|
||||
@ -1277,7 +1283,7 @@ static HRESULT _Generate3DMipsPointFilter( _In_ size_t depth, _In_ size_t levels
|
||||
|
||||
|
||||
//--- 3D Box Filter ---
|
||||
static HRESULT _Generate3DMipsBoxFilter( _In_ size_t depth, _In_ size_t levels, _In_ const ScratchImage& mipChain )
|
||||
static HRESULT _Generate3DMipsBoxFilter( _In_ size_t depth, _In_ size_t levels, _In_ DWORD filter, _In_ const ScratchImage& mipChain )
|
||||
{
|
||||
if ( !depth || !mipChain.GetImages() )
|
||||
return E_INVALIDARG;
|
||||
@ -1362,24 +1368,24 @@ static HRESULT _Generate3DMipsBoxFilter( _In_ size_t depth, _In_ size_t levels,
|
||||
|
||||
for( size_t y = 0; y < nheight; ++y )
|
||||
{
|
||||
if ( !_LoadScanline( urow0, width, pSrc1, aRowPitch, srca->format ) )
|
||||
if ( !_LoadScanlineLinear( urow0, width, pSrc1, aRowPitch, srca->format, filter ) )
|
||||
return E_FAIL;
|
||||
pSrc1 += aRowPitch;
|
||||
|
||||
if ( urow0 != urow1 )
|
||||
{
|
||||
if ( !_LoadScanline( urow1, width, pSrc1, aRowPitch, srca->format ) )
|
||||
if ( !_LoadScanlineLinear( urow1, width, pSrc1, aRowPitch, srca->format, filter ) )
|
||||
return E_FAIL;
|
||||
pSrc1 += aRowPitch;
|
||||
}
|
||||
|
||||
if ( !_LoadScanline( vrow0, width, pSrc2, bRowPitch, srcb->format ) )
|
||||
if ( !_LoadScanlineLinear( vrow0, width, pSrc2, bRowPitch, srcb->format, filter ) )
|
||||
return E_FAIL;
|
||||
pSrc2 += bRowPitch;
|
||||
|
||||
if ( vrow0 != vrow1 )
|
||||
{
|
||||
if ( !_LoadScanline( vrow1, width, pSrc2, bRowPitch, srcb->format ) )
|
||||
if ( !_LoadScanlineLinear( vrow1, width, pSrc2, bRowPitch, srcb->format, filter ) )
|
||||
return E_FAIL;
|
||||
pSrc2 += bRowPitch;
|
||||
}
|
||||
@ -1392,7 +1398,7 @@ static HRESULT _Generate3DMipsBoxFilter( _In_ size_t depth, _In_ size_t levels,
|
||||
vrow0[ x2 ], vrow1[ x2 ], vrow2[ x2 ], vrow3[ x2 ] );
|
||||
}
|
||||
|
||||
if ( !_StoreScanline( pDest, dest->rowPitch, dest->format, target, nwidth ) )
|
||||
if ( !_StoreScanlineLinear( pDest, dest->rowPitch, dest->format, target, nwidth, filter ) )
|
||||
return E_FAIL;
|
||||
pDest += dest->rowPitch;
|
||||
}
|
||||
@ -1417,13 +1423,13 @@ static HRESULT _Generate3DMipsBoxFilter( _In_ size_t depth, _In_ size_t levels,
|
||||
|
||||
for( size_t y = 0; y < nheight; ++y )
|
||||
{
|
||||
if ( !_LoadScanline( urow0, width, pSrc, rowPitch, src->format ) )
|
||||
if ( !_LoadScanlineLinear( urow0, width, pSrc, rowPitch, src->format, filter ) )
|
||||
return E_FAIL;
|
||||
pSrc += rowPitch;
|
||||
|
||||
if ( urow0 != urow1 )
|
||||
{
|
||||
if ( !_LoadScanline( urow1, width, pSrc, rowPitch, src->format ) )
|
||||
if ( !_LoadScanlineLinear( urow1, width, pSrc, rowPitch, src->format, filter ) )
|
||||
return E_FAIL;
|
||||
pSrc += rowPitch;
|
||||
}
|
||||
@ -1435,7 +1441,7 @@ static HRESULT _Generate3DMipsBoxFilter( _In_ size_t depth, _In_ size_t levels,
|
||||
AVERAGE4( target[ x ], urow0[ x2 ], urow1[ x2 ], urow2[ x2 ], urow3[ x2 ] );
|
||||
}
|
||||
|
||||
if ( !_StoreScanline( pDest, dest->rowPitch, dest->format, target, nwidth ) )
|
||||
if ( !_StoreScanlineLinear( pDest, dest->rowPitch, dest->format, target, nwidth, filter ) )
|
||||
return E_FAIL;
|
||||
pDest += dest->rowPitch;
|
||||
}
|
||||
@ -1538,8 +1544,8 @@ static HRESULT _Generate3DMipsLinearFilter( _In_ size_t depth, _In_ size_t level
|
||||
{
|
||||
u0 = toY.u0;
|
||||
|
||||
if ( !_LoadScanline( urow0, width, srca->pixels + (srca->rowPitch * u0), srca->rowPitch, srca->format )
|
||||
|| !_LoadScanline( vrow0, width, srcb->pixels + (srcb->rowPitch * u0), srcb->rowPitch, srcb->format ) )
|
||||
if ( !_LoadScanlineLinear( urow0, width, srca->pixels + (srca->rowPitch * u0), srca->rowPitch, srca->format, filter )
|
||||
|| !_LoadScanlineLinear( vrow0, width, srcb->pixels + (srcb->rowPitch * u0), srcb->rowPitch, srcb->format, filter ) )
|
||||
return E_FAIL;
|
||||
}
|
||||
else
|
||||
@ -1556,8 +1562,8 @@ static HRESULT _Generate3DMipsLinearFilter( _In_ size_t depth, _In_ size_t level
|
||||
{
|
||||
u1 = toY.u1;
|
||||
|
||||
if ( !_LoadScanline( urow1, width, srca->pixels + (srca->rowPitch * u1), srca->rowPitch, srca->format )
|
||||
|| !_LoadScanline( vrow1, width, srcb->pixels + (srcb->rowPitch * u1), srcb->rowPitch, srcb->format ) )
|
||||
if ( !_LoadScanlineLinear( urow1, width, srca->pixels + (srca->rowPitch * u1), srca->rowPitch, srca->format, filter )
|
||||
|| !_LoadScanlineLinear( vrow1, width, srcb->pixels + (srcb->rowPitch * u1), srcb->rowPitch, srcb->format, filter ) )
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
@ -1568,7 +1574,7 @@ static HRESULT _Generate3DMipsLinearFilter( _In_ size_t depth, _In_ size_t level
|
||||
TRILINEAR_INTERPOLATE( target[x], toX, toY, toZ, urow0, urow1, vrow0, vrow1 );
|
||||
}
|
||||
|
||||
if ( !_StoreScanline( pDest, dest->rowPitch, dest->format, target, nwidth ) )
|
||||
if ( !_StoreScanlineLinear( pDest, dest->rowPitch, dest->format, target, nwidth, filter ) )
|
||||
return E_FAIL;
|
||||
pDest += dest->rowPitch;
|
||||
}
|
||||
@ -1601,7 +1607,7 @@ static HRESULT _Generate3DMipsLinearFilter( _In_ size_t depth, _In_ size_t level
|
||||
{
|
||||
u0 = toY.u0;
|
||||
|
||||
if ( !_LoadScanline( urow0, width, pSrc + (rowPitch * u0), rowPitch, src->format ) )
|
||||
if ( !_LoadScanlineLinear( urow0, width, pSrc + (rowPitch * u0), rowPitch, src->format, filter ) )
|
||||
return E_FAIL;
|
||||
}
|
||||
else
|
||||
@ -1617,7 +1623,7 @@ static HRESULT _Generate3DMipsLinearFilter( _In_ size_t depth, _In_ size_t level
|
||||
{
|
||||
u1 = toY.u1;
|
||||
|
||||
if ( !_LoadScanline( urow1, width, pSrc + (rowPitch * u1), rowPitch, src->format ) )
|
||||
if ( !_LoadScanlineLinear( urow1, width, pSrc + (rowPitch * u1), rowPitch, src->format, filter ) )
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
@ -1628,7 +1634,7 @@ static HRESULT _Generate3DMipsLinearFilter( _In_ size_t depth, _In_ size_t level
|
||||
BILINEAR_INTERPOLATE( target[x], toX, toY, urow0, urow1 );
|
||||
}
|
||||
|
||||
if ( !_StoreScanline( pDest, dest->rowPitch, dest->format, target, nwidth ) )
|
||||
if ( !_StoreScanlineLinear( pDest, dest->rowPitch, dest->format, target, nwidth, filter ) )
|
||||
return E_FAIL;
|
||||
pDest += dest->rowPitch;
|
||||
}
|
||||
@ -1748,10 +1754,10 @@ static HRESULT _Generate3DMipsCubicFilter( _In_ size_t depth, _In_ size_t levels
|
||||
{
|
||||
u0 = toY.u0;
|
||||
|
||||
if ( !_LoadScanline( urow[0], width, srca->pixels + (srca->rowPitch * u0), srca->rowPitch, srca->format )
|
||||
|| !_LoadScanline( urow[1], width, srcb->pixels + (srcb->rowPitch * u0), srcb->rowPitch, srcb->format )
|
||||
|| !_LoadScanline( urow[2], width, srcc->pixels + (srcc->rowPitch * u0), srcc->rowPitch, srcc->format )
|
||||
|| !_LoadScanline( urow[3], width, srcd->pixels + (srcd->rowPitch * u0), srcd->rowPitch, srcd->format ) )
|
||||
if ( !_LoadScanlineLinear( urow[0], width, srca->pixels + (srca->rowPitch * u0), srca->rowPitch, srca->format, filter )
|
||||
|| !_LoadScanlineLinear( urow[1], width, srcb->pixels + (srcb->rowPitch * u0), srcb->rowPitch, srcb->format, filter )
|
||||
|| !_LoadScanlineLinear( urow[2], width, srcc->pixels + (srcc->rowPitch * u0), srcc->rowPitch, srcc->format, filter )
|
||||
|| !_LoadScanlineLinear( urow[3], width, srcd->pixels + (srcd->rowPitch * u0), srcd->rowPitch, srcd->format, filter ) )
|
||||
return E_FAIL;
|
||||
}
|
||||
else if ( toY.u0 == u1 )
|
||||
@ -1793,10 +1799,10 @@ static HRESULT _Generate3DMipsCubicFilter( _In_ size_t depth, _In_ size_t levels
|
||||
{
|
||||
u1 = toY.u1;
|
||||
|
||||
if ( !_LoadScanline( vrow[0], width, srca->pixels + (srca->rowPitch * u1), srca->rowPitch, srca->format )
|
||||
|| !_LoadScanline( vrow[1], width, srcb->pixels + (srcb->rowPitch * u1), srcb->rowPitch, srcb->format )
|
||||
|| !_LoadScanline( vrow[2], width, srcc->pixels + (srcc->rowPitch * u1), srcc->rowPitch, srcc->format )
|
||||
|| !_LoadScanline( vrow[3], width, srcd->pixels + (srcd->rowPitch * u1), srcd->rowPitch, srcd->format ) )
|
||||
if ( !_LoadScanlineLinear( vrow[0], width, srca->pixels + (srca->rowPitch * u1), srca->rowPitch, srca->format, filter )
|
||||
|| !_LoadScanlineLinear( vrow[1], width, srcb->pixels + (srcb->rowPitch * u1), srcb->rowPitch, srcb->format, filter )
|
||||
|| !_LoadScanlineLinear( vrow[2], width, srcc->pixels + (srcc->rowPitch * u1), srcc->rowPitch, srcc->format, filter )
|
||||
|| !_LoadScanlineLinear( vrow[3], width, srcd->pixels + (srcd->rowPitch * u1), srcd->rowPitch, srcd->format, filter ) )
|
||||
return E_FAIL;
|
||||
}
|
||||
else if ( toY.u1 == u2 )
|
||||
@ -1828,10 +1834,10 @@ static HRESULT _Generate3DMipsCubicFilter( _In_ size_t depth, _In_ size_t levels
|
||||
{
|
||||
u2 = toY.u2;
|
||||
|
||||
if ( !_LoadScanline( srow[0], width, srca->pixels + (srca->rowPitch * u2), srca->rowPitch, srca->format )
|
||||
|| !_LoadScanline( srow[1], width, srcb->pixels + (srcb->rowPitch * u2), srcb->rowPitch, srcb->format )
|
||||
|| !_LoadScanline( srow[2], width, srcc->pixels + (srcc->rowPitch * u2), srcc->rowPitch, srcc->format )
|
||||
|| !_LoadScanline( srow[3], width, srcd->pixels + (srcd->rowPitch * u2), srcd->rowPitch, srcd->format ) )
|
||||
if ( !_LoadScanlineLinear( srow[0], width, srca->pixels + (srca->rowPitch * u2), srca->rowPitch, srca->format, filter )
|
||||
|| !_LoadScanlineLinear( srow[1], width, srcb->pixels + (srcb->rowPitch * u2), srcb->rowPitch, srcb->format, filter )
|
||||
|| !_LoadScanlineLinear( srow[2], width, srcc->pixels + (srcc->rowPitch * u2), srcc->rowPitch, srcc->format, filter )
|
||||
|| !_LoadScanlineLinear( srow[3], width, srcd->pixels + (srcd->rowPitch * u2), srcd->rowPitch, srcd->format, filter ) )
|
||||
return E_FAIL;
|
||||
}
|
||||
else
|
||||
@ -1851,10 +1857,10 @@ static HRESULT _Generate3DMipsCubicFilter( _In_ size_t depth, _In_ size_t levels
|
||||
{
|
||||
u3 = toY.u3;
|
||||
|
||||
if ( !_LoadScanline( trow[0], width, srca->pixels + (srca->rowPitch * u3), srca->rowPitch, srca->format )
|
||||
|| !_LoadScanline( trow[1], width, srcb->pixels + (srcb->rowPitch * u3), srcb->rowPitch, srcb->format )
|
||||
|| !_LoadScanline( trow[2], width, srcc->pixels + (srcc->rowPitch * u3), srcc->rowPitch, srcc->format )
|
||||
|| !_LoadScanline( trow[3], width, srcd->pixels + (srcd->rowPitch * u3), srcd->rowPitch, srcd->format ) )
|
||||
if ( !_LoadScanlineLinear( trow[0], width, srca->pixels + (srca->rowPitch * u3), srca->rowPitch, srca->format, filter )
|
||||
|| !_LoadScanlineLinear( trow[1], width, srcb->pixels + (srcb->rowPitch * u3), srcb->rowPitch, srcb->format, filter )
|
||||
|| !_LoadScanlineLinear( trow[2], width, srcc->pixels + (srcc->rowPitch * u3), srcc->rowPitch, srcc->format, filter )
|
||||
|| !_LoadScanlineLinear( trow[3], width, srcd->pixels + (srcd->rowPitch * u3), srcd->rowPitch, srcd->format, filter ) )
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
@ -1878,7 +1884,7 @@ static HRESULT _Generate3DMipsCubicFilter( _In_ size_t depth, _In_ size_t levels
|
||||
CUBIC_INTERPOLATE( target[x], toZ.x, D[0], D[1], D[2], D[3] );
|
||||
}
|
||||
|
||||
if ( !_StoreScanline( pDest, dest->rowPitch, dest->format, target, nwidth ) )
|
||||
if ( !_StoreScanlineLinear( pDest, dest->rowPitch, dest->format, target, nwidth, filter ) )
|
||||
return E_FAIL;
|
||||
pDest += dest->rowPitch;
|
||||
}
|
||||
@ -1914,7 +1920,7 @@ static HRESULT _Generate3DMipsCubicFilter( _In_ size_t depth, _In_ size_t levels
|
||||
{
|
||||
u0 = toY.u0;
|
||||
|
||||
if ( !_LoadScanline( urow[0], width, pSrc + (rowPitch * u0), rowPitch, src->format ) )
|
||||
if ( !_LoadScanlineLinear( urow[0], width, pSrc + (rowPitch * u0), rowPitch, src->format, filter ) )
|
||||
return E_FAIL;
|
||||
}
|
||||
else if ( toY.u0 == u1 )
|
||||
@ -1947,7 +1953,7 @@ static HRESULT _Generate3DMipsCubicFilter( _In_ size_t depth, _In_ size_t levels
|
||||
{
|
||||
u1 = toY.u1;
|
||||
|
||||
if ( !_LoadScanline( vrow[0], width, pSrc + (rowPitch * u1), rowPitch, src->format ) )
|
||||
if ( !_LoadScanlineLinear( vrow[0], width, pSrc + (rowPitch * u1), rowPitch, src->format, filter ) )
|
||||
return E_FAIL;
|
||||
}
|
||||
else if ( toY.u1 == u2 )
|
||||
@ -1973,7 +1979,7 @@ static HRESULT _Generate3DMipsCubicFilter( _In_ size_t depth, _In_ size_t levels
|
||||
{
|
||||
u2 = toY.u2;
|
||||
|
||||
if ( !_LoadScanline( srow[0], width, pSrc + (rowPitch * u2), rowPitch, src->format ) )
|
||||
if ( !_LoadScanlineLinear( srow[0], width, pSrc + (rowPitch * u2), rowPitch, src->format, filter ) )
|
||||
return E_FAIL;
|
||||
}
|
||||
else
|
||||
@ -1990,7 +1996,7 @@ static HRESULT _Generate3DMipsCubicFilter( _In_ size_t depth, _In_ size_t levels
|
||||
{
|
||||
u3 = toY.u3;
|
||||
|
||||
if ( !_LoadScanline( trow[0], width, pSrc + (rowPitch * u3), rowPitch, src->format ) )
|
||||
if ( !_LoadScanlineLinear( trow[0], width, pSrc + (rowPitch * u3), rowPitch, src->format, filter ) )
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
@ -2007,7 +2013,7 @@ static HRESULT _Generate3DMipsCubicFilter( _In_ size_t depth, _In_ size_t levels
|
||||
CUBIC_INTERPOLATE( target[x], toY.x, C0, C1, C2, C3 );
|
||||
}
|
||||
|
||||
if ( !_StoreScanline( pDest, dest->rowPitch, dest->format, target, nwidth ) )
|
||||
if ( !_StoreScanlineLinear( pDest, dest->rowPitch, dest->format, target, nwidth, filter ) )
|
||||
return E_FAIL;
|
||||
pDest += dest->rowPitch;
|
||||
}
|
||||
@ -2143,7 +2149,7 @@ HRESULT GenerateMipMaps( const Image& baseImage, DWORD filter, size_t levels, Sc
|
||||
if ( FAILED(hr) )
|
||||
return hr;
|
||||
|
||||
hr = _Generate2DMipsBoxFilter( levels, mipChain, 0 );
|
||||
hr = _Generate2DMipsBoxFilter( levels, filter, mipChain, 0 );
|
||||
if ( FAILED(hr) )
|
||||
mipChain.Release();
|
||||
return hr;
|
||||
@ -2320,7 +2326,7 @@ HRESULT GenerateMipMaps( const Image* srcImages, size_t nimages, const TexMetada
|
||||
|
||||
for( size_t item = 0; item < metadata.arraySize; ++item )
|
||||
{
|
||||
hr = _Generate2DMipsBoxFilter( levels, mipChain, item );
|
||||
hr = _Generate2DMipsBoxFilter( levels, filter, mipChain, item );
|
||||
if ( FAILED(hr) )
|
||||
mipChain.Release();
|
||||
}
|
||||
@ -2427,7 +2433,7 @@ HRESULT GenerateMipMaps3D( const Image* baseImages, size_t depth, DWORD filter,
|
||||
if ( FAILED(hr) )
|
||||
return hr;
|
||||
|
||||
hr = _Generate3DMipsBoxFilter( depth, levels, mipChain );
|
||||
hr = _Generate3DMipsBoxFilter( depth, levels, filter, mipChain );
|
||||
if ( FAILED(hr) )
|
||||
mipChain.Release();
|
||||
return hr;
|
||||
@ -2525,7 +2531,7 @@ HRESULT GenerateMipMaps3D( const Image* srcImages, size_t nimages, const TexMeta
|
||||
if ( FAILED(hr) )
|
||||
return hr;
|
||||
|
||||
hr = _Generate3DMipsBoxFilter( metadata.depth, levels, mipChain );
|
||||
hr = _Generate3DMipsBoxFilter( metadata.depth, levels, filter, mipChain );
|
||||
if ( FAILED(hr) )
|
||||
mipChain.Release();
|
||||
return hr;
|
||||
|
@ -185,10 +185,18 @@ namespace DirectX
|
||||
bool _LoadScanline( _Out_writes_(count) XMVECTOR* pDestination, _In_ size_t count,
|
||||
_In_reads_bytes_(size) LPCVOID pSource, _In_ size_t size, _In_ DXGI_FORMAT format );
|
||||
|
||||
_Success_(return != false)
|
||||
bool _LoadScanlineLinear( _Out_writes_(count) XMVECTOR* pDestination, _In_ size_t count,
|
||||
_In_reads_bytes_(size) LPCVOID pSource, _In_ size_t size, _In_ DXGI_FORMAT format, _In_ DWORD flags );
|
||||
|
||||
_Success_(return != false)
|
||||
bool _StoreScanline( LPVOID pDestination, _In_ size_t size, _In_ DXGI_FORMAT format,
|
||||
_In_reads_(count) const XMVECTOR* pSource, _In_ size_t count);
|
||||
|
||||
_Success_(return != false)
|
||||
bool _StoreScanlineLinear( LPVOID pDestination, _In_ size_t size, _In_ DXGI_FORMAT format,
|
||||
_Inout_updates_all_(count) XMVECTOR* pSource, _In_ size_t count, _In_ DWORD flags );
|
||||
|
||||
HRESULT _ConvertToR32G32B32A32( _In_ const Image& srcImage, _Inout_ ScratchImage& image );
|
||||
|
||||
HRESULT _ConvertFromR32G32B32A32( _In_ const Image& srcImage, _In_ const Image& destImage );
|
||||
|
Loading…
Reference in New Issue
Block a user