mirror of
https://github.com/microsoft/DirectXTex.git
synced 2025-07-15 14:30:13 +02:00
BC7 compressor optimization for skipping mode 0 & 2 by default
This commit is contained in:
parent
b86f3faf6d
commit
429b3e7995
@ -59,6 +59,7 @@ enum BC_FLAGS
|
|||||||
BC_FLAGS_DITHER_RGB = 0x10000, // Enables dithering for RGB colors for BC1-3
|
BC_FLAGS_DITHER_RGB = 0x10000, // Enables dithering for RGB colors for BC1-3
|
||||||
BC_FLAGS_DITHER_A = 0x20000, // Enables dithering for Alpha channel for BC1-3
|
BC_FLAGS_DITHER_A = 0x20000, // Enables dithering for Alpha channel for BC1-3
|
||||||
BC_FLAGS_UNIFORM = 0x40000, // By default, uses perceptual weighting for BC1-3; this flag makes it a uniform weighting
|
BC_FLAGS_UNIFORM = 0x40000, // By default, uses perceptual weighting for BC1-3; this flag makes it a uniform weighting
|
||||||
|
BC_FLAGS_USE_3SUBSETS = 0x80000,// By default, BC7 skips mode 0 & 2; this flag adds those modes back
|
||||||
};
|
};
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------
|
||||||
@ -623,7 +624,7 @@ class D3DX_BC7 : private CBits< 16 >
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void Decode(_Out_writes_(NUM_PIXELS_PER_BLOCK) HDRColorA* pOut) const;
|
void Decode(_Out_writes_(NUM_PIXELS_PER_BLOCK) HDRColorA* pOut) const;
|
||||||
void Encode(_In_reads_(NUM_PIXELS_PER_BLOCK) const HDRColorA* const pIn);
|
void Encode(bool skip3subsets, _In_reads_(NUM_PIXELS_PER_BLOCK) const HDRColorA* const pIn);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct ModeInfo
|
struct ModeInfo
|
||||||
|
@ -2143,7 +2143,7 @@ void D3DX_BC7::Decode(HDRColorA* pOut) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
_Use_decl_annotations_
|
_Use_decl_annotations_
|
||||||
void D3DX_BC7::Encode(const HDRColorA* const pIn)
|
void D3DX_BC7::Encode(bool skip3subsets, const HDRColorA* const pIn)
|
||||||
{
|
{
|
||||||
assert( pIn );
|
assert( pIn );
|
||||||
|
|
||||||
@ -2161,6 +2161,12 @@ void D3DX_BC7::Encode(const HDRColorA* const pIn)
|
|||||||
|
|
||||||
for(EP.uMode = 0; EP.uMode < 8 && fMSEBest > 0; ++EP.uMode)
|
for(EP.uMode = 0; EP.uMode < 8 && fMSEBest > 0; ++EP.uMode)
|
||||||
{
|
{
|
||||||
|
if ( skip3subsets && (EP.uMode == 0 || EP.uMode == 2) )
|
||||||
|
{
|
||||||
|
// 3 subset modes tend to be used rarely and add significant compression time
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const size_t uShapes = size_t(1) << ms_aInfo[EP.uMode].uPartitionBits;
|
const size_t uShapes = size_t(1) << ms_aInfo[EP.uMode].uPartitionBits;
|
||||||
assert( uShapes <= BC7_MAX_SHAPES );
|
assert( uShapes <= BC7_MAX_SHAPES );
|
||||||
_Analysis_assume_( uShapes <= BC7_MAX_SHAPES );
|
_Analysis_assume_( uShapes <= BC7_MAX_SHAPES );
|
||||||
@ -2860,10 +2866,9 @@ void D3DXDecodeBC7(XMVECTOR *pColor, const uint8_t *pBC)
|
|||||||
_Use_decl_annotations_
|
_Use_decl_annotations_
|
||||||
void D3DXEncodeBC7(uint8_t *pBC, const XMVECTOR *pColor, DWORD flags)
|
void D3DXEncodeBC7(uint8_t *pBC, const XMVECTOR *pColor, DWORD flags)
|
||||||
{
|
{
|
||||||
UNREFERENCED_PARAMETER(flags);
|
|
||||||
assert( pBC && pColor );
|
assert( pBC && pColor );
|
||||||
static_assert( sizeof(D3DX_BC7) == 16, "D3DX_BC7 should be 16 bytes" );
|
static_assert( sizeof(D3DX_BC7) == 16, "D3DX_BC7 should be 16 bytes" );
|
||||||
reinterpret_cast< D3DX_BC7* >( pBC )->Encode(reinterpret_cast<const HDRColorA*>(pColor));
|
reinterpret_cast< D3DX_BC7* >( pBC )->Encode( !(flags& BC_FLAGS_USE_3SUBSETS), reinterpret_cast<const HDRColorA*>(pColor));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -178,7 +178,7 @@ HRESULT GPUCompressBC::Initialize( ID3D11Device* pDevice )
|
|||||||
|
|
||||||
//-------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------
|
||||||
_Use_decl_annotations_
|
_Use_decl_annotations_
|
||||||
HRESULT GPUCompressBC::Prepare( size_t width, size_t height, DXGI_FORMAT format, float alphaWeight )
|
HRESULT GPUCompressBC::Prepare( size_t width, size_t height, DXGI_FORMAT format, float alphaWeight, bool skip3subsets )
|
||||||
{
|
{
|
||||||
if ( !width || !height || alphaWeight < 0.f )
|
if ( !width || !height || alphaWeight < 0.f )
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
@ -193,6 +193,8 @@ HRESULT GPUCompressBC::Prepare( size_t width, size_t height, DXGI_FORMAT format,
|
|||||||
|
|
||||||
m_alphaWeight = alphaWeight;
|
m_alphaWeight = alphaWeight;
|
||||||
|
|
||||||
|
m_skip3Subsets = skip3subsets;
|
||||||
|
|
||||||
size_t xblocks = std::max<size_t>( 1, (width + 3) >> 2 );
|
size_t xblocks = std::max<size_t>( 1, (width + 3) >> 2 );
|
||||||
size_t yblocks = std::max<size_t>( 1, (height + 3) >> 2 );
|
size_t yblocks = std::max<size_t>( 1, (height + 3) >> 2 );
|
||||||
size_t num_blocks = xblocks * yblocks;
|
size_t num_blocks = xblocks * yblocks;
|
||||||
@ -468,6 +470,10 @@ HRESULT GPUCompressBC::Compress( const Image& srcImage, const Image& destImage )
|
|||||||
for ( UINT i = 0; i < 3; ++i )
|
for ( UINT i = 0; i < 3; ++i )
|
||||||
{
|
{
|
||||||
static const UINT modes[] = { 1, 3, 7 };
|
static const UINT modes[] = { 1, 3, 7 };
|
||||||
|
|
||||||
|
// Mode 1: err1 -> err2
|
||||||
|
// Mode 3: err2 -> err1
|
||||||
|
// Mode 7: err1 -> err2
|
||||||
{
|
{
|
||||||
D3D11_MAPPED_SUBRESOURCE mapped;
|
D3D11_MAPPED_SUBRESOURCE mapped;
|
||||||
HRESULT hr = pContext->Map( m_constBuffer.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped );
|
HRESULT hr = pContext->Map( m_constBuffer.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped );
|
||||||
@ -494,33 +500,39 @@ HRESULT GPUCompressBC::Compress( const Image& srcImage, const Image& destImage )
|
|||||||
(i & 1) ? m_err1UAV.Get() : m_err2UAV.Get(), uThreadGroupCount );
|
(i & 1) ? m_err1UAV.Get() : m_err2UAV.Get(), uThreadGroupCount );
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( UINT i = 0; i < 2; ++i )
|
if ( !m_skip3Subsets )
|
||||||
{
|
{
|
||||||
static const UINT modes[] = { 0, 2 };
|
// 3 subset modes tend to be used rarely and add significant compression time
|
||||||
|
for ( UINT i = 0; i < 2; ++i )
|
||||||
{
|
{
|
||||||
D3D11_MAPPED_SUBRESOURCE mapped;
|
static const UINT modes[] = { 0, 2 };
|
||||||
HRESULT hr = pContext->Map( m_constBuffer.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped );
|
// Mode 0: err2 -> err1
|
||||||
if ( FAILED(hr) )
|
// Mode 2: err1 -> err2
|
||||||
{
|
{
|
||||||
ResetContext( pContext );
|
D3D11_MAPPED_SUBRESOURCE mapped;
|
||||||
return hr;
|
HRESULT hr = pContext->Map( m_constBuffer.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped );
|
||||||
|
if ( FAILED(hr) )
|
||||||
|
{
|
||||||
|
ResetContext( pContext );
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConstantsBC6HBC7 param;
|
||||||
|
param.tex_width = static_cast<UINT>( srcImage.width );
|
||||||
|
param.num_block_x = static_cast<UINT>( xblocks );
|
||||||
|
param.format = m_bcformat;
|
||||||
|
param.mode_id = modes[i];
|
||||||
|
param.start_block_id = start_block_id;
|
||||||
|
param.num_total_blocks = num_total_blocks;
|
||||||
|
param.alpha_weight = m_alphaWeight;
|
||||||
|
memcpy( mapped.pData, ¶m, sizeof( param ) );
|
||||||
|
pContext->Unmap( m_constBuffer.Get(), 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstantsBC6HBC7 param;
|
pSRVs[1] = (i & 1) ? m_err1SRV.Get() : m_err2SRV.Get();
|
||||||
param.tex_width = static_cast<UINT>( srcImage.width );
|
RunComputeShader( pContext, m_BC7_tryMode02CS.Get(), pSRVs, 2, m_constBuffer.Get(),
|
||||||
param.num_block_x = static_cast<UINT>( xblocks );
|
(i & 1) ? m_err2UAV.Get() : m_err1UAV.Get(), uThreadGroupCount );
|
||||||
param.format = m_bcformat;
|
|
||||||
param.mode_id = modes[i];
|
|
||||||
param.start_block_id = start_block_id;
|
|
||||||
param.num_total_blocks = num_total_blocks;
|
|
||||||
param.alpha_weight = m_alphaWeight;
|
|
||||||
memcpy( mapped.pData, ¶m, sizeof( param ) );
|
|
||||||
pContext->Unmap( m_constBuffer.Get(), 0 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pSRVs[1] = (i & 1) ? m_err1SRV.Get() : m_err2SRV.Get();
|
|
||||||
RunComputeShader( pContext, m_BC7_tryMode02CS.Get(), pSRVs, 2, m_constBuffer.Get(),
|
|
||||||
(i & 1) ? m_err2UAV.Get() : m_err1UAV.Get(), uThreadGroupCount );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pSRVs[1] = m_err2SRV.Get();
|
pSRVs[1] = m_err2SRV.Get();
|
||||||
|
@ -23,7 +23,7 @@ public:
|
|||||||
|
|
||||||
HRESULT Initialize( _In_ ID3D11Device* pDevice );
|
HRESULT Initialize( _In_ ID3D11Device* pDevice );
|
||||||
|
|
||||||
HRESULT Prepare( _In_ size_t width, _In_ size_t height, _In_ DXGI_FORMAT format, _In_ float alphaWeight = 1.f );
|
HRESULT Prepare( _In_ size_t width, _In_ size_t height, _In_ DXGI_FORMAT format, _In_ float alphaWeight = 1.f, _In_ bool skip3subsets = true );
|
||||||
|
|
||||||
HRESULT Compress( _In_ const Image& srcImage, _In_ const Image& destImage );
|
HRESULT Compress( _In_ const Image& srcImage, _In_ const Image& destImage );
|
||||||
|
|
||||||
@ -33,6 +33,7 @@ private:
|
|||||||
DXGI_FORMAT m_bcformat;
|
DXGI_FORMAT m_bcformat;
|
||||||
DXGI_FORMAT m_srcformat;
|
DXGI_FORMAT m_srcformat;
|
||||||
float m_alphaWeight;
|
float m_alphaWeight;
|
||||||
|
bool m_skip3Subsets;
|
||||||
size_t m_width;
|
size_t m_width;
|
||||||
size_t m_height;
|
size_t m_height;
|
||||||
|
|
||||||
|
@ -521,6 +521,9 @@ namespace DirectX
|
|||||||
TEX_COMPRESS_UNIFORM = 0x40000,
|
TEX_COMPRESS_UNIFORM = 0x40000,
|
||||||
// Uniform color weighting for BC1-3 compression; by default uses perceptual weighting
|
// Uniform color weighting for BC1-3 compression; by default uses perceptual weighting
|
||||||
|
|
||||||
|
TEX_COMPRESS_BC7_USE_3SUBSETS = 0x80000,
|
||||||
|
// Enables exhaustive search for BC7 compress for mode 0 and 2; by default skips trying these modes
|
||||||
|
|
||||||
TEX_COMPRESS_SRGB_IN = 0x1000000,
|
TEX_COMPRESS_SRGB_IN = 0x1000000,
|
||||||
TEX_COMPRESS_SRGB_OUT = 0x2000000,
|
TEX_COMPRESS_SRGB_OUT = 0x2000000,
|
||||||
TEX_COMPRESS_SRGB = ( TEX_COMPRESS_SRGB_IN | TEX_COMPRESS_SRGB_OUT ),
|
TEX_COMPRESS_SRGB = ( TEX_COMPRESS_SRGB_IN | TEX_COMPRESS_SRGB_OUT ),
|
||||||
|
@ -32,7 +32,8 @@ inline static DWORD _GetBCFlags( _In_ DWORD compress )
|
|||||||
static_assert( TEX_COMPRESS_A_DITHER == BC_FLAGS_DITHER_A, "TEX_COMPRESS_* flags should match BC_FLAGS_*" );
|
static_assert( TEX_COMPRESS_A_DITHER == BC_FLAGS_DITHER_A, "TEX_COMPRESS_* flags should match BC_FLAGS_*" );
|
||||||
static_assert( TEX_COMPRESS_DITHER == (BC_FLAGS_DITHER_RGB | BC_FLAGS_DITHER_A), "TEX_COMPRESS_* flags should match BC_FLAGS_*" );
|
static_assert( TEX_COMPRESS_DITHER == (BC_FLAGS_DITHER_RGB | BC_FLAGS_DITHER_A), "TEX_COMPRESS_* flags should match BC_FLAGS_*" );
|
||||||
static_assert( TEX_COMPRESS_UNIFORM == BC_FLAGS_UNIFORM, "TEX_COMPRESS_* flags should match BC_FLAGS_*" );
|
static_assert( TEX_COMPRESS_UNIFORM == BC_FLAGS_UNIFORM, "TEX_COMPRESS_* flags should match BC_FLAGS_*" );
|
||||||
return ( compress & (BC_FLAGS_DITHER_RGB|BC_FLAGS_DITHER_A|BC_FLAGS_UNIFORM) );
|
static_assert( TEX_COMPRESS_BC7_USE_3SUBSETS == BC_FLAGS_USE_3SUBSETS, "TEX_COMPRESS_* flags should match BC_FLAGS_*" );
|
||||||
|
return ( compress & (BC_FLAGS_DITHER_RGB|BC_FLAGS_DITHER_A|BC_FLAGS_UNIFORM|BC_FLAGS_USE_3SUBSETS) );
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static DWORD _GetSRGBFlags( _In_ DWORD compress )
|
inline static DWORD _GetSRGBFlags( _In_ DWORD compress )
|
||||||
|
@ -216,7 +216,7 @@ HRESULT Compress( ID3D11Device* pDevice, const Image& srcImage, DXGI_FORMAT form
|
|||||||
if ( FAILED(hr) )
|
if ( FAILED(hr) )
|
||||||
return hr;
|
return hr;
|
||||||
|
|
||||||
hr = gpubc->Prepare( srcImage.width, srcImage.height, format, alphaWeight );
|
hr = gpubc->Prepare( srcImage.width, srcImage.height, format, alphaWeight, !(compress & TEX_COMPRESS_BC7_USE_3SUBSETS) );
|
||||||
if ( FAILED(hr) )
|
if ( FAILED(hr) )
|
||||||
return hr;
|
return hr;
|
||||||
|
|
||||||
@ -295,7 +295,7 @@ HRESULT Compress( ID3D11Device* pDevice, const Image* srcImages, size_t nimages,
|
|||||||
|
|
||||||
for( size_t level=0; level < metadata.mipLevels; ++level )
|
for( size_t level=0; level < metadata.mipLevels; ++level )
|
||||||
{
|
{
|
||||||
hr = gpubc->Prepare( w, h, format, alphaWeight );
|
hr = gpubc->Prepare( w, h, format, alphaWeight, !(compress & TEX_COMPRESS_BC7_USE_3SUBSETS) );
|
||||||
if ( FAILED(hr) )
|
if ( FAILED(hr) )
|
||||||
{
|
{
|
||||||
cImages.Release();
|
cImages.Release();
|
||||||
@ -346,7 +346,7 @@ HRESULT Compress( ID3D11Device* pDevice, const Image* srcImages, size_t nimages,
|
|||||||
|
|
||||||
for( size_t level=0; level < metadata.mipLevels; ++level )
|
for( size_t level=0; level < metadata.mipLevels; ++level )
|
||||||
{
|
{
|
||||||
hr = gpubc->Prepare( w, h, format, alphaWeight );
|
hr = gpubc->Prepare( w, h, format, alphaWeight, !(compress & TEX_COMPRESS_BC7_USE_3SUBSETS) );
|
||||||
if ( FAILED(hr) )
|
if ( FAILED(hr) )
|
||||||
{
|
{
|
||||||
cImages.Release();
|
cImages.Release();
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
using namespace DirectX;
|
using namespace DirectX;
|
||||||
using Microsoft::WRL::ComPtr;
|
using Microsoft::WRL::ComPtr;
|
||||||
|
|
||||||
enum OPTIONS // Note: dwOptions below assumes 32 or less options.
|
enum OPTIONS // Note: dwOptions below assumes 64 or less options.
|
||||||
{
|
{
|
||||||
OPT_WIDTH = 1,
|
OPT_WIDTH = 1,
|
||||||
OPT_HEIGHT,
|
OPT_HEIGHT,
|
||||||
@ -41,6 +41,7 @@ enum OPTIONS // Note: dwOptions below assumes 32 or less options.
|
|||||||
OPT_DDS_DWORD_ALIGN,
|
OPT_DDS_DWORD_ALIGN,
|
||||||
OPT_USE_DX10,
|
OPT_USE_DX10,
|
||||||
OPT_NOLOGO,
|
OPT_NOLOGO,
|
||||||
|
OPT_TIMING,
|
||||||
OPT_SEPALPHA,
|
OPT_SEPALPHA,
|
||||||
OPT_TYPELESS_UNORM,
|
OPT_TYPELESS_UNORM,
|
||||||
OPT_TYPELESS_FLOAT,
|
OPT_TYPELESS_FLOAT,
|
||||||
@ -55,10 +56,13 @@ enum OPTIONS // Note: dwOptions below assumes 32 or less options.
|
|||||||
OPT_ALPHA_WEIGHT,
|
OPT_ALPHA_WEIGHT,
|
||||||
OPT_NORMAL_MAP,
|
OPT_NORMAL_MAP,
|
||||||
OPT_NORMAL_MAP_AMPLITUDE,
|
OPT_NORMAL_MAP_AMPLITUDE,
|
||||||
|
OPT_COMPRESS_UNIFORM,
|
||||||
|
OPT_COMPRESS_MAX,
|
||||||
|
OPT_COMPRESS_DITHER,
|
||||||
OPT_MAX
|
OPT_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert( OPT_MAX <= 32, "dwOptions is a DWORD bitfield" );
|
static_assert( OPT_MAX <= 64, "dwOptions is a DWORD64 bitfield" );
|
||||||
|
|
||||||
struct SConversion
|
struct SConversion
|
||||||
{
|
{
|
||||||
@ -95,6 +99,7 @@ SValue g_pOptions[] =
|
|||||||
{ L"dword", OPT_DDS_DWORD_ALIGN },
|
{ L"dword", OPT_DDS_DWORD_ALIGN },
|
||||||
{ L"dx10", OPT_USE_DX10 },
|
{ L"dx10", OPT_USE_DX10 },
|
||||||
{ L"nologo", OPT_NOLOGO },
|
{ L"nologo", OPT_NOLOGO },
|
||||||
|
{ L"timing", OPT_TIMING },
|
||||||
{ L"sepalpha", OPT_SEPALPHA },
|
{ L"sepalpha", OPT_SEPALPHA },
|
||||||
{ L"tu", OPT_TYPELESS_UNORM },
|
{ L"tu", OPT_TYPELESS_UNORM },
|
||||||
{ L"tf", OPT_TYPELESS_FLOAT },
|
{ L"tf", OPT_TYPELESS_FLOAT },
|
||||||
@ -109,6 +114,9 @@ SValue g_pOptions[] =
|
|||||||
{ L"aw", OPT_ALPHA_WEIGHT },
|
{ L"aw", OPT_ALPHA_WEIGHT },
|
||||||
{ L"nmap", OPT_NORMAL_MAP },
|
{ L"nmap", OPT_NORMAL_MAP },
|
||||||
{ L"nmapamp", OPT_NORMAL_MAP_AMPLITUDE },
|
{ L"nmapamp", OPT_NORMAL_MAP_AMPLITUDE },
|
||||||
|
{ L"bcuniform", OPT_COMPRESS_UNIFORM },
|
||||||
|
{ L"bcmax", OPT_COMPRESS_MAX },
|
||||||
|
{ L"bcdither", OPT_COMPRESS_DITHER },
|
||||||
{ nullptr, 0 }
|
{ nullptr, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -454,8 +462,6 @@ void PrintUsage()
|
|||||||
wprintf( L" -wrap, -mirror texture addressing mode (wrap, mirror, or clamp)\n");
|
wprintf( L" -wrap, -mirror texture addressing mode (wrap, mirror, or clamp)\n");
|
||||||
wprintf( L" -pmalpha convert final texture to use premultiplied alpha\n");
|
wprintf( L" -pmalpha convert final texture to use premultiplied alpha\n");
|
||||||
wprintf( L" -pow2 resize to fit a power-of-2, respecting aspect ratio\n" );
|
wprintf( L" -pow2 resize to fit a power-of-2, respecting aspect ratio\n" );
|
||||||
wprintf( L" -aw <weight> BC7 GPU compressor weighting for alpha error metric\n"
|
|
||||||
L" (defaults to 1.0)\n" );
|
|
||||||
wprintf (L" -nmap <options> converts height-map to normal-map\n"
|
wprintf (L" -nmap <options> converts height-map to normal-map\n"
|
||||||
L" options must be one or more of\n"
|
L" options must be one or more of\n"
|
||||||
L" r, g, b, a, l, m, u, v, i, o\n" );
|
L" r, g, b, a, l, m, u, v, i, o\n" );
|
||||||
@ -468,10 +474,16 @@ void PrintUsage()
|
|||||||
wprintf( L"\n (DDS output only)\n");
|
wprintf( L"\n (DDS output only)\n");
|
||||||
wprintf( L" -dx10 Force use of 'DX10' extended header\n");
|
wprintf( L" -dx10 Force use of 'DX10' extended header\n");
|
||||||
wprintf( L"\n -nologo suppress copyright message\n");
|
wprintf( L"\n -nologo suppress copyright message\n");
|
||||||
|
wprintf( L" -timing Display elapsed processing time\n\n");
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
wprintf( L" -singleproc Do not use multi-threaded compression\n");
|
wprintf( L" -singleproc Do not use multi-threaded compression\n");
|
||||||
#endif
|
#endif
|
||||||
wprintf( L" -nogpu Do not use DirectCompute-based codecs\n");
|
wprintf( L" -nogpu Do not use DirectCompute-based codecs\n");
|
||||||
|
wprintf( L" -bcuniform Use uniform rather than perceptual weighting for BC1-3\n");
|
||||||
|
wprintf( L" -bcdither Use dithering for BC1-3\n");
|
||||||
|
wprintf( L" -bcmax Use exchaustive compression (BC7 only)\n");
|
||||||
|
wprintf( L" -aw <weight> BC7 GPU compressor weighting for alpha error metric\n"
|
||||||
|
L" (defaults to 1.0)\n" );
|
||||||
|
|
||||||
wprintf( L"\n");
|
wprintf( L"\n");
|
||||||
wprintf( L" <format>: ");
|
wprintf( L" <format>: ");
|
||||||
@ -628,6 +640,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
|||||||
DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN;
|
DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN;
|
||||||
DWORD dwFilter = TEX_FILTER_DEFAULT;
|
DWORD dwFilter = TEX_FILTER_DEFAULT;
|
||||||
DWORD dwSRGB = 0;
|
DWORD dwSRGB = 0;
|
||||||
|
DWORD dwCompress = TEX_COMPRESS_DEFAULT;
|
||||||
DWORD dwFilterOpts = 0;
|
DWORD dwFilterOpts = 0;
|
||||||
DWORD FileType = CODEC_DDS;
|
DWORD FileType = CODEC_DDS;
|
||||||
DWORD maxSize = 16384;
|
DWORD maxSize = 16384;
|
||||||
@ -652,7 +665,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Process command line
|
// Process command line
|
||||||
DWORD dwOptions = 0;
|
DWORD64 dwOptions = 0;
|
||||||
std::list<SConversion> conversion;
|
std::list<SConversion> conversion;
|
||||||
|
|
||||||
for(int iArg = 1; iArg < argc; iArg++)
|
for(int iArg = 1; iArg < argc; iArg++)
|
||||||
@ -671,20 +684,21 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
|||||||
|
|
||||||
DWORD dwOption = LookupByName(pArg, g_pOptions);
|
DWORD dwOption = LookupByName(pArg, g_pOptions);
|
||||||
|
|
||||||
if(!dwOption || (dwOptions & (1 << dwOption)))
|
if(!dwOption || (dwOptions & (DWORD64(1) << dwOption)))
|
||||||
{
|
{
|
||||||
PrintUsage();
|
PrintUsage();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
dwOptions |= 1 << dwOption;
|
dwOptions |= (DWORD64(1) << dwOption);
|
||||||
|
|
||||||
if( (OPT_NOLOGO != dwOption) && (OPT_TYPELESS_UNORM != dwOption) && (OPT_TYPELESS_FLOAT != dwOption)
|
if( (OPT_NOLOGO != dwOption) && (OPT_TIMING != dwOption) && (OPT_TYPELESS_UNORM != dwOption) && (OPT_TYPELESS_FLOAT != dwOption)
|
||||||
&& (OPT_SEPALPHA != dwOption) && (OPT_PREMUL_ALPHA != dwOption) && (OPT_EXPAND_LUMINANCE != dwOption)
|
&& (OPT_SEPALPHA != dwOption) && (OPT_PREMUL_ALPHA != dwOption) && (OPT_EXPAND_LUMINANCE != dwOption)
|
||||||
&& (OPT_TA_WRAP != dwOption) && (OPT_TA_MIRROR != dwOption)
|
&& (OPT_TA_WRAP != dwOption) && (OPT_TA_MIRROR != dwOption)
|
||||||
&& (OPT_FORCE_SINGLEPROC != dwOption) && (OPT_NOGPU != dwOption) && (OPT_FIT_POWEROF2 != dwOption)
|
&& (OPT_FORCE_SINGLEPROC != dwOption) && (OPT_NOGPU != dwOption) && (OPT_FIT_POWEROF2 != dwOption)
|
||||||
&& (OPT_SRGB != dwOption) && (OPT_SRGBI != dwOption) && (OPT_SRGBO != dwOption)
|
&& (OPT_SRGB != dwOption) && (OPT_SRGBI != dwOption) && (OPT_SRGBO != dwOption)
|
||||||
&& (OPT_HFLIP != dwOption) && (OPT_VFLIP != dwOption)
|
&& (OPT_HFLIP != dwOption) && (OPT_VFLIP != dwOption)
|
||||||
|
&& (OPT_COMPRESS_UNIFORM != dwOption) && (OPT_COMPRESS_MAX != dwOption) && (OPT_COMPRESS_DITHER != dwOption)
|
||||||
&& (OPT_DDS_DWORD_ALIGN != dwOption) && (OPT_USE_DX10 != dwOption) )
|
&& (OPT_DDS_DWORD_ALIGN != dwOption) && (OPT_USE_DX10 != dwOption) )
|
||||||
{
|
{
|
||||||
if(!*pValue)
|
if(!*pValue)
|
||||||
@ -919,6 +933,18 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case OPT_COMPRESS_UNIFORM:
|
||||||
|
dwCompress |= TEX_COMPRESS_UNIFORM;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OPT_COMPRESS_MAX:
|
||||||
|
dwCompress |= TEX_COMPRESS_BC7_USE_3SUBSETS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OPT_COMPRESS_DITHER:
|
||||||
|
dwCompress |= TEX_COMPRESS_DITHER;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -938,7 +964,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(~dwOptions & (1 << OPT_NOLOGO))
|
if(~dwOptions & (DWORD64(1) << OPT_NOLOGO))
|
||||||
PrintLogo();
|
PrintLogo();
|
||||||
|
|
||||||
// Work out out filename prefix and suffix
|
// Work out out filename prefix and suffix
|
||||||
@ -967,6 +993,19 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
|||||||
mipLevels = 1;
|
mipLevels = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LARGE_INTEGER qpcFreq;
|
||||||
|
if ( !QueryPerformanceFrequency( &qpcFreq ) )
|
||||||
|
{
|
||||||
|
qpcFreq.QuadPart = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LARGE_INTEGER qpcStart;
|
||||||
|
if ( !QueryPerformanceCounter( &qpcStart ) )
|
||||||
|
{
|
||||||
|
qpcStart.QuadPart = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Convert images
|
// Convert images
|
||||||
bool nonpow2warn = false;
|
bool nonpow2warn = false;
|
||||||
bool non4bc = false;
|
bool non4bc = false;
|
||||||
@ -997,9 +1036,9 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
|||||||
if ( _wcsicmp( ext, L".dds" ) == 0 )
|
if ( _wcsicmp( ext, L".dds" ) == 0 )
|
||||||
{
|
{
|
||||||
DWORD ddsFlags = DDS_FLAGS_NONE;
|
DWORD ddsFlags = DDS_FLAGS_NONE;
|
||||||
if ( dwOptions & (1 << OPT_DDS_DWORD_ALIGN) )
|
if ( dwOptions & (DWORD64(1) << OPT_DDS_DWORD_ALIGN) )
|
||||||
ddsFlags |= DDS_FLAGS_LEGACY_DWORD;
|
ddsFlags |= DDS_FLAGS_LEGACY_DWORD;
|
||||||
if ( dwOptions & (1 << OPT_EXPAND_LUMINANCE) )
|
if ( dwOptions & (DWORD64(1) << OPT_EXPAND_LUMINANCE) )
|
||||||
ddsFlags |= DDS_FLAGS_EXPAND_LUMINANCE;
|
ddsFlags |= DDS_FLAGS_EXPAND_LUMINANCE;
|
||||||
|
|
||||||
hr = LoadFromDDSFile( pConv->szSrc, ddsFlags, &info, *image );
|
hr = LoadFromDDSFile( pConv->szSrc, ddsFlags, &info, *image );
|
||||||
@ -1011,11 +1050,11 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
|||||||
|
|
||||||
if ( IsTypeless( info.format ) )
|
if ( IsTypeless( info.format ) )
|
||||||
{
|
{
|
||||||
if ( dwOptions & (1 << OPT_TYPELESS_UNORM) )
|
if ( dwOptions & (DWORD64(1) << OPT_TYPELESS_UNORM) )
|
||||||
{
|
{
|
||||||
info.format = MakeTypelessUNORM( info.format );
|
info.format = MakeTypelessUNORM( info.format );
|
||||||
}
|
}
|
||||||
else if ( dwOptions & (1 << OPT_TYPELESS_FLOAT) )
|
else if ( dwOptions & (DWORD64(1) << OPT_TYPELESS_FLOAT) )
|
||||||
{
|
{
|
||||||
info.format = MakeTypelessFLOAT( info.format );
|
info.format = MakeTypelessFLOAT( info.format );
|
||||||
}
|
}
|
||||||
@ -1089,7 +1128,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
|||||||
wprintf( L"\nWARNING: Target size exceeds maximum size for feature level (%u)\n", maxSize );
|
wprintf( L"\nWARNING: Target size exceeds maximum size for feature level (%u)\n", maxSize );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dwOptions & (1 << OPT_FIT_POWEROF2))
|
if (dwOptions & (DWORD64(1) << OPT_FIT_POWEROF2))
|
||||||
{
|
{
|
||||||
FitPowerOf2( info.width, info.height, twidth, theight, maxSize );
|
FitPowerOf2( info.width, info.height, twidth, theight, maxSize );
|
||||||
}
|
}
|
||||||
@ -1185,7 +1224,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
// --- Flip/Rotate -------------------------------------------------------------
|
// --- Flip/Rotate -------------------------------------------------------------
|
||||||
if ( dwOptions & ( (1 << OPT_HFLIP) | (1 << OPT_VFLIP) ) )
|
if ( dwOptions & ( (DWORD64(1) << OPT_HFLIP) | (DWORD64(1) << OPT_VFLIP) ) )
|
||||||
{
|
{
|
||||||
std::unique_ptr<ScratchImage> timage( new (std::nothrow) ScratchImage );
|
std::unique_ptr<ScratchImage> timage( new (std::nothrow) ScratchImage );
|
||||||
if ( !timage )
|
if ( !timage )
|
||||||
@ -1196,10 +1235,10 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
|||||||
|
|
||||||
DWORD dwFlags = 0;
|
DWORD dwFlags = 0;
|
||||||
|
|
||||||
if ( dwOptions & (1 << OPT_HFLIP) )
|
if ( dwOptions & (DWORD64(1) << OPT_HFLIP) )
|
||||||
dwFlags |= TEX_FR_FLIP_HORIZONTAL;
|
dwFlags |= TEX_FR_FLIP_HORIZONTAL;
|
||||||
|
|
||||||
if ( dwOptions & (1 << OPT_VFLIP) )
|
if ( dwOptions & (DWORD64(1) << OPT_VFLIP) )
|
||||||
dwFlags |= TEX_FR_FLIP_VERTICAL;
|
dwFlags |= TEX_FR_FLIP_VERTICAL;
|
||||||
|
|
||||||
assert( dwFlags != 0 );
|
assert( dwFlags != 0 );
|
||||||
@ -1266,7 +1305,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
// --- Convert -----------------------------------------------------------------
|
// --- Convert -----------------------------------------------------------------
|
||||||
if ( dwOptions & (1 << OPT_NORMAL_MAP) )
|
if ( dwOptions & (DWORD64(1) << OPT_NORMAL_MAP) )
|
||||||
{
|
{
|
||||||
std::unique_ptr<ScratchImage> timage( new (std::nothrow) ScratchImage );
|
std::unique_ptr<ScratchImage> timage( new (std::nothrow) ScratchImage );
|
||||||
if ( !timage )
|
if ( !timage )
|
||||||
@ -1491,7 +1530,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
// --- Premultiplied alpha (if requested) --------------------------------------
|
// --- Premultiplied alpha (if requested) --------------------------------------
|
||||||
if ( ( dwOptions & (1 << OPT_PREMUL_ALPHA) )
|
if ( ( dwOptions & (DWORD64(1) << OPT_PREMUL_ALPHA) )
|
||||||
&& HasAlpha( info.format )
|
&& HasAlpha( info.format )
|
||||||
&& info.format != DXGI_FORMAT_A8_UNORM )
|
&& info.format != DXGI_FORMAT_A8_UNORM )
|
||||||
{
|
{
|
||||||
@ -1594,7 +1633,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
|||||||
{
|
{
|
||||||
s_tryonce = true;
|
s_tryonce = true;
|
||||||
|
|
||||||
if ( !(dwOptions & (1 << OPT_NOGPU) ) )
|
if ( !(dwOptions & (DWORD64(1) << OPT_NOGPU) ) )
|
||||||
{
|
{
|
||||||
if ( !CreateDevice( pDevice.GetAddressOf() ) )
|
if ( !CreateDevice( pDevice.GetAddressOf() ) )
|
||||||
wprintf( L"\nWARNING: DirectCompute is not available, using BC6H / BC7 CPU codec\n" );
|
wprintf( L"\nWARNING: DirectCompute is not available, using BC6H / BC7 CPU codec\n" );
|
||||||
@ -1608,9 +1647,9 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD cflags = TEX_COMPRESS_DEFAULT;
|
DWORD cflags = dwCompress;
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
if ( bc6hbc7 && !(dwOptions & (1 << OPT_FORCE_SINGLEPROC) ) )
|
if ( bc6hbc7 && !(dwOptions & (DWORD64(1) << OPT_FORCE_SINGLEPROC) ) )
|
||||||
{
|
{
|
||||||
cflags |= TEX_COMPRESS_PARALLEL;
|
cflags |= TEX_COMPRESS_PARALLEL;
|
||||||
}
|
}
|
||||||
@ -1623,7 +1662,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
|||||||
|
|
||||||
if ( bc6hbc7 && pDevice )
|
if ( bc6hbc7 && pDevice )
|
||||||
{
|
{
|
||||||
hr = Compress( pDevice.Get(), img, nimg, info, tformat, dwSRGB, alphaWeight, *timage );
|
hr = Compress( pDevice.Get(), img, nimg, info, tformat, dwCompress | dwSRGB, alphaWeight, *timage );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1667,7 +1706,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
|||||||
{
|
{
|
||||||
// Aleady set TEX_ALPHA_MODE_PREMULTIPLIED
|
// Aleady set TEX_ALPHA_MODE_PREMULTIPLIED
|
||||||
}
|
}
|
||||||
else if ( dwOptions & (1 << OPT_SEPALPHA) )
|
else if ( dwOptions & (DWORD64(1) << OPT_SEPALPHA) )
|
||||||
{
|
{
|
||||||
info.SetAlphaMode(TEX_ALPHA_MODE_CUSTOM);
|
info.SetAlphaMode(TEX_ALPHA_MODE_CUSTOM);
|
||||||
}
|
}
|
||||||
@ -1717,7 +1756,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
|||||||
{
|
{
|
||||||
case CODEC_DDS:
|
case CODEC_DDS:
|
||||||
hr = SaveToDDSFile( img, nimg, info,
|
hr = SaveToDDSFile( img, nimg, info,
|
||||||
(dwOptions & (1 << OPT_USE_DX10) ) ? (DDS_FLAGS_FORCE_DX10_EXT|DDS_FLAGS_FORCE_DX10_EXT_MISC2) : DDS_FLAGS_NONE,
|
(dwOptions & (DWORD64(1) << OPT_USE_DX10) ) ? (DDS_FLAGS_FORCE_DX10_EXT|DDS_FLAGS_FORCE_DX10_EXT_MISC2) : DDS_FLAGS_NONE,
|
||||||
pConv->szDest );
|
pConv->szDest );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1745,5 +1784,15 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
|||||||
if ( non4bc )
|
if ( non4bc )
|
||||||
wprintf( L"\n WARNING: Direct3D requires BC image to be multiple of 4 in width & height\n" );
|
wprintf( L"\n WARNING: Direct3D requires BC image to be multiple of 4 in width & height\n" );
|
||||||
|
|
||||||
|
if(dwOptions & (DWORD64(1) << OPT_TIMING))
|
||||||
|
{
|
||||||
|
LARGE_INTEGER qpcEnd;
|
||||||
|
if ( QueryPerformanceCounter( &qpcEnd ) )
|
||||||
|
{
|
||||||
|
LONGLONG delta = qpcEnd.QuadPart - qpcStart.QuadPart;
|
||||||
|
wprintf( L"\n Processing time: %f seconds\n", double(delta) / double(qpcFreq.QuadPart) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user