[etcpak] Sync with upstream
This commit is contained in:
parent
d3352813ea
commit
becf5b1d23
|
@ -13,7 +13,6 @@ thirdparty_dir = "#thirdparty/etcpak/"
|
||||||
thirdparty_sources = [
|
thirdparty_sources = [
|
||||||
"Dither.cpp",
|
"Dither.cpp",
|
||||||
"ProcessDxtc.cpp",
|
"ProcessDxtc.cpp",
|
||||||
"ProcessRgtc.cpp",
|
|
||||||
"ProcessRGB.cpp",
|
"ProcessRGB.cpp",
|
||||||
"Tables.cpp",
|
"Tables.cpp",
|
||||||
]
|
]
|
||||||
|
|
|
@ -35,7 +35,6 @@
|
||||||
|
|
||||||
#include <ProcessDxtc.hpp>
|
#include <ProcessDxtc.hpp>
|
||||||
#include <ProcessRGB.hpp>
|
#include <ProcessRGB.hpp>
|
||||||
#include <ProcessRgtc.hpp>
|
|
||||||
|
|
||||||
EtcpakType _determine_etc_type(Image::UsedChannels p_channels) {
|
EtcpakType _determine_etc_type(Image::UsedChannels p_channels) {
|
||||||
switch (p_channels) {
|
switch (p_channels) {
|
||||||
|
@ -246,11 +245,11 @@ void _compress_etcpak(EtcpakType p_compresstype, Image *r_img) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EtcpakType::ETCPAK_TYPE_ETC2_R:
|
case EtcpakType::ETCPAK_TYPE_ETC2_R:
|
||||||
CompressEtc2R8(src_mip_read, dest_mip_write, blocks, mip_w);
|
CompressEacR(src_mip_read, dest_mip_write, blocks, mip_w);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EtcpakType::ETCPAK_TYPE_ETC2_RG:
|
case EtcpakType::ETCPAK_TYPE_ETC2_RG:
|
||||||
CompressEtc2RG8(src_mip_read, dest_mip_write, blocks, mip_w);
|
CompressEacRg(src_mip_read, dest_mip_write, blocks, mip_w);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EtcpakType::ETCPAK_TYPE_DXT1:
|
case EtcpakType::ETCPAK_TYPE_DXT1:
|
||||||
|
@ -263,11 +262,11 @@ void _compress_etcpak(EtcpakType p_compresstype, Image *r_img) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EtcpakType::ETCPAK_TYPE_RGTC_R:
|
case EtcpakType::ETCPAK_TYPE_RGTC_R:
|
||||||
CompressRgtcR(src_mip_read, dest_mip_write, blocks, mip_w);
|
CompressBc4(src_mip_read, dest_mip_write, blocks, mip_w);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EtcpakType::ETCPAK_TYPE_RGTC_RG:
|
case EtcpakType::ETCPAK_TYPE_RGTC_RG:
|
||||||
CompressRgtcRG(src_mip_read, dest_mip_write, blocks, mip_w);
|
CompressBc5(src_mip_read, dest_mip_write, blocks, mip_w);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -213,7 +213,7 @@ its functionality to IPv4 only.
|
||||||
## etcpak
|
## etcpak
|
||||||
|
|
||||||
- Upstream: https://github.com/wolfpld/etcpak
|
- Upstream: https://github.com/wolfpld/etcpak
|
||||||
- Version: 1.0 (153f0e04a18b93c277684b577365210adcf8e11c, 2022)
|
- Version: git (5380688660a3801aec4b25483366027fe0442d7b, 2024)
|
||||||
- License: BSD-3-Clause
|
- License: BSD-3-Clause
|
||||||
|
|
||||||
Files extracted from upstream source:
|
Files extracted from upstream source:
|
||||||
|
@ -225,12 +225,6 @@ Files extracted from upstream source:
|
||||||
```
|
```
|
||||||
- `AUTHORS.txt` and `LICENSE.txt`
|
- `AUTHORS.txt` and `LICENSE.txt`
|
||||||
|
|
||||||
Two files (`ProcessRGB.{cpp,hpp}`) have been modified to provide ETC2_R and ETC2_RG compression,
|
|
||||||
the changes are based on the existing code.
|
|
||||||
|
|
||||||
Two files (`ProcessRgtc.{cpp,hpp}`) have been added to provide RGTC compression implementation,
|
|
||||||
based on library's `ProcessDxtc.{cpp,hpp}`.
|
|
||||||
|
|
||||||
## fonts
|
## fonts
|
||||||
|
|
||||||
- `DroidSans*.woff2`:
|
- `DroidSans*.woff2`:
|
||||||
|
|
|
@ -739,18 +739,8 @@ static etcpak_force_inline uint64_t ProcessRGB_SSE( __m128i px0, __m128i px1, __
|
||||||
return uint64_t( ( uint64_t( to565( vmin ) ) << 16 ) | to565( vmax ) | ( uint64_t( vp ) << 32 ) );
|
return uint64_t( ( uint64_t( to565( vmin ) ) << 16 ) | to565( vmax ) | ( uint64_t( vp ) << 32 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
static etcpak_force_inline uint64_t ProcessAlpha_SSE( __m128i px0, __m128i px1, __m128i px2, __m128i px3 )
|
static etcpak_force_inline uint64_t ProcessOneChannel_SSE( __m128i a )
|
||||||
{
|
{
|
||||||
__m128i mask = _mm_setr_epi32( 0x0f0b0703, -1, -1, -1 );
|
|
||||||
|
|
||||||
__m128i m0 = _mm_shuffle_epi8( px0, mask );
|
|
||||||
__m128i m1 = _mm_shuffle_epi8( px1, _mm_shuffle_epi32( mask, _MM_SHUFFLE( 3, 3, 0, 3 ) ) );
|
|
||||||
__m128i m2 = _mm_shuffle_epi8( px2, _mm_shuffle_epi32( mask, _MM_SHUFFLE( 3, 0, 3, 3 ) ) );
|
|
||||||
__m128i m3 = _mm_shuffle_epi8( px3, _mm_shuffle_epi32( mask, _MM_SHUFFLE( 0, 3, 3, 3 ) ) );
|
|
||||||
__m128i m4 = _mm_or_si128( m0, m1 );
|
|
||||||
__m128i m5 = _mm_or_si128( m2, m3 );
|
|
||||||
__m128i a = _mm_or_si128( m4, m5 );
|
|
||||||
|
|
||||||
__m128i solidCmp = _mm_shuffle_epi8( a, _mm_setzero_si128() );
|
__m128i solidCmp = _mm_shuffle_epi8( a, _mm_setzero_si128() );
|
||||||
__m128i cmpRes = _mm_cmpeq_epi8( a, solidCmp );
|
__m128i cmpRes = _mm_cmpeq_epi8( a, solidCmp );
|
||||||
if( _mm_testc_si128( cmpRes, _mm_set1_epi32( -1 ) ) )
|
if( _mm_testc_si128( cmpRes, _mm_set1_epi32( -1 ) ) )
|
||||||
|
@ -800,6 +790,21 @@ static etcpak_force_inline uint64_t ProcessAlpha_SSE( __m128i px0, __m128i px1,
|
||||||
}
|
}
|
||||||
return (uint64_t)(uint16_t)_mm_cvtsi128_si32( minmax ) | ( data << 16 );
|
return (uint64_t)(uint16_t)_mm_cvtsi128_si32( minmax ) | ( data << 16 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static etcpak_force_inline uint64_t ProcessAlpha_SSE( __m128i px0, __m128i px1, __m128i px2, __m128i px3 )
|
||||||
|
{
|
||||||
|
__m128i mask = _mm_setr_epi32( 0x0f0b0703, -1, -1, -1 );
|
||||||
|
|
||||||
|
__m128i m0 = _mm_shuffle_epi8( px0, mask );
|
||||||
|
__m128i m1 = _mm_shuffle_epi8( px1, _mm_shuffle_epi32( mask, _MM_SHUFFLE( 3, 3, 0, 3 ) ) );
|
||||||
|
__m128i m2 = _mm_shuffle_epi8( px2, _mm_shuffle_epi32( mask, _MM_SHUFFLE( 3, 0, 3, 3 ) ) );
|
||||||
|
__m128i m3 = _mm_shuffle_epi8( px3, _mm_shuffle_epi32( mask, _MM_SHUFFLE( 0, 3, 3, 3 ) ) );
|
||||||
|
__m128i m4 = _mm_or_si128( m0, m1 );
|
||||||
|
__m128i m5 = _mm_or_si128( m2, m3 );
|
||||||
|
__m128i a = _mm_or_si128( m4, m5 );
|
||||||
|
|
||||||
|
return ProcessOneChannel_SSE( a );
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void CompressDxt1( const uint32_t* src, uint64_t* dst, uint32_t blocks, size_t width )
|
void CompressDxt1( const uint32_t* src, uint64_t* dst, uint32_t blocks, size_t width )
|
||||||
|
@ -954,3 +959,128 @@ void CompressDxt5( const uint32_t* src, uint64_t* dst, uint32_t blocks, size_t w
|
||||||
}
|
}
|
||||||
while( --blocks );
|
while( --blocks );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CompressBc4( const uint32_t* src, uint64_t* dst, uint32_t blocks, size_t width )
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
auto ptr = dst;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
#ifdef __SSE4_1__
|
||||||
|
__m128i px0 = _mm_loadu_si128( (__m128i*)( src + width * 0 ) );
|
||||||
|
__m128i px1 = _mm_loadu_si128( (__m128i*)( src + width * 1 ) );
|
||||||
|
__m128i px2 = _mm_loadu_si128( (__m128i*)( src + width * 2 ) );
|
||||||
|
__m128i px3 = _mm_loadu_si128( (__m128i*)( src + width * 3 ) );
|
||||||
|
|
||||||
|
src += 4;
|
||||||
|
if( ++i == width/4 )
|
||||||
|
{
|
||||||
|
src += width * 3;
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
__m128i mask = _mm_setr_epi32( 0x0c080400, -1, -1, -1 );
|
||||||
|
|
||||||
|
__m128i m0 = _mm_shuffle_epi8( px0, mask );
|
||||||
|
__m128i m1 = _mm_shuffle_epi8( px1, _mm_shuffle_epi32( mask, _MM_SHUFFLE( 3, 3, 0, 3 ) ) );
|
||||||
|
__m128i m2 = _mm_shuffle_epi8( px2, _mm_shuffle_epi32( mask, _MM_SHUFFLE( 3, 0, 3, 3 ) ) );
|
||||||
|
__m128i m3 = _mm_shuffle_epi8( px3, _mm_shuffle_epi32( mask, _MM_SHUFFLE( 0, 3, 3, 3 ) ) );
|
||||||
|
__m128i m4 = _mm_or_si128( m0, m1 );
|
||||||
|
__m128i m5 = _mm_or_si128( m2, m3 );
|
||||||
|
|
||||||
|
*ptr++ = ProcessOneChannel_SSE( _mm_or_si128( m4, m5 ) );
|
||||||
|
#else
|
||||||
|
uint8_t r[4*4];
|
||||||
|
auto rgba = src;
|
||||||
|
for( int i=0; i<4; i++ )
|
||||||
|
{
|
||||||
|
r[i*4] = rgba[0] & 0xff;
|
||||||
|
r[i*4+1] = rgba[1] & 0xff;
|
||||||
|
r[i*4+2] = rgba[2] & 0xff;
|
||||||
|
r[i*4+3] = rgba[3] & 0xff;
|
||||||
|
|
||||||
|
rgba += width;
|
||||||
|
}
|
||||||
|
|
||||||
|
src += 4;
|
||||||
|
if( ++i == width/4 )
|
||||||
|
{
|
||||||
|
src += width * 3;
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ptr++ = ProcessAlpha( r );
|
||||||
|
#endif
|
||||||
|
} while( --blocks );
|
||||||
|
}
|
||||||
|
|
||||||
|
void CompressBc5( const uint32_t* src, uint64_t* dst, uint32_t blocks, size_t width )
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
auto ptr = dst;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
#ifdef __SSE4_1__
|
||||||
|
__m128i px0 = _mm_loadu_si128( (__m128i*)( src + width * 0 ) );
|
||||||
|
__m128i px1 = _mm_loadu_si128( (__m128i*)( src + width * 1 ) );
|
||||||
|
__m128i px2 = _mm_loadu_si128( (__m128i*)( src + width * 2 ) );
|
||||||
|
__m128i px3 = _mm_loadu_si128( (__m128i*)( src + width * 3 ) );
|
||||||
|
|
||||||
|
src += 4;
|
||||||
|
if( ++i == width/4 )
|
||||||
|
{
|
||||||
|
src += width*3;
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
__m128i mask = _mm_setr_epi32( 0x0c080400, -1, -1, -1 );
|
||||||
|
|
||||||
|
__m128i m0 = _mm_shuffle_epi8( px0, mask );
|
||||||
|
__m128i m1 = _mm_shuffle_epi8( px1, _mm_shuffle_epi32( mask, _MM_SHUFFLE( 3, 3, 0, 3 ) ) );
|
||||||
|
__m128i m2 = _mm_shuffle_epi8( px2, _mm_shuffle_epi32( mask, _MM_SHUFFLE( 3, 0, 3, 3 ) ) );
|
||||||
|
__m128i m3 = _mm_shuffle_epi8( px3, _mm_shuffle_epi32( mask, _MM_SHUFFLE( 0, 3, 3, 3 ) ) );
|
||||||
|
__m128i m4 = _mm_or_si128( m0, m1 );
|
||||||
|
__m128i m5 = _mm_or_si128( m2, m3 );
|
||||||
|
|
||||||
|
*ptr++ = ProcessOneChannel_SSE( _mm_or_si128( m4, m5 ) );
|
||||||
|
|
||||||
|
mask = _mm_setr_epi32( 0x0d090501, -1, -1, -1 );
|
||||||
|
|
||||||
|
m0 = _mm_shuffle_epi8( px0, mask );
|
||||||
|
m1 = _mm_shuffle_epi8( px1, _mm_shuffle_epi32( mask, _MM_SHUFFLE( 3, 3, 0, 3 ) ) );
|
||||||
|
m2 = _mm_shuffle_epi8( px2, _mm_shuffle_epi32( mask, _MM_SHUFFLE( 3, 0, 3, 3 ) ) );
|
||||||
|
m3 = _mm_shuffle_epi8( px3, _mm_shuffle_epi32( mask, _MM_SHUFFLE( 0, 3, 3, 3 ) ) );
|
||||||
|
m4 = _mm_or_si128( m0, m1 );
|
||||||
|
m5 = _mm_or_si128( m2, m3 );
|
||||||
|
|
||||||
|
*ptr++ = ProcessOneChannel_SSE( _mm_or_si128( m4, m5 ) );
|
||||||
|
#else
|
||||||
|
uint8_t rg[4*4*2];
|
||||||
|
auto rgba = src;
|
||||||
|
for( int i=0; i<4; i++ )
|
||||||
|
{
|
||||||
|
rg[i*4] = rgba[0] & 0xff;
|
||||||
|
rg[i*4+1] = rgba[1] & 0xff;
|
||||||
|
rg[i*4+2] = rgba[2] & 0xff;
|
||||||
|
rg[i*4+3] = rgba[3] & 0xff;
|
||||||
|
|
||||||
|
rg[16+i*4] = (rgba[0] & 0xff00) >> 8;
|
||||||
|
rg[16+i*4+1] = (rgba[1] & 0xff00) >> 8;
|
||||||
|
rg[16+i*4+2] = (rgba[2] & 0xff00) >> 8;
|
||||||
|
rg[16+i*4+3] = (rgba[3] & 0xff00) >> 8;
|
||||||
|
|
||||||
|
rgba += width;
|
||||||
|
}
|
||||||
|
|
||||||
|
src += 4;
|
||||||
|
if( ++i == width/4 )
|
||||||
|
{
|
||||||
|
src += width*3;
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ptr++ = ProcessAlpha( rg );
|
||||||
|
*ptr++ = ProcessAlpha( &rg[16] );
|
||||||
|
#endif
|
||||||
|
} while( --blocks );
|
||||||
|
}
|
||||||
|
|
|
@ -8,4 +8,7 @@ void CompressDxt1( const uint32_t* src, uint64_t* dst, uint32_t blocks, size_t w
|
||||||
void CompressDxt1Dither( const uint32_t* src, uint64_t* dst, uint32_t blocks, size_t width );
|
void CompressDxt1Dither( const uint32_t* src, uint64_t* dst, uint32_t blocks, size_t width );
|
||||||
void CompressDxt5( const uint32_t* src, uint64_t* dst, uint32_t blocks, size_t width );
|
void CompressDxt5( const uint32_t* src, uint64_t* dst, uint32_t blocks, size_t width );
|
||||||
|
|
||||||
|
void CompressBc4( const uint32_t* src, uint64_t* dst, uint32_t blocks, size_t width );
|
||||||
|
void CompressBc5( const uint32_t* src, uint64_t* dst, uint32_t blocks, size_t width );
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -3266,16 +3266,21 @@ etcpak_force_inline static int16x8_t WidenMultiplier_EAC_NEON( int16x8_t multipl
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
template<bool checkSolid = true>
|
||||||
static etcpak_force_inline uint64_t ProcessAlpha_ETC2( const uint8_t* src )
|
static etcpak_force_inline uint64_t ProcessAlpha_ETC2( const uint8_t* src )
|
||||||
{
|
{
|
||||||
#if defined __SSE4_1__
|
#if defined __SSE4_1__
|
||||||
// Check solid
|
|
||||||
__m128i s = _mm_loadu_si128( (__m128i*)src );
|
__m128i s = _mm_loadu_si128( (__m128i*)src );
|
||||||
__m128i solidCmp = _mm_set1_epi8( src[0] );
|
|
||||||
__m128i cmpRes = _mm_cmpeq_epi8( s, solidCmp );
|
if( checkSolid )
|
||||||
if( _mm_testc_si128( cmpRes, _mm_set1_epi32( -1 ) ) )
|
|
||||||
{
|
{
|
||||||
return src[0];
|
// Check solid
|
||||||
|
__m128i solidCmp = _mm_set1_epi8( src[0] );
|
||||||
|
__m128i cmpRes = _mm_cmpeq_epi8( s, solidCmp );
|
||||||
|
if( _mm_testc_si128( cmpRes, _mm_set1_epi32( -1 ) ) )
|
||||||
|
{
|
||||||
|
return src[0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate min, max
|
// Calculate min, max
|
||||||
|
@ -3684,12 +3689,15 @@ static etcpak_force_inline uint64_t ProcessAlpha_ETC2( const uint8_t* src )
|
||||||
int srcMid;
|
int srcMid;
|
||||||
uint8x16_t srcAlphaBlock = vld1q_u8( src );
|
uint8x16_t srcAlphaBlock = vld1q_u8( src );
|
||||||
{
|
{
|
||||||
uint8_t ref = src[0];
|
if( checkSolid )
|
||||||
uint8x16_t a0 = vdupq_n_u8( ref );
|
{
|
||||||
uint8x16_t r = vceqq_u8( srcAlphaBlock, a0 );
|
uint8_t ref = src[0];
|
||||||
int64x2_t m = vreinterpretq_s64_u8( r );
|
uint8x16_t a0 = vdupq_n_u8( ref );
|
||||||
if( m[0] == -1 && m[1] == -1 )
|
uint8x16_t r = vceqq_u8( srcAlphaBlock, a0 );
|
||||||
return ref;
|
int64x2_t m = vreinterpretq_s64_u8( r );
|
||||||
|
if( m[0] == -1 && m[1] == -1 )
|
||||||
|
return ref;
|
||||||
|
}
|
||||||
|
|
||||||
// srcRange
|
// srcRange
|
||||||
#ifdef __aarch64__
|
#ifdef __aarch64__
|
||||||
|
@ -3759,6 +3767,7 @@ static etcpak_force_inline uint64_t ProcessAlpha_ETC2( const uint8_t* src )
|
||||||
#undef EAC_RECONSTRUCT_VALUE
|
#undef EAC_RECONSTRUCT_VALUE
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
if( checkSolid )
|
||||||
{
|
{
|
||||||
bool solid = true;
|
bool solid = true;
|
||||||
const uint8_t* ptr = src + 1;
|
const uint8_t* ptr = src + 1;
|
||||||
|
@ -3849,7 +3858,6 @@ static etcpak_force_inline uint64_t ProcessAlpha_ETC2( const uint8_t* src )
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CompressEtc1Alpha( const uint32_t* src, uint64_t* dst, uint32_t blocks, size_t width )
|
void CompressEtc1Alpha( const uint32_t* src, uint64_t* dst, uint32_t blocks, size_t width )
|
||||||
{
|
{
|
||||||
int w = 0;
|
int w = 0;
|
||||||
|
@ -4176,14 +4184,13 @@ void CompressEtc2Rgba( const uint32_t* src, uint64_t* dst, uint32_t blocks, size
|
||||||
src += width * 3;
|
src += width * 3;
|
||||||
w = 0;
|
w = 0;
|
||||||
}
|
}
|
||||||
*dst++ = ProcessAlpha_ETC2( alpha );
|
*dst++ = ProcessAlpha_ETC2<true>( alpha );
|
||||||
*dst++ = ProcessRGB_ETC2( (uint8_t*)rgba, useHeuristics );
|
*dst++ = ProcessRGB_ETC2( (uint8_t*)rgba, useHeuristics );
|
||||||
}
|
}
|
||||||
while( --blocks );
|
while( --blocks );
|
||||||
}
|
}
|
||||||
|
|
||||||
// -- GODOT start --
|
void CompressEacR( const uint32_t* src, uint64_t* dst, uint32_t blocks, size_t width )
|
||||||
void CompressEtc2R8( const uint32_t* src, uint64_t* dst, uint32_t blocks, size_t width )
|
|
||||||
{
|
{
|
||||||
int w = 0;
|
int w = 0;
|
||||||
uint8_t r[4*4];
|
uint8_t r[4*4];
|
||||||
|
@ -4239,12 +4246,12 @@ void CompressEtc2R8( const uint32_t* src, uint64_t* dst, uint32_t blocks, size_t
|
||||||
src += width * 3;
|
src += width * 3;
|
||||||
w = 0;
|
w = 0;
|
||||||
}
|
}
|
||||||
*dst++ = ProcessAlpha_ETC2( r );
|
*dst++ = ProcessAlpha_ETC2<false>( r );
|
||||||
}
|
}
|
||||||
while( --blocks );
|
while( --blocks );
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompressEtc2RG8( const uint32_t* src, uint64_t* dst, uint32_t blocks, size_t width )
|
void CompressEacRg( const uint32_t* src, uint64_t* dst, uint32_t blocks, size_t width )
|
||||||
{
|
{
|
||||||
int w = 0;
|
int w = 0;
|
||||||
uint8_t rg[4*4*2];
|
uint8_t rg[4*4*2];
|
||||||
|
@ -4300,15 +4307,15 @@ void CompressEtc2RG8( const uint32_t* src, uint64_t* dst, uint32_t blocks, size_
|
||||||
src += width;
|
src += width;
|
||||||
v = *src;
|
v = *src;
|
||||||
*ptrr++ = (v & 0xff0000) >> 16;
|
*ptrr++ = (v & 0xff0000) >> 16;
|
||||||
*ptrg++ = (v & 0xff00) >> 8;
|
*ptrg++ = (v & 0xff00) >> 8;
|
||||||
src += width;
|
src += width;
|
||||||
v = *src;
|
v = *src;
|
||||||
*ptrr++ = (v & 0xff0000) >> 16;
|
*ptrr++ = (v & 0xff0000) >> 16;
|
||||||
*ptrg++ = (v & 0xff00) >> 8;
|
*ptrg++ = (v & 0xff00) >> 8;
|
||||||
src += width;
|
src += width;
|
||||||
v = *src;
|
v = *src;
|
||||||
*ptrr++ = (v & 0xff0000) >> 16;
|
*ptrr++ = (v & 0xff0000) >> 16;
|
||||||
*ptrg++ = (v & 0xff00) >> 8;
|
*ptrg++ = (v & 0xff00) >> 8;
|
||||||
src -= width * 3 - 1;
|
src -= width * 3 - 1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -4317,9 +4324,8 @@ void CompressEtc2RG8( const uint32_t* src, uint64_t* dst, uint32_t blocks, size_
|
||||||
src += width * 3;
|
src += width * 3;
|
||||||
w = 0;
|
w = 0;
|
||||||
}
|
}
|
||||||
*dst++ = ProcessAlpha_ETC2( rg );
|
*dst++ = ProcessAlpha_ETC2<false>( rg );
|
||||||
*dst++ = ProcessAlpha_ETC2( &rg[16] );
|
*dst++ = ProcessAlpha_ETC2<false>( &rg[16] );
|
||||||
}
|
}
|
||||||
while( --blocks );
|
while( --blocks );
|
||||||
}
|
}
|
||||||
// -- GODOT end --
|
|
||||||
|
|
|
@ -9,8 +9,8 @@ void CompressEtc1Rgb( const uint32_t* src, uint64_t* dst, uint32_t blocks, size_
|
||||||
void CompressEtc1RgbDither( const uint32_t* src, uint64_t* dst, uint32_t blocks, size_t width );
|
void CompressEtc1RgbDither( const uint32_t* src, uint64_t* dst, uint32_t blocks, size_t width );
|
||||||
void CompressEtc2Rgb( const uint32_t* src, uint64_t* dst, uint32_t blocks, size_t width, bool useHeuristics );
|
void CompressEtc2Rgb( const uint32_t* src, uint64_t* dst, uint32_t blocks, size_t width, bool useHeuristics );
|
||||||
void CompressEtc2Rgba( const uint32_t* src, uint64_t* dst, uint32_t blocks, size_t width, bool useHeuristics );
|
void CompressEtc2Rgba( const uint32_t* src, uint64_t* dst, uint32_t blocks, size_t width, bool useHeuristics );
|
||||||
// -- GODOT start --
|
|
||||||
void CompressEtc2R8( const uint32_t* src, uint64_t* dst, uint32_t blocks, size_t width );
|
void CompressEacR( const uint32_t* src, uint64_t* dst, uint32_t blocks, size_t width );
|
||||||
void CompressEtc2RG8( const uint32_t* src, uint64_t* dst, uint32_t blocks, size_t width );
|
void CompressEacRg( const uint32_t* src, uint64_t* dst, uint32_t blocks, size_t width );
|
||||||
// -- GODOT end --
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,265 +0,0 @@
|
||||||
// -- GODOT start --
|
|
||||||
|
|
||||||
#include "ForceInline.hpp"
|
|
||||||
#include "ProcessRgtc.hpp"
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#if defined __AVX__ && !defined __SSE4_1__
|
|
||||||
# define __SSE4_1__
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined __SSE4_1__ || defined __AVX2__
|
|
||||||
# ifdef _MSC_VER
|
|
||||||
# include <intrin.h>
|
|
||||||
# else
|
|
||||||
# include <x86intrin.h>
|
|
||||||
# ifndef _mm256_cvtsi256_si32
|
|
||||||
# define _mm256_cvtsi256_si32( v ) ( _mm_cvtsi128_si32( _mm256_castsi256_si128( v ) ) )
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static const uint8_t AlphaIndexTable[8] = { 1, 7, 6, 5, 4, 3, 2, 0 };
|
|
||||||
|
|
||||||
static const uint8_t AlphaIndexTable_SSE[64] = {
|
|
||||||
9, 15, 14, 13, 12, 11, 10, 8, 57, 63, 62, 61, 60, 59, 58, 56,
|
|
||||||
49, 55, 54, 53, 52, 51, 50, 48, 41, 47, 46, 45, 44, 43, 42, 40,
|
|
||||||
33, 39, 38, 37, 36, 35, 34, 32, 25, 31, 30, 29, 28, 27, 26, 24,
|
|
||||||
17, 23, 22, 21, 20, 19, 18, 16, 1, 7, 6, 5, 4, 3, 2, 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const uint16_t DivTableAlpha[256] = {
|
|
||||||
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xe38e, 0xcccc, 0xba2e, 0xaaaa, 0x9d89, 0x9249, 0x8888, 0x8000,
|
|
||||||
0x7878, 0x71c7, 0x6bca, 0x6666, 0x6186, 0x5d17, 0x590b, 0x5555, 0x51eb, 0x4ec4, 0x4bda, 0x4924, 0x469e, 0x4444, 0x4210, 0x4000,
|
|
||||||
0x3e0f, 0x3c3c, 0x3a83, 0x38e3, 0x3759, 0x35e5, 0x3483, 0x3333, 0x31f3, 0x30c3, 0x2fa0, 0x2e8b, 0x2d82, 0x2c85, 0x2b93, 0x2aaa,
|
|
||||||
0x29cb, 0x28f5, 0x2828, 0x2762, 0x26a4, 0x25ed, 0x253c, 0x2492, 0x23ee, 0x234f, 0x22b6, 0x2222, 0x2192, 0x2108, 0x2082, 0x2000,
|
|
||||||
0x1f81, 0x1f07, 0x1e91, 0x1e1e, 0x1dae, 0x1d41, 0x1cd8, 0x1c71, 0x1c0e, 0x1bac, 0x1b4e, 0x1af2, 0x1a98, 0x1a41, 0x19ec, 0x1999,
|
|
||||||
0x1948, 0x18f9, 0x18ac, 0x1861, 0x1818, 0x17d0, 0x178a, 0x1745, 0x1702, 0x16c1, 0x1681, 0x1642, 0x1605, 0x15c9, 0x158e, 0x1555,
|
|
||||||
0x151d, 0x14e5, 0x14af, 0x147a, 0x1446, 0x1414, 0x13e2, 0x13b1, 0x1381, 0x1352, 0x1323, 0x12f6, 0x12c9, 0x129e, 0x1273, 0x1249,
|
|
||||||
0x121f, 0x11f7, 0x11cf, 0x11a7, 0x1181, 0x115b, 0x1135, 0x1111, 0x10ec, 0x10c9, 0x10a6, 0x1084, 0x1062, 0x1041, 0x1020, 0x1000,
|
|
||||||
0x0fe0, 0x0fc0, 0x0fa2, 0x0f83, 0x0f66, 0x0f48, 0x0f2b, 0x0f0f, 0x0ef2, 0x0ed7, 0x0ebb, 0x0ea0, 0x0e86, 0x0e6c, 0x0e52, 0x0e38,
|
|
||||||
0x0e1f, 0x0e07, 0x0dee, 0x0dd6, 0x0dbe, 0x0da7, 0x0d90, 0x0d79, 0x0d62, 0x0d4c, 0x0d36, 0x0d20, 0x0d0b, 0x0cf6, 0x0ce1, 0x0ccc,
|
|
||||||
0x0cb8, 0x0ca4, 0x0c90, 0x0c7c, 0x0c69, 0x0c56, 0x0c43, 0x0c30, 0x0c1e, 0x0c0c, 0x0bfa, 0x0be8, 0x0bd6, 0x0bc5, 0x0bb3, 0x0ba2,
|
|
||||||
0x0b92, 0x0b81, 0x0b70, 0x0b60, 0x0b50, 0x0b40, 0x0b30, 0x0b21, 0x0b11, 0x0b02, 0x0af3, 0x0ae4, 0x0ad6, 0x0ac7, 0x0ab8, 0x0aaa,
|
|
||||||
0x0a9c, 0x0a8e, 0x0a80, 0x0a72, 0x0a65, 0x0a57, 0x0a4a, 0x0a3d, 0x0a30, 0x0a23, 0x0a16, 0x0a0a, 0x09fd, 0x09f1, 0x09e4, 0x09d8,
|
|
||||||
0x09cc, 0x09c0, 0x09b4, 0x09a9, 0x099d, 0x0991, 0x0986, 0x097b, 0x0970, 0x0964, 0x095a, 0x094f, 0x0944, 0x0939, 0x092f, 0x0924,
|
|
||||||
0x091a, 0x090f, 0x0905, 0x08fb, 0x08f1, 0x08e7, 0x08dd, 0x08d3, 0x08ca, 0x08c0, 0x08b7, 0x08ad, 0x08a4, 0x089a, 0x0891, 0x0888,
|
|
||||||
0x087f, 0x0876, 0x086d, 0x0864, 0x085b, 0x0853, 0x084a, 0x0842, 0x0839, 0x0831, 0x0828, 0x0820, 0x0818, 0x0810, 0x0808, 0x0800,
|
|
||||||
};
|
|
||||||
|
|
||||||
static etcpak_force_inline uint64_t ProcessAlpha( const uint8_t* src )
|
|
||||||
{
|
|
||||||
uint8_t solid8 = *src;
|
|
||||||
uint16_t solid16 = uint16_t( solid8 ) | ( uint16_t( solid8 ) << 8 );
|
|
||||||
uint32_t solid32 = uint32_t( solid16 ) | ( uint32_t( solid16 ) << 16 );
|
|
||||||
uint64_t solid64 = uint64_t( solid32 ) | ( uint64_t( solid32 ) << 32 );
|
|
||||||
if( memcmp( src, &solid64, 8 ) == 0 && memcmp( src+8, &solid64, 8 ) == 0 )
|
|
||||||
{
|
|
||||||
return solid8;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t min = src[0];
|
|
||||||
uint8_t max = min;
|
|
||||||
for( int i=1; i<16; i++ )
|
|
||||||
{
|
|
||||||
const auto v = src[i];
|
|
||||||
if( v > max ) max = v;
|
|
||||||
else if( v < min ) min = v;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t range = ( 8 << 13 ) / ( 1 + max - min );
|
|
||||||
uint64_t data = 0;
|
|
||||||
for( int i=0; i<16; i++ )
|
|
||||||
{
|
|
||||||
uint8_t a = src[i] - min;
|
|
||||||
uint64_t idx = AlphaIndexTable[( a * range ) >> 13];
|
|
||||||
data |= idx << (i*3);
|
|
||||||
}
|
|
||||||
|
|
||||||
return max | ( min << 8 ) | ( data << 16 );
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __SSE4_1__
|
|
||||||
static etcpak_force_inline uint64_t Process_Alpha_SSE( __m128i a )
|
|
||||||
{
|
|
||||||
__m128i solidCmp = _mm_shuffle_epi8( a, _mm_setzero_si128() );
|
|
||||||
__m128i cmpRes = _mm_cmpeq_epi8( a, solidCmp );
|
|
||||||
if( _mm_testc_si128( cmpRes, _mm_set1_epi32( -1 ) ) )
|
|
||||||
{
|
|
||||||
return _mm_cvtsi128_si32( a ) & 0xFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
__m128i a1 = _mm_shuffle_epi32( a, _MM_SHUFFLE( 2, 3, 0, 1 ) );
|
|
||||||
__m128i max1 = _mm_max_epu8( a, a1 );
|
|
||||||
__m128i min1 = _mm_min_epu8( a, a1 );
|
|
||||||
__m128i amax2 = _mm_shuffle_epi32( max1, _MM_SHUFFLE( 0, 0, 2, 2 ) );
|
|
||||||
__m128i amin2 = _mm_shuffle_epi32( min1, _MM_SHUFFLE( 0, 0, 2, 2 ) );
|
|
||||||
__m128i max2 = _mm_max_epu8( max1, amax2 );
|
|
||||||
__m128i min2 = _mm_min_epu8( min1, amin2 );
|
|
||||||
__m128i amax3 = _mm_alignr_epi8( max2, max2, 2 );
|
|
||||||
__m128i amin3 = _mm_alignr_epi8( min2, min2, 2 );
|
|
||||||
__m128i max3 = _mm_max_epu8( max2, amax3 );
|
|
||||||
__m128i min3 = _mm_min_epu8( min2, amin3 );
|
|
||||||
__m128i amax4 = _mm_alignr_epi8( max3, max3, 1 );
|
|
||||||
__m128i amin4 = _mm_alignr_epi8( min3, min3, 1 );
|
|
||||||
__m128i max = _mm_max_epu8( max3, amax4 );
|
|
||||||
__m128i min = _mm_min_epu8( min3, amin4 );
|
|
||||||
__m128i minmax = _mm_unpacklo_epi8( max, min );
|
|
||||||
|
|
||||||
__m128i r = _mm_sub_epi8( max, min );
|
|
||||||
int range = _mm_cvtsi128_si32( r ) & 0xFF;
|
|
||||||
__m128i rv = _mm_set1_epi16( DivTableAlpha[range] );
|
|
||||||
|
|
||||||
__m128i v = _mm_sub_epi8( a, min );
|
|
||||||
|
|
||||||
__m128i lo16 = _mm_unpacklo_epi8( v, _mm_setzero_si128() );
|
|
||||||
__m128i hi16 = _mm_unpackhi_epi8( v, _mm_setzero_si128() );
|
|
||||||
|
|
||||||
__m128i lomul = _mm_mulhi_epu16( lo16, rv );
|
|
||||||
__m128i himul = _mm_mulhi_epu16( hi16, rv );
|
|
||||||
|
|
||||||
__m128i p0 = _mm_packus_epi16( lomul, himul );
|
|
||||||
__m128i p1 = _mm_or_si128( _mm_and_si128( p0, _mm_set1_epi16( 0x3F ) ), _mm_srai_epi16( _mm_and_si128( p0, _mm_set1_epi16( 0x3F00 ) ), 5 ) );
|
|
||||||
__m128i p2 = _mm_packus_epi16( p1, p1 );
|
|
||||||
|
|
||||||
uint64_t pi = _mm_cvtsi128_si64( p2 );
|
|
||||||
uint64_t data = 0;
|
|
||||||
for( int i=0; i<8; i++ )
|
|
||||||
{
|
|
||||||
uint64_t idx = AlphaIndexTable_SSE[(pi>>(i*8)) & 0x3F];
|
|
||||||
data |= idx << (i*6);
|
|
||||||
}
|
|
||||||
return (uint64_t)(uint16_t)_mm_cvtsi128_si32( minmax ) | ( data << 16 );
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void CompressRgtcR(const uint32_t *src, uint64_t *dst, uint32_t blocks, size_t width)
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
auto ptr = dst;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
#ifdef __SSE4_1__
|
|
||||||
__m128i px0 = _mm_loadu_si128( (__m128i*)( src + width * 0 ) );
|
|
||||||
__m128i px1 = _mm_loadu_si128( (__m128i*)( src + width * 1 ) );
|
|
||||||
__m128i px2 = _mm_loadu_si128( (__m128i*)( src + width * 2 ) );
|
|
||||||
__m128i px3 = _mm_loadu_si128( (__m128i*)( src + width * 3 ) );
|
|
||||||
|
|
||||||
src += 4;
|
|
||||||
if (++i == width / 4)
|
|
||||||
{
|
|
||||||
src += width * 3;
|
|
||||||
i = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
__m128i mask = _mm_setr_epi32( 0x0c080400, -1, -1, -1 );
|
|
||||||
|
|
||||||
__m128i m0 = _mm_shuffle_epi8( px0, mask );
|
|
||||||
__m128i m1 = _mm_shuffle_epi8( px1, _mm_shuffle_epi32( mask, _MM_SHUFFLE( 3, 3, 0, 3 ) ) );
|
|
||||||
__m128i m2 = _mm_shuffle_epi8( px2, _mm_shuffle_epi32( mask, _MM_SHUFFLE( 3, 0, 3, 3 ) ) );
|
|
||||||
__m128i m3 = _mm_shuffle_epi8( px3, _mm_shuffle_epi32( mask, _MM_SHUFFLE( 0, 3, 3, 3 ) ) );
|
|
||||||
__m128i m4 = _mm_or_si128( m0, m1 );
|
|
||||||
__m128i m5 = _mm_or_si128( m2, m3 );
|
|
||||||
|
|
||||||
*ptr++ = Process_Alpha_SSE(_mm_or_si128( m4, m5 ));
|
|
||||||
#else
|
|
||||||
uint8_t r[4 * 4];
|
|
||||||
auto rgba = src;
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
r[i * 4] = rgba[0] & 0xff;
|
|
||||||
r[i * 4 + 1] = rgba[1] & 0xff;
|
|
||||||
r[i * 4 + 2] = rgba[2] & 0xff;
|
|
||||||
r[i * 4 + 3] = rgba[3] & 0xff;
|
|
||||||
|
|
||||||
rgba += width;
|
|
||||||
}
|
|
||||||
|
|
||||||
src += 4;
|
|
||||||
if (++i == width / 4)
|
|
||||||
{
|
|
||||||
src += width * 3;
|
|
||||||
i = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
*ptr++ = ProcessAlpha(r);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
while (--blocks);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CompressRgtcRG(const uint32_t *src, uint64_t *dst, uint32_t blocks, size_t width)
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
auto ptr = dst;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
#ifdef __SSE4_1__
|
|
||||||
__m128i px0 = _mm_loadu_si128( (__m128i*)( src + width * 0 ) );
|
|
||||||
__m128i px1 = _mm_loadu_si128( (__m128i*)( src + width * 1 ) );
|
|
||||||
__m128i px2 = _mm_loadu_si128( (__m128i*)( src + width * 2 ) );
|
|
||||||
__m128i px3 = _mm_loadu_si128( (__m128i*)( src + width * 3 ) );
|
|
||||||
|
|
||||||
src += 4;
|
|
||||||
if (++i == width / 4)
|
|
||||||
{
|
|
||||||
src += width * 3;
|
|
||||||
i = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
__m128i mask = _mm_setr_epi32( 0x0c080400, -1, -1, -1 );
|
|
||||||
|
|
||||||
__m128i m0 = _mm_shuffle_epi8( px0, mask );
|
|
||||||
__m128i m1 = _mm_shuffle_epi8( px1, _mm_shuffle_epi32( mask, _MM_SHUFFLE( 3, 3, 0, 3 ) ) );
|
|
||||||
__m128i m2 = _mm_shuffle_epi8( px2, _mm_shuffle_epi32( mask, _MM_SHUFFLE( 3, 0, 3, 3 ) ) );
|
|
||||||
__m128i m3 = _mm_shuffle_epi8( px3, _mm_shuffle_epi32( mask, _MM_SHUFFLE( 0, 3, 3, 3 ) ) );
|
|
||||||
__m128i m4 = _mm_or_si128( m0, m1 );
|
|
||||||
__m128i m5 = _mm_or_si128( m2, m3 );
|
|
||||||
|
|
||||||
*ptr++ = Process_Alpha_SSE(_mm_or_si128( m4, m5 ));
|
|
||||||
|
|
||||||
mask = _mm_setr_epi32( 0x0d090501, -1, -1, -1 );
|
|
||||||
|
|
||||||
m0 = _mm_shuffle_epi8( px0, mask );
|
|
||||||
m1 = _mm_shuffle_epi8( px1, _mm_shuffle_epi32( mask, _MM_SHUFFLE( 3, 3, 0, 3 ) ) );
|
|
||||||
m2 = _mm_shuffle_epi8( px2, _mm_shuffle_epi32( mask, _MM_SHUFFLE( 3, 0, 3, 3 ) ) );
|
|
||||||
m3 = _mm_shuffle_epi8( px3, _mm_shuffle_epi32( mask, _MM_SHUFFLE( 0, 3, 3, 3 ) ) );
|
|
||||||
m4 = _mm_or_si128( m0, m1 );
|
|
||||||
m5 = _mm_or_si128( m2, m3 );
|
|
||||||
|
|
||||||
*ptr++ = Process_Alpha_SSE(_mm_or_si128( m4, m5 ));
|
|
||||||
#else
|
|
||||||
uint8_t rg[4 * 4 * 2];
|
|
||||||
auto rgba = src;
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
rg[i * 4] = rgba[0] & 0xff;
|
|
||||||
rg[i * 4 + 1] = rgba[1] & 0xff;
|
|
||||||
rg[i * 4 + 2] = rgba[2] & 0xff;
|
|
||||||
rg[i * 4 + 3] = rgba[3] & 0xff;
|
|
||||||
|
|
||||||
rg[16 + i * 4] = (rgba[0] & 0xff00) >> 8;
|
|
||||||
rg[16 + i * 4 + 1] = (rgba[1] & 0xff00) >> 8;
|
|
||||||
rg[16 + i * 4 + 2] = (rgba[2] & 0xff00) >> 8;
|
|
||||||
rg[16 + i * 4 + 3] = (rgba[3] & 0xff00) >> 8;
|
|
||||||
|
|
||||||
rgba += width;
|
|
||||||
}
|
|
||||||
|
|
||||||
src += 4;
|
|
||||||
if (++i == width / 4)
|
|
||||||
{
|
|
||||||
src += width * 3;
|
|
||||||
i = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
*ptr++ = ProcessAlpha(rg);
|
|
||||||
*ptr++ = ProcessAlpha(&rg[16]);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
while (--blocks);
|
|
||||||
}
|
|
||||||
|
|
||||||
// -- GODOT end --
|
|
|
@ -1,14 +0,0 @@
|
||||||
// -- GODOT start --
|
|
||||||
|
|
||||||
#ifndef __PROCESSRGTC_HPP__
|
|
||||||
#define __PROCESSRGTC_HPP__
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
void CompressRgtcR(const uint32_t *src, uint64_t *dst, uint32_t blocks, size_t width);
|
|
||||||
void CompressRgtcRG(const uint32_t *src, uint64_t *dst, uint32_t blocks, size_t width);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// -- GODOT end --
|
|
|
@ -86,6 +86,8 @@ const int32_t g_alpha[16][8] = {
|
||||||
{ -3, -5, -7, -9, 2, 4, 6, 8 }
|
{ -3, -5, -7, -9, 2, 4, 6, 8 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const int32_t g_alpha11Mul[16] = { 1, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120 };
|
||||||
|
|
||||||
const int32_t g_alphaRange[16] = {
|
const int32_t g_alphaRange[16] = {
|
||||||
0x100FF / ( 1 + g_alpha[0][7] - g_alpha[0][3] ),
|
0x100FF / ( 1 + g_alpha[0][7] - g_alpha[0][3] ),
|
||||||
0x100FF / ( 1 + g_alpha[1][7] - g_alpha[1][3] ),
|
0x100FF / ( 1 + g_alpha[1][7] - g_alpha[1][3] ),
|
||||||
|
|
|
@ -23,6 +23,7 @@ extern const uint32_t g_avg2[16];
|
||||||
extern const uint32_t g_flags[64];
|
extern const uint32_t g_flags[64];
|
||||||
|
|
||||||
extern const int32_t g_alpha[16][8];
|
extern const int32_t g_alpha[16][8];
|
||||||
|
extern const int32_t g_alpha11Mul[16];
|
||||||
extern const int32_t g_alphaRange[16];
|
extern const int32_t g_alphaRange[16];
|
||||||
|
|
||||||
#ifdef __SSE4_1__
|
#ifdef __SSE4_1__
|
||||||
|
|
|
@ -1,164 +0,0 @@
|
||||||
diff --git a/thirdparty/etcpak/ProcessRGB.cpp b/thirdparty/etcpak/ProcessRGB.cpp
|
|
||||||
index 4dc3bf23af..0caa687bc6 100644
|
|
||||||
--- a/thirdparty/etcpak/ProcessRGB.cpp
|
|
||||||
+++ b/thirdparty/etcpak/ProcessRGB.cpp
|
|
||||||
@@ -4181,3 +4181,145 @@ void CompressEtc2Rgba( const uint32_t* src, uint64_t* dst, uint32_t blocks, size
|
|
||||||
}
|
|
||||||
while( --blocks );
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+// -- GODOT start --
|
|
||||||
+void CompressEtc2R8( const uint32_t* src, uint64_t* dst, uint32_t blocks, size_t width )
|
|
||||||
+{
|
|
||||||
+ int w = 0;
|
|
||||||
+ uint8_t r[4*4];
|
|
||||||
+ do
|
|
||||||
+ {
|
|
||||||
+#ifdef __SSE4_1__
|
|
||||||
+ __m128 px0 = _mm_castsi128_ps( _mm_loadu_si128( (__m128i*)( src + width * 0 ) ) );
|
|
||||||
+ __m128 px1 = _mm_castsi128_ps( _mm_loadu_si128( (__m128i*)( src + width * 1 ) ) );
|
|
||||||
+ __m128 px2 = _mm_castsi128_ps( _mm_loadu_si128( (__m128i*)( src + width * 2 ) ) );
|
|
||||||
+ __m128 px3 = _mm_castsi128_ps( _mm_loadu_si128( (__m128i*)( src + width * 3 ) ) );
|
|
||||||
+
|
|
||||||
+ _MM_TRANSPOSE4_PS( px0, px1, px2, px3 );
|
|
||||||
+
|
|
||||||
+ __m128i c0 = _mm_castps_si128( px0 );
|
|
||||||
+ __m128i c1 = _mm_castps_si128( px1 );
|
|
||||||
+ __m128i c2 = _mm_castps_si128( px2 );
|
|
||||||
+ __m128i c3 = _mm_castps_si128( px3 );
|
|
||||||
+
|
|
||||||
+ __m128i mask = _mm_setr_epi32( 0x0e0a0602, -1, -1, -1 );
|
|
||||||
+
|
|
||||||
+ __m128i a0 = _mm_shuffle_epi8( c0, mask );
|
|
||||||
+ __m128i a1 = _mm_shuffle_epi8( c1, _mm_shuffle_epi32( mask, _MM_SHUFFLE( 3, 3, 0, 3 ) ) );
|
|
||||||
+ __m128i a2 = _mm_shuffle_epi8( c2, _mm_shuffle_epi32( mask, _MM_SHUFFLE( 3, 0, 3, 3 ) ) );
|
|
||||||
+ __m128i a3 = _mm_shuffle_epi8( c3, _mm_shuffle_epi32( mask, _MM_SHUFFLE( 0, 3, 3, 3 ) ) );
|
|
||||||
+
|
|
||||||
+ __m128i s0 = _mm_or_si128( a0, a1 );
|
|
||||||
+ __m128i s1 = _mm_or_si128( a2, a3 );
|
|
||||||
+ __m128i s2 = _mm_or_si128( s0, s1 );
|
|
||||||
+
|
|
||||||
+ _mm_store_si128( (__m128i*)r, s2 );
|
|
||||||
+
|
|
||||||
+ src += 4;
|
|
||||||
+#else
|
|
||||||
+ auto ptr8 = r;
|
|
||||||
+ for( int x=0; x<4; x++ )
|
|
||||||
+ {
|
|
||||||
+ auto v = *src;
|
|
||||||
+ *ptr8++ = (v & 0xff0000) >> 16;
|
|
||||||
+ src += width;
|
|
||||||
+ v = *src;
|
|
||||||
+ *ptr8++ = (v & 0xff0000) >> 16;
|
|
||||||
+ src += width;
|
|
||||||
+ v = *src;
|
|
||||||
+ *ptr8++ = (v & 0xff0000) >> 16;
|
|
||||||
+ src += width;
|
|
||||||
+ v = *src;
|
|
||||||
+ *ptr8++ = (v & 0xff0000) >> 16;
|
|
||||||
+ src -= width * 3 - 1;
|
|
||||||
+ }
|
|
||||||
+#endif
|
|
||||||
+ if( ++w == width/4 )
|
|
||||||
+ {
|
|
||||||
+ src += width * 3;
|
|
||||||
+ w = 0;
|
|
||||||
+ }
|
|
||||||
+ *dst++ = ProcessAlpha_ETC2( r );
|
|
||||||
+ }
|
|
||||||
+ while( --blocks );
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+void CompressEtc2RG8( const uint32_t* src, uint64_t* dst, uint32_t blocks, size_t width )
|
|
||||||
+{
|
|
||||||
+ int w = 0;
|
|
||||||
+ uint8_t rg[4*4*2];
|
|
||||||
+ do
|
|
||||||
+ {
|
|
||||||
+#ifdef __SSE4_1__
|
|
||||||
+ __m128 px0 = _mm_castsi128_ps( _mm_loadu_si128( (__m128i*)( src + width * 0 ) ) );
|
|
||||||
+ __m128 px1 = _mm_castsi128_ps( _mm_loadu_si128( (__m128i*)( src + width * 1 ) ) );
|
|
||||||
+ __m128 px2 = _mm_castsi128_ps( _mm_loadu_si128( (__m128i*)( src + width * 2 ) ) );
|
|
||||||
+ __m128 px3 = _mm_castsi128_ps( _mm_loadu_si128( (__m128i*)( src + width * 3 ) ) );
|
|
||||||
+
|
|
||||||
+ _MM_TRANSPOSE4_PS( px0, px1, px2, px3 );
|
|
||||||
+
|
|
||||||
+ __m128i c0 = _mm_castps_si128( px0 );
|
|
||||||
+ __m128i c1 = _mm_castps_si128( px1 );
|
|
||||||
+ __m128i c2 = _mm_castps_si128( px2 );
|
|
||||||
+ __m128i c3 = _mm_castps_si128( px3 );
|
|
||||||
+
|
|
||||||
+ __m128i mask = _mm_setr_epi32( 0x0e0a0602, -1, -1, -1 );
|
|
||||||
+
|
|
||||||
+ __m128i r0 = _mm_shuffle_epi8( c0, mask );
|
|
||||||
+ __m128i r1 = _mm_shuffle_epi8( c1, _mm_shuffle_epi32( mask, _MM_SHUFFLE( 3, 3, 0, 3 ) ) );
|
|
||||||
+ __m128i r2 = _mm_shuffle_epi8( c2, _mm_shuffle_epi32( mask, _MM_SHUFFLE( 3, 0, 3, 3 ) ) );
|
|
||||||
+ __m128i r3 = _mm_shuffle_epi8( c3, _mm_shuffle_epi32( mask, _MM_SHUFFLE( 0, 3, 3, 3 ) ) );
|
|
||||||
+
|
|
||||||
+ __m128i s0 = _mm_or_si128( r0, r1 );
|
|
||||||
+ __m128i s1 = _mm_or_si128( r2, r3 );
|
|
||||||
+ __m128i s2 = _mm_or_si128( s0, s1 );
|
|
||||||
+
|
|
||||||
+ _mm_store_si128( (__m128i*)rg, s2 );
|
|
||||||
+
|
|
||||||
+ mask = _mm_setr_epi32( 0x0d090501, -1, -1, -1 );
|
|
||||||
+
|
|
||||||
+ r0 = _mm_shuffle_epi8( c0, mask );
|
|
||||||
+ r1 = _mm_shuffle_epi8( c1, _mm_shuffle_epi32( mask, _MM_SHUFFLE( 3, 3, 0, 3 ) ) );
|
|
||||||
+ r2 = _mm_shuffle_epi8( c2, _mm_shuffle_epi32( mask, _MM_SHUFFLE( 3, 0, 3, 3 ) ) );
|
|
||||||
+ r3 = _mm_shuffle_epi8( c3, _mm_shuffle_epi32( mask, _MM_SHUFFLE( 0, 3, 3, 3 ) ) );
|
|
||||||
+
|
|
||||||
+ s0 = _mm_or_si128( r0, r1 );
|
|
||||||
+ s1 = _mm_or_si128( r2, r3 );
|
|
||||||
+ s2 = _mm_or_si128( s0, s1 );
|
|
||||||
+
|
|
||||||
+ _mm_store_si128( (__m128i*)&rg[16], s2 );
|
|
||||||
+ src += 4;
|
|
||||||
+#else
|
|
||||||
+ auto ptrr = rg;
|
|
||||||
+ auto ptrg = ptrr + 16;
|
|
||||||
+ for( int x=0; x<4; x++ )
|
|
||||||
+ {
|
|
||||||
+ auto v = *src;
|
|
||||||
+ *ptrr++ = (v & 0xff0000) >> 16;
|
|
||||||
+ *ptrg++ = (v & 0xff00) >> 8;
|
|
||||||
+ src += width;
|
|
||||||
+ v = *src;
|
|
||||||
+ *ptrr++ = (v & 0xff0000) >> 16;
|
|
||||||
+ *ptrg++ = (v & 0xff00) >> 8;
|
|
||||||
+ src += width;
|
|
||||||
+ v = *src;
|
|
||||||
+ *ptrr++ = (v & 0xff0000) >> 16;
|
|
||||||
+ *ptrg++ = (v & 0xff00) >> 8;
|
|
||||||
+ src += width;
|
|
||||||
+ v = *src;
|
|
||||||
+ *ptrr++ = (v & 0xff0000) >> 16;
|
|
||||||
+ *ptrg++ = (v & 0xff00) >> 8;
|
|
||||||
+ src -= width * 3 - 1;
|
|
||||||
+ }
|
|
||||||
+#endif
|
|
||||||
+ if( ++w == width/4 )
|
|
||||||
+ {
|
|
||||||
+ src += width * 3;
|
|
||||||
+ w = 0;
|
|
||||||
+ }
|
|
||||||
+ *dst++ = ProcessAlpha_ETC2( rg );
|
|
||||||
+ *dst++ = ProcessAlpha_ETC2( &rg[16] );
|
|
||||||
+ }
|
|
||||||
+ while( --blocks );
|
|
||||||
+}
|
|
||||||
+// -- GODOT end --
|
|
||||||
diff --git a/thirdparty/etcpak/ProcessRGB.hpp b/thirdparty/etcpak/ProcessRGB.hpp
|
|
||||||
index 043b46e636..050ea42562 100644
|
|
||||||
--- a/thirdparty/etcpak/ProcessRGB.hpp
|
|
||||||
+++ b/thirdparty/etcpak/ProcessRGB.hpp
|
|
||||||
@@ -9,5 +9,8 @@ void CompressEtc1Rgb( const uint32_t* src, uint64_t* dst, uint32_t blocks, size_
|
|
||||||
void CompressEtc1RgbDither( const uint32_t* src, uint64_t* dst, uint32_t blocks, size_t width );
|
|
||||||
void CompressEtc2Rgb( const uint32_t* src, uint64_t* dst, uint32_t blocks, size_t width, bool useHeuristics );
|
|
||||||
void CompressEtc2Rgba( const uint32_t* src, uint64_t* dst, uint32_t blocks, size_t width, bool useHeuristics );
|
|
||||||
-
|
|
||||||
+// -- GODOT start --
|
|
||||||
+void CompressEtc2R8( const uint32_t* src, uint64_t* dst, uint32_t blocks, size_t width );
|
|
||||||
+void CompressEtc2RG8( const uint32_t* src, uint64_t* dst, uint32_t blocks, size_t width );
|
|
||||||
+// -- GODOT end --
|
|
||||||
#endif
|
|
Loading…
Reference in New Issue