mirror of
https://github.com/microsoft/DirectXTex.git
synced 2025-07-15 14:30:13 +02:00
DirectXTex: code review feedback
This commit is contained in:
parent
4e1e8b49c1
commit
0853752b5d
@ -366,18 +366,18 @@ HRESULT _ResizeSeparateColorAndAlpha( _In_ IWICImagingFactory* pWIC, _In_ IWICBi
|
|||||||
|
|
||||||
|
|
||||||
//--- determine when to use WIC vs. non-WIC paths ---
|
//--- determine when to use WIC vs. non-WIC paths ---
|
||||||
static HRESULT _UseWICFiltering( _In_ DXGI_FORMAT format, _In_ DWORD filter )
|
static bool _UseWICFiltering( _In_ DXGI_FORMAT format, _In_ DWORD filter )
|
||||||
{
|
{
|
||||||
if ( filter & TEX_FILTER_FORCE_NON_WIC )
|
if ( filter & TEX_FILTER_FORCE_NON_WIC )
|
||||||
{
|
{
|
||||||
// Explicit flag indicates use of non-WIC code paths
|
// Explicit flag indicates use of non-WIC code paths
|
||||||
return S_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( filter & TEX_FILTER_FORCE_WIC )
|
if ( filter & TEX_FILTER_FORCE_WIC )
|
||||||
{
|
{
|
||||||
// Explicit flag to use WIC code paths, skips all the case checks below
|
// Explicit flag to use WIC code paths, skips all the case checks below
|
||||||
return S_OK;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static_assert( TEX_FILTER_POINT == 0x100000, "TEX_FILTER_ flag values don't match TEX_FILTER_MASK" );
|
static_assert( TEX_FILTER_POINT == 0x100000, "TEX_FILTER_ flag values don't match TEX_FILTER_MASK" );
|
||||||
@ -388,13 +388,13 @@ static HRESULT _UseWICFiltering( _In_ DXGI_FORMAT format, _In_ DWORD filter )
|
|||||||
if ( filter & TEX_FILTER_WRAP )
|
if ( filter & TEX_FILTER_WRAP )
|
||||||
{
|
{
|
||||||
// WIC only supports 'clamp' semantics (MIRROR is equivalent to clamp for linear)
|
// WIC only supports 'clamp' semantics (MIRROR is equivalent to clamp for linear)
|
||||||
return S_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( BitsPerColor(format) > 8 )
|
if ( BitsPerColor(format) > 8 )
|
||||||
{
|
{
|
||||||
// Avoid the WIC bitmap scaler when doing Linear filtering of XR/HDR formats
|
// Avoid the WIC bitmap scaler when doing Linear filtering of XR/HDR formats
|
||||||
return S_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -402,21 +402,18 @@ static HRESULT _UseWICFiltering( _In_ DXGI_FORMAT format, _In_ DWORD filter )
|
|||||||
if ( filter & ( TEX_FILTER_WRAP | TEX_FILTER_MIRROR ) )
|
if ( filter & ( TEX_FILTER_WRAP | TEX_FILTER_MIRROR ) )
|
||||||
{
|
{
|
||||||
// WIC only supports 'clamp' semantics
|
// WIC only supports 'clamp' semantics
|
||||||
return S_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( BitsPerColor(format) > 8 )
|
if ( BitsPerColor(format) > 8 )
|
||||||
{
|
{
|
||||||
// Avoid the WIC bitmap scaler when doing Cubic filtering of XR/HDR formats
|
// Avoid the WIC bitmap scaler when doing Cubic filtering of XR/HDR formats
|
||||||
return S_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return S_OK;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2054,13 +2051,65 @@ HRESULT GenerateMipMaps( const Image& baseImage, DWORD filter, size_t levels, Sc
|
|||||||
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
|
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT hr = _UseWICFiltering( baseImage.format, filter );
|
HRESULT hr;
|
||||||
if ( FAILED(hr) )
|
|
||||||
return hr;
|
|
||||||
|
|
||||||
static_assert( TEX_FILTER_POINT == 0x100000, "TEX_FILTER_ flag values don't match TEX_FILTER_MASK" );
|
static_assert( TEX_FILTER_POINT == 0x100000, "TEX_FILTER_ flag values don't match TEX_FILTER_MASK" );
|
||||||
|
|
||||||
if ( hr == S_FALSE )
|
if ( _UseWICFiltering( baseImage.format, filter ) )
|
||||||
|
{
|
||||||
|
//--- Use WIC filtering to generate mipmaps -----------------------------------
|
||||||
|
switch(filter & TEX_FILTER_MASK)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
case TEX_FILTER_POINT:
|
||||||
|
case TEX_FILTER_FANT: // Equivalent to Box filter
|
||||||
|
case TEX_FILTER_LINEAR:
|
||||||
|
case TEX_FILTER_CUBIC:
|
||||||
|
{
|
||||||
|
static_assert( TEX_FILTER_FANT == TEX_FILTER_BOX, "TEX_FILTER_ flag alias mismatch" );
|
||||||
|
|
||||||
|
WICPixelFormatGUID pfGUID;
|
||||||
|
if ( _DXGIToWIC( baseImage.format, pfGUID, true ) )
|
||||||
|
{
|
||||||
|
// Case 1: Base image format is supported by Windows Imaging Component
|
||||||
|
HRESULT hr = (baseImage.height > 1 || !allow1D)
|
||||||
|
? mipChain.Initialize2D( baseImage.format, baseImage.width, baseImage.height, 1, levels )
|
||||||
|
: mipChain.Initialize1D( baseImage.format, baseImage.width, 1, levels );
|
||||||
|
if ( FAILED(hr) )
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
return _GenerateMipMapsUsingWIC( baseImage, filter, levels, pfGUID, mipChain, 0 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Case 2: Base image format is not supported by WIC, so we have to convert, generate, and convert back
|
||||||
|
assert( baseImage.format != DXGI_FORMAT_R32G32B32A32_FLOAT );
|
||||||
|
ScratchImage temp;
|
||||||
|
HRESULT hr = _ConvertToR32G32B32A32( baseImage, temp );
|
||||||
|
if ( FAILED(hr) )
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
const Image *timg = temp.GetImage( 0, 0, 0 );
|
||||||
|
if ( !timg )
|
||||||
|
return E_POINTER;
|
||||||
|
|
||||||
|
ScratchImage tMipChain;
|
||||||
|
hr = _GenerateMipMapsUsingWIC( *timg, filter, levels, GUID_WICPixelFormat128bppRGBAFloat, tMipChain, 0 );
|
||||||
|
if ( FAILED(hr) )
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
temp.Release();
|
||||||
|
|
||||||
|
return _ConvertFromR32G32B32A32( tMipChain.GetImages(), tMipChain.GetImageCount(), tMipChain.GetMetadata(), baseImage.format, mipChain );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
//--- Use custom filters to generate mipmaps ----------------------------------
|
//--- Use custom filters to generate mipmaps ----------------------------------
|
||||||
TexMetadata mdata;
|
TexMetadata mdata;
|
||||||
@ -2133,60 +2182,6 @@ HRESULT GenerateMipMaps( const Image& baseImage, DWORD filter, size_t levels, Sc
|
|||||||
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
|
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
//--- Use WIC filtering to generate mipmaps -----------------------------------
|
|
||||||
switch(filter & TEX_FILTER_MASK)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
case TEX_FILTER_POINT:
|
|
||||||
case TEX_FILTER_FANT: // Equivalent to Box filter
|
|
||||||
case TEX_FILTER_LINEAR:
|
|
||||||
case TEX_FILTER_CUBIC:
|
|
||||||
{
|
|
||||||
static_assert( TEX_FILTER_FANT == TEX_FILTER_BOX, "TEX_FILTER_ flag alias mismatch" );
|
|
||||||
|
|
||||||
WICPixelFormatGUID pfGUID;
|
|
||||||
if ( _DXGIToWIC( baseImage.format, pfGUID, true ) )
|
|
||||||
{
|
|
||||||
// Case 1: Base image format is supported by Windows Imaging Component
|
|
||||||
HRESULT hr = (baseImage.height > 1 || !allow1D)
|
|
||||||
? mipChain.Initialize2D( baseImage.format, baseImage.width, baseImage.height, 1, levels )
|
|
||||||
: mipChain.Initialize1D( baseImage.format, baseImage.width, 1, levels );
|
|
||||||
if ( FAILED(hr) )
|
|
||||||
return hr;
|
|
||||||
|
|
||||||
return _GenerateMipMapsUsingWIC( baseImage, filter, levels, pfGUID, mipChain, 0 );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Case 2: Base image format is not supported by WIC, so we have to convert, generate, and convert back
|
|
||||||
assert( baseImage.format != DXGI_FORMAT_R32G32B32A32_FLOAT );
|
|
||||||
ScratchImage temp;
|
|
||||||
HRESULT hr = _ConvertToR32G32B32A32( baseImage, temp );
|
|
||||||
if ( FAILED(hr) )
|
|
||||||
return hr;
|
|
||||||
|
|
||||||
const Image *timg = temp.GetImage( 0, 0, 0 );
|
|
||||||
if ( !timg )
|
|
||||||
return E_POINTER;
|
|
||||||
|
|
||||||
ScratchImage tMipChain;
|
|
||||||
hr = _GenerateMipMapsUsingWIC( *timg, filter, levels, GUID_WICPixelFormat128bppRGBAFloat, tMipChain, 0 );
|
|
||||||
if ( FAILED(hr) )
|
|
||||||
return hr;
|
|
||||||
|
|
||||||
temp.Release();
|
|
||||||
|
|
||||||
return _ConvertFromR32G32B32A32( tMipChain.GetImages(), tMipChain.GetImageCount(), tMipChain.GetMetadata(), baseImage.format, mipChain );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_Use_decl_annotations_
|
_Use_decl_annotations_
|
||||||
@ -2226,84 +2221,11 @@ HRESULT GenerateMipMaps( const Image* srcImages, size_t nimages, const TexMetada
|
|||||||
|
|
||||||
assert( baseImages.size() == metadata.arraySize );
|
assert( baseImages.size() == metadata.arraySize );
|
||||||
|
|
||||||
HRESULT hr = _UseWICFiltering( metadata.format, filter );
|
HRESULT hr;
|
||||||
if ( FAILED(hr) )
|
|
||||||
return hr;
|
|
||||||
|
|
||||||
static_assert( TEX_FILTER_POINT == 0x100000, "TEX_FILTER_ flag values don't match TEX_FILTER_MASK" );
|
static_assert( TEX_FILTER_POINT == 0x100000, "TEX_FILTER_ flag values don't match TEX_FILTER_MASK" );
|
||||||
|
|
||||||
if ( hr == S_FALSE )
|
if ( _UseWICFiltering( metadata.format, filter ) )
|
||||||
{
|
|
||||||
//--- Use custom filters to generate mipmaps ----------------------------------
|
|
||||||
TexMetadata mdata2 = metadata;
|
|
||||||
mdata2.mipLevels = levels;
|
|
||||||
|
|
||||||
DWORD filter_select = ( filter & TEX_FILTER_MASK );
|
|
||||||
if ( !filter_select )
|
|
||||||
{
|
|
||||||
// Default filter choice
|
|
||||||
filter_select = ( ispow2(metadata.width) && ispow2(metadata.height) ) ? TEX_FILTER_BOX : TEX_FILTER_LINEAR;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch( filter_select )
|
|
||||||
{
|
|
||||||
case TEX_FILTER_BOX:
|
|
||||||
hr = _Setup2DMips( &baseImages[0], metadata.arraySize, mdata2, mipChain );
|
|
||||||
if ( FAILED(hr) )
|
|
||||||
return hr;
|
|
||||||
|
|
||||||
for( size_t item = 0; item < metadata.arraySize; ++item )
|
|
||||||
{
|
|
||||||
hr = _Generate2DMipsBoxFilter( levels, mipChain, item );
|
|
||||||
if ( FAILED(hr) )
|
|
||||||
mipChain.Release();
|
|
||||||
}
|
|
||||||
return hr;
|
|
||||||
|
|
||||||
case TEX_FILTER_POINT:
|
|
||||||
hr = _Setup2DMips( &baseImages[0], metadata.arraySize, mdata2, mipChain );
|
|
||||||
if ( FAILED(hr) )
|
|
||||||
return hr;
|
|
||||||
|
|
||||||
for( size_t item = 0; item < metadata.arraySize; ++item )
|
|
||||||
{
|
|
||||||
hr = _Generate2DMipsPointFilter( levels, mipChain, item );
|
|
||||||
if ( FAILED(hr) )
|
|
||||||
mipChain.Release();
|
|
||||||
}
|
|
||||||
return hr;
|
|
||||||
|
|
||||||
case TEX_FILTER_LINEAR:
|
|
||||||
hr = _Setup2DMips( &baseImages[0], metadata.arraySize, mdata2, mipChain );
|
|
||||||
if ( FAILED(hr) )
|
|
||||||
return hr;
|
|
||||||
|
|
||||||
for( size_t item = 0; item < metadata.arraySize; ++item )
|
|
||||||
{
|
|
||||||
hr = _Generate2DMipsLinearFilter( levels, filter, mipChain, item );
|
|
||||||
if ( FAILED(hr) )
|
|
||||||
mipChain.Release();
|
|
||||||
}
|
|
||||||
return hr;
|
|
||||||
|
|
||||||
case TEX_FILTER_CUBIC:
|
|
||||||
hr = _Setup2DMips( &baseImages[0], metadata.arraySize, mdata2, mipChain );
|
|
||||||
if ( FAILED(hr) )
|
|
||||||
return hr;
|
|
||||||
|
|
||||||
for( size_t item = 0; item < metadata.arraySize; ++item )
|
|
||||||
{
|
|
||||||
hr = _Generate2DMipsCubicFilter( levels, filter, mipChain, item );
|
|
||||||
if ( FAILED(hr) )
|
|
||||||
mipChain.Release();
|
|
||||||
}
|
|
||||||
return hr;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
//--- Use WIC filtering to generate mipmaps -----------------------------------
|
//--- Use WIC filtering to generate mipmaps -----------------------------------
|
||||||
switch(filter & TEX_FILTER_MASK)
|
switch(filter & TEX_FILTER_MASK)
|
||||||
@ -2376,6 +2298,77 @@ HRESULT GenerateMipMaps( const Image* srcImages, size_t nimages, const TexMetada
|
|||||||
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
|
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//--- Use custom filters to generate mipmaps ----------------------------------
|
||||||
|
TexMetadata mdata2 = metadata;
|
||||||
|
mdata2.mipLevels = levels;
|
||||||
|
|
||||||
|
DWORD filter_select = ( filter & TEX_FILTER_MASK );
|
||||||
|
if ( !filter_select )
|
||||||
|
{
|
||||||
|
// Default filter choice
|
||||||
|
filter_select = ( ispow2(metadata.width) && ispow2(metadata.height) ) ? TEX_FILTER_BOX : TEX_FILTER_LINEAR;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch( filter_select )
|
||||||
|
{
|
||||||
|
case TEX_FILTER_BOX:
|
||||||
|
hr = _Setup2DMips( &baseImages[0], metadata.arraySize, mdata2, mipChain );
|
||||||
|
if ( FAILED(hr) )
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
for( size_t item = 0; item < metadata.arraySize; ++item )
|
||||||
|
{
|
||||||
|
hr = _Generate2DMipsBoxFilter( levels, mipChain, item );
|
||||||
|
if ( FAILED(hr) )
|
||||||
|
mipChain.Release();
|
||||||
|
}
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
case TEX_FILTER_POINT:
|
||||||
|
hr = _Setup2DMips( &baseImages[0], metadata.arraySize, mdata2, mipChain );
|
||||||
|
if ( FAILED(hr) )
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
for( size_t item = 0; item < metadata.arraySize; ++item )
|
||||||
|
{
|
||||||
|
hr = _Generate2DMipsPointFilter( levels, mipChain, item );
|
||||||
|
if ( FAILED(hr) )
|
||||||
|
mipChain.Release();
|
||||||
|
}
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
case TEX_FILTER_LINEAR:
|
||||||
|
hr = _Setup2DMips( &baseImages[0], metadata.arraySize, mdata2, mipChain );
|
||||||
|
if ( FAILED(hr) )
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
for( size_t item = 0; item < metadata.arraySize; ++item )
|
||||||
|
{
|
||||||
|
hr = _Generate2DMipsLinearFilter( levels, filter, mipChain, item );
|
||||||
|
if ( FAILED(hr) )
|
||||||
|
mipChain.Release();
|
||||||
|
}
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
case TEX_FILTER_CUBIC:
|
||||||
|
hr = _Setup2DMips( &baseImages[0], metadata.arraySize, mdata2, mipChain );
|
||||||
|
if ( FAILED(hr) )
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
for( size_t item = 0; item < metadata.arraySize; ++item )
|
||||||
|
{
|
||||||
|
hr = _Generate2DMipsCubicFilter( levels, filter, mipChain, item );
|
||||||
|
if ( FAILED(hr) )
|
||||||
|
mipChain.Release();
|
||||||
|
}
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ struct LinearFilter
|
|||||||
float weight1;
|
float weight1;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void _CreateLinearFilter( _In_ size_t source, _In_ size_t dest, _In_ bool wrap, _Out_writes_(dest) LinearFilter* lf )
|
inline void _CreateLinearFilter( _In_ size_t source, _In_ size_t dest, _In_ bool wrap, _Out_writes_(dest) LinearFilter* lf )
|
||||||
{
|
{
|
||||||
assert( source > 0 );
|
assert( source > 0 );
|
||||||
assert( dest > 0 );
|
assert( dest > 0 );
|
||||||
@ -73,6 +73,8 @@ static void _CreateLinearFilter( _In_ size_t source, _In_ size_t dest, _In_ bool
|
|||||||
|
|
||||||
float scale = float(source) / float(dest);
|
float scale = float(source) / float(dest);
|
||||||
|
|
||||||
|
// Mirror is the same case as clamp for linear
|
||||||
|
|
||||||
for( size_t u = 0; u < dest; ++u )
|
for( size_t u = 0; u < dest; ++u )
|
||||||
{
|
{
|
||||||
float srcB = ( float(u) + 0.5f ) * scale + 0.5f;
|
float srcB = ( float(u) + 0.5f ) * scale + 0.5f;
|
||||||
@ -145,6 +147,7 @@ inline ptrdiff_t bounduvw( ptrdiff_t u, ptrdiff_t maxu, bool wrap, bool mirror )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handles clamp, but also a safety factor for degenerate images for wrap/mirror
|
||||||
u = std::min<ptrdiff_t>( u, maxu );
|
u = std::min<ptrdiff_t>( u, maxu );
|
||||||
u = std::max<ptrdiff_t>( u, 0 );
|
u = std::max<ptrdiff_t>( u, 0 );
|
||||||
|
|
||||||
@ -160,7 +163,7 @@ struct CubicFilter
|
|||||||
float x;
|
float x;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void _CreateCubicFilter( _In_ size_t source, _In_ size_t dest, _In_ bool wrap, bool mirror, _Out_writes_(dest) CubicFilter* cf )
|
inline void _CreateCubicFilter( _In_ size_t source, _In_ size_t dest, _In_ bool wrap, bool mirror, _Out_writes_(dest) CubicFilter* cf )
|
||||||
{
|
{
|
||||||
assert( source > 0 );
|
assert( source > 0 );
|
||||||
assert( dest > 0 );
|
assert( dest > 0 );
|
||||||
|
Loading…
x
Reference in New Issue
Block a user