Skip to content
This repository was archived by the owner on Sep 19, 2020. It is now read-only.

Commit 559a1b0

Browse files
authored
Merge pull request Unity-Technologies#9 from Unity-Technologies/unity
Implement ETC1S/ETC2AS image compression / better thread management
2 parents d55ac49 + 8708900 commit 559a1b0

File tree

5 files changed

+69
-1
lines changed

5 files changed

+69
-1
lines changed

bin/crunch_x64.exe

1.5 KB
Binary file not shown.

crnlib/crn_dxt_image.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1040,6 +1040,30 @@ void dxt_image::set_block_pixels(
10401040
rg_etc1::pack_etc1_block(pElement, (uint32*)pPixels, pack_params);
10411041
}
10421042
}
1043+
1044+
} else if (m_format == cETC1S) {
1045+
crn_etc1_pack_params pack_params;
1046+
pack_params.m_perceptual = p.m_perceptual;
1047+
pack_params.m_dithering = p.m_dithering;
1048+
pack_params.m_quality = p.m_quality <= cCRNDXTQualityFast ? cCRNETCQualityFast : p.m_quality <= cCRNDXTQualityNormal ? cCRNETCQualityMedium : cCRNETCQualitySlow;
1049+
pack_etc1s_block(*(etc1_block*)pElement, pPixels, pack_params);
1050+
1051+
} else if (m_format == cETC2AS) {
1052+
for (uint element_index = 0; element_index < m_num_elements_per_block; element_index++, pElement++) {
1053+
if (m_element_type[element_index] == cAlphaETC2) {
1054+
rg_etc1::etc2a_pack_params pack_params;
1055+
pack_params.m_quality = p.m_quality <= cCRNDXTQualityFast ? rg_etc1::cLowQuality : p.m_quality <= cCRNDXTQualityNormal ? rg_etc1::cMediumQuality : rg_etc1::cHighQuality;
1056+
pack_params.comp_index = m_element_component_index[element_index];
1057+
rg_etc1::pack_etc2_alpha(pElement, (uint32*)pPixels, pack_params);
1058+
} else {
1059+
crn_etc1_pack_params pack_params;
1060+
pack_params.m_perceptual = p.m_perceptual;
1061+
pack_params.m_dithering = p.m_dithering;
1062+
pack_params.m_quality = p.m_quality <= cCRNDXTQualityFast ? cCRNETCQualityFast : p.m_quality <= cCRNDXTQualityNormal ? cCRNETCQualityMedium : cCRNETCQualitySlow;
1063+
pack_etc1s_block(*(etc1_block*)pElement, pPixels, pack_params);
1064+
}
1065+
}
1066+
10431067
} else
10441068
#if CRNLIB_SUPPORT_SQUISH
10451069
if ((p.m_compressor == cCRNDXTCompressorSquish) && ((m_format == cDXT1) || (m_format == cDXT1A) || (m_format == cDXT3) || (m_format == cDXT5) || (m_format == cDXT5A))) {

crnlib/crn_etc.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1580,4 +1580,47 @@ uint64 pack_etc1_block(etc1_block& dst_block, const color_quad_u8* pSrc_pixels,
15801580
return best_error;
15811581
}
15821582

1583+
uint64 pack_etc1s_block(etc1_block& dst_block, const color_quad_u8* pSrc_pixels, crn_etc1_pack_params& pack_params) {
1584+
uint8 selectors[16];
1585+
etc1_optimizer optimizer;
1586+
etc1_optimizer::params params;
1587+
params.m_pSrc_pixels = pSrc_pixels;
1588+
params.m_num_src_pixels = 16;
1589+
params.m_use_color4 = false;
1590+
params.m_constrain_against_base_color5 = false;
1591+
etc1_optimizer::results results;
1592+
results.m_pSelectors = selectors;
1593+
results.m_n = 16;
1594+
optimizer.init(params, results);
1595+
1596+
const int scan[] = {-4, -3, -2, -1, 0, 1, 2, 3, 4};
1597+
params.m_scan_delta_size = pack_params.m_quality == cCRNETCQualitySlow ? CRNLIB_ARRAY_SIZE(scan) : pack_params.m_quality == cCRNETCQualityMedium ? 3 : 1;
1598+
params.m_pScan_deltas = scan + ((CRNLIB_ARRAY_SIZE(scan) - params.m_scan_delta_size) >> 1);
1599+
optimizer.compute();
1600+
1601+
if (params.m_quality >= cCRNETCQualityMedium && results.m_error > 6000) {
1602+
const int refine_medium[] = {-3, -2, 2, 3};
1603+
const int refine_high[] = {-8, -7, -6, -5, 5, 6, 7, 8};
1604+
if (params.m_quality == cCRNETCQualityMedium) {
1605+
params.m_scan_delta_size = CRNLIB_ARRAY_SIZE(refine_medium);
1606+
params.m_pScan_deltas = refine_medium;
1607+
} else {
1608+
params.m_scan_delta_size = results.m_error > 12000 ? CRNLIB_ARRAY_SIZE(refine_high) : 2;
1609+
params.m_pScan_deltas = refine_high + ((CRNLIB_ARRAY_SIZE(refine_high) - params.m_scan_delta_size) >> 1);
1610+
}
1611+
optimizer.compute();
1612+
}
1613+
1614+
uint32 selector = 0;
1615+
for (uint32 i = 0, t = 8, h = 0; h < 4; h++, t -= 15) {
1616+
for (uint32 w = 0; w < 4; w++, t += 4, i++) {
1617+
uint32 s = g_selector_index_to_etc1[selectors[i]];
1618+
selector |= (s >> 1 | (s & 1) << 16) << (t & 15);
1619+
}
1620+
}
1621+
1622+
dst_block.m_uint64 = (uint64)selector << 32 | results.m_block_inten_table << 29 | results.m_block_inten_table << 26 | 1 << 25 | (results.m_block_color_unscaled.m_u32 & 0xFFFFFF) << 3;
1623+
return results.m_error;
1624+
}
1625+
15831626
} // namespace crnlib

crnlib/crn_etc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -538,5 +538,6 @@ struct pack_etc1_block_context {
538538
void pack_etc1_block_init();
539539

540540
uint64 pack_etc1_block(etc1_block& block, const color_quad_u8* pSrc_pixels, crn_etc1_pack_params& pack_params, pack_etc1_block_context& context);
541+
uint64 pack_etc1s_block(etc1_block& block, const color_quad_u8* pSrc_pixels, crn_etc1_pack_params& pack_params);
541542

542543
} // namespace crnlib

inc/crnlib.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ enum crn_limits {
9292
cCRNMaxFaces = 6,
9393
cCRNMaxLevels = 16,
9494

95-
cCRNMaxHelperThreads = 16,
95+
cCRNMaxHelperThreads = 15,
9696

9797
cCRNMinQualityLevel = 0,
9898
cCRNMaxQualityLevel = 255

0 commit comments

Comments
 (0)