Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 57 additions & 13 deletions .azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,41 +37,77 @@ strategy:
CXX_COMPILER: i686-linux-gnu-g++
COMPILER_FLAGS: -mfpmath=sse -msse
Linux arm64 GCC:
VM_IMAGE: 'ubuntu-22.04'
VM_IMAGE: 'ubuntu-26.04'
APT_PACKAGES: ninja-build g++-aarch64-linux-gnu qemu-user
C_COMPILER: aarch64-linux-gnu-gcc
CXX_COMPILER: aarch64-linux-gnu-g++
CRUNCH_EXE_RUNNER: qemu-aarch64 -L /usr/aarch64-linux-gnu
Linux armhf GCC:
# There is an IO bug in qemu-arm from ubuntu-22.04.
VM_IMAGE: 'ubuntu-24.04'
VM_IMAGE: 'ubuntu-26.04'
APT_PACKAGES: ninja-build g++-arm-linux-gnueabihf qemu-user
C_COMPILER: arm-linux-gnueabihf-gcc
CXX_COMPILER: arm-linux-gnueabihf-g++
CRUNCH_EXE_RUNNER: qemu-arm -L /usr/arm-linux-gnueabihf
Linux ppc64 GCC:
VM_IMAGE: 'ubuntu-26.04'
APT_PACKAGES: ninja-build g++-powerpc64-linux-gnu qemu-user
C_COMPILER: powerpc64-linux-gnu-gcc
CXX_COMPILER: powerpc64-linux-gnu-g++
CRUNCH_EXE_RUNNER: qemu-ppc64 -L /usr/powerpc64-linux-gnu
Linux ppc64el GCC:
VM_IMAGE: 'ubuntu-26.04'
APT_PACKAGES: ninja-build g++-powerpc64le-linux-gnu qemu-user
C_COMPILER: powerpc64le-linux-gnu-gcc
CXX_COMPILER: powerpc64le-linux-gnu-g++
CRUNCH_EXE_RUNNER: qemu-ppc64le -L /usr/powerpc64le-linux-gnu
Linux riscv64 GCC:
VM_IMAGE: 'ubuntu-26.04'
APT_PACKAGES: ninja-build g++-riscv64-linux-gnu qemu-user
C_COMPILER: riscv64-linux-gnu-gcc
CXX_COMPILER: riscv64-linux-gnu-g++
CRUNCH_EXE_RUNNER: qemu-riscv64 -L /usr/riscv64-linux-gnu
Linux loong64 GCC:
VM_IMAGE: 'ubuntu-26.04'
APT_PACKAGES: ninja-build g++-loongarch64-linux-gnu qemu-user
C_COMPILER: loongarch64-linux-gnu-gcc
CXX_COMPILER: loongarch64-linux-gnu-g++
CRUNCH_EXE_RUNNER: qemu-loongarch64 -L /usr/loongarch64-linux-gnu
Linux s390x GCC:
VM_IMAGE: 'ubuntu-26.04'
APT_PACKAGES: ninja-build g++-s390x-linux-gnu qemu-user
C_COMPILER: s390x-linux-gnu-gcc
CXX_COMPILER: s390x-linux-gnu-g++
CRUNCH_EXE_RUNNER: qemu-s390x -L /usr/s390x-linux-gnu
Linux amd64 Clang:
VM_IMAGE: 'ubuntu-22.04'
APT_PACKAGES: ninja-build
C_COMPILER: clang
CXX_COMPILER: clang++
Windows amd64 MinGW:
VM_IMAGE: 'ubuntu-22.04'
APT_PACKAGES: ninja-build g++-mingw-w64-x86-64 mingw-w64-x86-64-dev gcc-mingw-w64-x86-64-posix-runtime wine
VM_IMAGE: 'ubuntu-26.04'
APT_PACKAGES: ninja-build g++-mingw-w64-x86-64 mingw-w64-x86-64-dev gcc-mingw-w64-x86-64-posix-runtime wine64
SETUP_COMMANDS: sudo update-alternatives --set x86_64-w64-mingw32-g++ /usr/bin/x86_64-w64-mingw32-g++-posix
TOOLCHAIN_FILE: cmake/cross-toolchain-mingw64.cmake
RUNTIME_FILES: /usr/lib/gcc/x86_64-w64-mingw32/13-posix/libgcc_s_seh-1.dll /usr/lib/gcc/x86_64-w64-mingw32/13-posix/libstdc++-6.dll /usr/x86_64-w64-mingw32/lib/libwinpthread-1.dll
CRUNCH_EXE_RUNNER: wine
CRUNCH_EXTENSION: .exe
RUNTIME_FILES: /usr/lib/gcc/x86_64-w64-mingw32/10-posix/libgcc_s_seh-1.dll /usr/lib/gcc/x86_64-w64-mingw32/10-posix/libstdc++-6.dll /usr/x86_64-w64-mingw32/lib/libwinpthread-1.dll
CRUNCH_EXE_EXTENSION: .exe
Windows i686 MinGW:
VM_IMAGE: 'ubuntu-22.04'
VM_IMAGE: 'ubuntu-26.04'
APT_ARCHITECTURE: i386
APT_PACKAGES: ninja-build g++-mingw-w64-i686 mingw-w64-i686-dev gcc-mingw-w64-i686-posix-runtime wine wine32
APT_PACKAGES: ninja-build g++-mingw-w64-i686 mingw-w64-i686-dev gcc-mingw-w64-i686-posix-runtime wine64
SETUP_COMMANDS: sudo update-alternatives --set i686-w64-mingw32-g++ /usr/bin/i686-w64-mingw32-g++-posix
TOOLCHAIN_FILE: cmake/cross-toolchain-mingw32.cmake
COMPILER_FLAGS: -mfpmath=sse -msse
RUNTIME_FILES: /usr/lib/gcc/i686-w64-mingw32/13-posix/libgcc_s_dw2-1.dll /usr/lib/gcc/i686-w64-mingw32/13-posix/libstdc++-6.dll /usr/i686-w64-mingw32/lib/libwinpthread-1.dll
CRUNCH_EXE_RUNNER: wine
CRUNCH_EXTENSION: .exe
RUNTIME_FILES: /usr/lib/gcc/i686-w64-mingw32/10-posix/libgcc_s_dw2-1.dll /usr/lib/gcc/i686-w64-mingw32/10-posix/libstdc++-6.dll /usr/i686-w64-mingw32/lib/libwinpthread-1.dll
CRUNCH_EXE_EXTENSION: .exe
Windows arm64 MinGW:
VM_IMAGE: 'windows-2025'
PACMAN_PACKAGES: mingw-w64-cross-mingwarm64-gcc
C_COMPILER: aarch64-w64-mingw32-gcc
CXX_COMPILER: aarch64-w64-mingw32-g++
CRUNCH_EXE_EXTENSION: .exe
RUN_TESTS: false
macOS amd64 AppleClang:
VM_IMAGE: 'macOS-14'
PIP_PACKAGES: colorama
Expand Down Expand Up @@ -104,11 +140,19 @@ steps:
if [ -n "${APT_PACKAGES:-}" ]; then
sudo apt-get update && sudo apt-get -y -q --no-install-recommends install ${APT_PACKAGES}
fi
if [ -n "${PACMAN_PACKAGES:-}" ]; then
'C:\msys64\usr\bin\bash.exe' -lc "pacman -Sy --noconfirm && pacman -S --noconfirm ${PACMAN_PACKAGES}"
echo '##vso[task.prependpath]C:\msys64\usr\bin'
echo '##vso[task.prependpath]C:\msys64\opt\bin'
fi
if [ -n "${PIP_PACKAGES:-}" ]; then
pip install ${PIP_PACKAGES}
fi
if [ -n "${SETUP_COMMANDS:-}" ]; then
$(SETUP_COMMANDS)
$(SETUP_COMMANDS)
fi
if [ -x '/usr/lib/x86_64-linux-gnu/wine/wineserver' ]; then
echo '##vso[task.prependpath]/usr/lib/x86_64-linux-gnu/wine'
fi
displayName: 'Setup'
- bash: |
Expand Down Expand Up @@ -138,7 +182,7 @@ steps:
set -xue
EXECUTABLES="${EXECUTABLES:-crunch example1 example2 example3}"
for exe_file in ${EXECUTABLES}; do
file "build/${exe_file}${CRUNCH_EXTENSION:-}"
file "build/${exe_file}${CRUNCH_EXE_EXTENSION:-}"
done
if [ -n "${RUNTIME_FILES:-}" ]; then
cp -av ${RUNTIME_FILES} build/
Expand Down
14 changes: 14 additions & 0 deletions crnlib/crn_color.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,20 @@ class color_quad : public helpers::rel_ops<color_quad<component_type, parameter_
a = 0;
}

inline void set_rgba_u32(uint32 v) {
r = static_cast<component_t>(v);
g = static_cast<component_t>(v >> 8);
b = static_cast<component_t>(v >> 16);
a = static_cast<component_t>(v >> 24);
}

inline uint32 get_rgba_u32() const {
return uint32(r) |
(uint32(g) << 8) |
(uint32(b) << 16) |
(uint32(a) << 24);
}

inline color_quad& operator=(const color_quad& other) {
r = other.r;
g = other.g;
Expand Down
14 changes: 12 additions & 2 deletions crnlib/crn_comp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -795,9 +795,19 @@ void crn_comp::optimize_color() {
}
}
crnlib::vector<optimize_color_params::unpacked_endpoint> unpacked_endpoints(n);

for (uint16 i = 0; i < n; i++) {
unpacked_endpoints[i].low.m_u32 = m_has_etc_color_blocks ? m_color_endpoints[i] & 0xFFFFFF : dxt1_block::unpack_color(m_color_endpoints[i] & 0xFFFF, true).m_u32;
unpacked_endpoints[i].high.m_u32 = m_has_etc_color_blocks ? m_color_endpoints[i] >> 24 : dxt1_block::unpack_color(m_color_endpoints[i] >> 16, true).m_u32;
uint32 endpoint = m_color_endpoints[i];

if (m_has_etc_color_blocks) {
unpacked_endpoints[i].low.set_rgba_u32(endpoint & 0xFFFFFF);
unpacked_endpoints[i].high.set_rgba_u32(endpoint >> 24);
} else {
unpacked_endpoints[i].low =
dxt1_block::unpack_color(endpoint & 0xFFFF, true);
unpacked_endpoints[i].high =
dxt1_block::unpack_color(endpoint >> 16, true);
}
}

optimize_color_params::result remapping_trial[4];
Expand Down
6 changes: 6 additions & 0 deletions crnlib/crn_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,13 @@

#define CRNLIB_USE_UNALIGNED_INT_LOADS 1

#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#define CRNLIB_LITTLE_ENDIAN_CPU 1
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
#define CRNLIB_BIG_ENDIAN_CPU 1
#else
#error "Unknown CPU endianness"
#endif

#define CRNLIB_USE_PTHREADS_API 1
#define CRNLIB_USE_GCC_ATOMIC_BUILTINS 1
Expand Down
29 changes: 15 additions & 14 deletions crnlib/crn_dxt1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ void dxt1_endpoint_optimizer::return_solution() {
m_pResults->m_enforce_selector = m_best_solution.m_enforce_selector;
m_pResults->m_enforced_selector = m_best_solution.m_enforced_selector;
m_pResults->m_reordered = invert_selectors;

if (invert_selectors) {
m_pResults->m_low_color = m_best_solution.m_coords.m_high_color;
m_pResults->m_high_color = m_best_solution.m_coords.m_low_color;
Expand All @@ -234,17 +235,13 @@ void dxt1_endpoint_optimizer::return_solution() {
if (invert_selectors)
pInvert_table = m_best_solution.m_alpha_block ? g_invTableAlpha : g_invTableColor;

const uint alpha_thresh = m_pParams->m_pixels_have_alpha ? (m_pParams->m_dxt1a_alpha_threshold << 24U) : 0;

const uint32* pSrc_pixels = reinterpret_cast<const uint32*>(m_pParams->m_pPixels);
const color_quad_u8* pSrc_pixels = m_pParams->m_pPixels;
uint8* pDst_selectors = m_pResults->m_pSelectors;

if ((m_unique_colors.size() == 1) && (!m_pParams->m_pixels_have_alpha)) {
uint32 c = utils::read_le32(pSrc_pixels);

CRNLIB_ASSERT(c >= alpha_thresh);
color_quad_u8 color(pSrc_pixels->r, pSrc_pixels->g, pSrc_pixels->b, 255);

c |= 0xFF000000U;
uint32 c = color.get_rgba_u32();

unique_color_hash_map::const_iterator it(m_unique_color_hash_map.find(c));
CRNLIB_ASSERT(it != m_unique_color_hash_map.end());
Expand All @@ -261,13 +258,15 @@ void dxt1_endpoint_optimizer::return_solution() {
uint32 prev_color = 0;

do {
uint32 c = utils::read_le32(pSrc_pixels);
pSrc_pixels++;

uint8 selector = 3;

if (c >= alpha_thresh) {
c |= 0xFF000000U;
uint8 alpha_thresh = pSrc_pixels->a;

if (!m_pParams->m_pixels_have_alpha || (alpha_thresh >= m_pParams->m_dxt1a_alpha_threshold)) {

color_quad_u8 color(pSrc_pixels->r, pSrc_pixels->g, pSrc_pixels->b, 255);

uint32 c = color.get_rgba_u32();

if (c == prev_color)
selector = prev_selector;
Expand All @@ -285,6 +284,8 @@ void dxt1_endpoint_optimizer::return_solution() {
}
}

pSrc_pixels++;

*pDst_selectors++ = selector;

} while (pDst_selectors != pDst_selectors_end);
Expand Down Expand Up @@ -1708,8 +1709,8 @@ void dxt1_endpoint_optimizer::compute_internal(const params& p, results& r) {
unique_color color(color_quad_u8(0), 1);
for (uint i = 0; i < m_pParams->m_num_pixels; i++) {
if (!m_pParams->m_pixels_have_alpha || m_pParams->m_pPixels[i].a >= m_pParams->m_dxt1a_alpha_threshold) {
color.m_color.m_u32 = m_pParams->m_pPixels[i].m_u32 | 0xFF000000;
unique_color_hash_map::insert_result ins_result(m_unique_color_hash_map.insert(color.m_color.m_u32, m_unique_colors.size()));
color.m_color = color_quad_u8(m_pParams->m_pPixels[i].r, m_pParams->m_pPixels[i].g, m_pParams->m_pPixels[i].b, 255);
unique_color_hash_map::insert_result ins_result(m_unique_color_hash_map.insert(color.m_color.get_rgba_u32(), m_unique_colors.size()));
if (ins_result.second) {
m_unique_colors.push_back(color);
} else {
Expand Down
2 changes: 1 addition & 1 deletion crnlib/crn_dxt_hc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -616,7 +616,7 @@ void dxt_hc::determine_color_endpoint_codebook_task_etc(uint64 data, void*) {
for (int c = 0; c < 3; c++)
endpoint.c[c] = results.m_block_color_unscaled.c[c] << 3 | results.m_block_color_unscaled.c[c] >> 2;
endpoint.c[3] = results.m_block_inten_table;
cluster.first_endpoint = endpoint.m_u32;
cluster.first_endpoint = endpoint.get_rgba_u32();
for (uint8 d0 = delta[endpoint.c[3]][0], d1 = delta[endpoint.c[3]][1], c = 0; c < 3; c++) {
uint8 q = endpoint.c[c];
cluster.color_values[0].c[c] = q <= d1 ? 0 : q - d1;
Expand Down
15 changes: 14 additions & 1 deletion crnlib/crn_etc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1617,7 +1617,20 @@ uint64 pack_etc1s_block(etc1_block& dst_block, const color_quad_u8* pSrc_pixels,
}
}

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;
const uint32 color =
((uint32)results.m_block_color_unscaled.r << 16) |
((uint32)results.m_block_color_unscaled.g << 8) |
(uint32)results.m_block_color_unscaled.b;

const uint64 packed =
(uint64)selector << 32 |
(uint64)results.m_block_inten_table << 29 |
(uint64)results.m_block_inten_table << 26 |
(uint64)1 << 25 |
(uint64)color << 3;

utils::write_be64(&dst_block.m_uint64, packed);

return results.m_error;
}

Expand Down
Loading