Permalink
Browse files

Merge pull request #9 from Unity-Technologies/unity

Implement ETC1S/ETC2AS image compression / better thread management
  • Loading branch information...
illwieckz committed Dec 2, 2018
2 parents d55ac49 + 8708900 commit 559a1b045b50b5f716294b47325c0170c8236dbc
Showing with 69 additions and 1 deletion.
  1. BIN bin/crunch_x64.exe
  2. +24 −0 crnlib/crn_dxt_image.cpp
  3. +43 −0 crnlib/crn_etc.cpp
  4. +1 −0 crnlib/crn_etc.h
  5. +1 −1 inc/crnlib.h
BIN +1.5 KB (100%) bin/crunch_x64.exe
Binary file not shown.
@@ -1040,6 +1040,30 @@ void dxt_image::set_block_pixels(
rg_etc1::pack_etc1_block(pElement, (uint32*)pPixels, pack_params);
}
}

} else if (m_format == cETC1S) {
crn_etc1_pack_params pack_params;
pack_params.m_perceptual = p.m_perceptual;
pack_params.m_dithering = p.m_dithering;
pack_params.m_quality = p.m_quality <= cCRNDXTQualityFast ? cCRNETCQualityFast : p.m_quality <= cCRNDXTQualityNormal ? cCRNETCQualityMedium : cCRNETCQualitySlow;
pack_etc1s_block(*(etc1_block*)pElement, pPixels, pack_params);

} else if (m_format == cETC2AS) {
for (uint element_index = 0; element_index < m_num_elements_per_block; element_index++, pElement++) {
if (m_element_type[element_index] == cAlphaETC2) {
rg_etc1::etc2a_pack_params pack_params;
pack_params.m_quality = p.m_quality <= cCRNDXTQualityFast ? rg_etc1::cLowQuality : p.m_quality <= cCRNDXTQualityNormal ? rg_etc1::cMediumQuality : rg_etc1::cHighQuality;
pack_params.comp_index = m_element_component_index[element_index];
rg_etc1::pack_etc2_alpha(pElement, (uint32*)pPixels, pack_params);
} else {
crn_etc1_pack_params pack_params;
pack_params.m_perceptual = p.m_perceptual;
pack_params.m_dithering = p.m_dithering;
pack_params.m_quality = p.m_quality <= cCRNDXTQualityFast ? cCRNETCQualityFast : p.m_quality <= cCRNDXTQualityNormal ? cCRNETCQualityMedium : cCRNETCQualitySlow;
pack_etc1s_block(*(etc1_block*)pElement, pPixels, pack_params);
}
}

} else
#if CRNLIB_SUPPORT_SQUISH
if ((p.m_compressor == cCRNDXTCompressorSquish) && ((m_format == cDXT1) || (m_format == cDXT1A) || (m_format == cDXT3) || (m_format == cDXT5) || (m_format == cDXT5A))) {
@@ -1580,4 +1580,47 @@ uint64 pack_etc1_block(etc1_block& dst_block, const color_quad_u8* pSrc_pixels,
return best_error;
}

uint64 pack_etc1s_block(etc1_block& dst_block, const color_quad_u8* pSrc_pixels, crn_etc1_pack_params& pack_params) {
uint8 selectors[16];
etc1_optimizer optimizer;
etc1_optimizer::params params;
params.m_pSrc_pixels = pSrc_pixels;
params.m_num_src_pixels = 16;
params.m_use_color4 = false;
params.m_constrain_against_base_color5 = false;
etc1_optimizer::results results;
results.m_pSelectors = selectors;
results.m_n = 16;
optimizer.init(params, results);

const int scan[] = {-4, -3, -2, -1, 0, 1, 2, 3, 4};
params.m_scan_delta_size = pack_params.m_quality == cCRNETCQualitySlow ? CRNLIB_ARRAY_SIZE(scan) : pack_params.m_quality == cCRNETCQualityMedium ? 3 : 1;
params.m_pScan_deltas = scan + ((CRNLIB_ARRAY_SIZE(scan) - params.m_scan_delta_size) >> 1);
optimizer.compute();

if (params.m_quality >= cCRNETCQualityMedium && results.m_error > 6000) {
const int refine_medium[] = {-3, -2, 2, 3};
const int refine_high[] = {-8, -7, -6, -5, 5, 6, 7, 8};
if (params.m_quality == cCRNETCQualityMedium) {
params.m_scan_delta_size = CRNLIB_ARRAY_SIZE(refine_medium);
params.m_pScan_deltas = refine_medium;
} else {
params.m_scan_delta_size = results.m_error > 12000 ? CRNLIB_ARRAY_SIZE(refine_high) : 2;
params.m_pScan_deltas = refine_high + ((CRNLIB_ARRAY_SIZE(refine_high) - params.m_scan_delta_size) >> 1);
}
optimizer.compute();
}

uint32 selector = 0;
for (uint32 i = 0, t = 8, h = 0; h < 4; h++, t -= 15) {
for (uint32 w = 0; w < 4; w++, t += 4, i++) {
uint32 s = g_selector_index_to_etc1[selectors[i]];
selector |= (s >> 1 | (s & 1) << 16) << (t & 15);
}
}

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;
return results.m_error;
}

} // namespace crnlib
@@ -538,5 +538,6 @@ struct pack_etc1_block_context {
void pack_etc1_block_init();

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

} // namespace crnlib
@@ -92,7 +92,7 @@ enum crn_limits {
cCRNMaxFaces = 6,
cCRNMaxLevels = 16,

cCRNMaxHelperThreads = 16,
cCRNMaxHelperThreads = 15,

cCRNMinQualityLevel = 0,
cCRNMaxQualityLevel = 255

0 comments on commit 559a1b0

Please sign in to comment.