From 7aebf0c25107e4d7b15179574caa9124d0596371 Mon Sep 17 00:00:00 2001 From: Ignacio Castano Date: Sun, 5 Jul 2020 23:08:57 -0700 Subject: [PATCH] ETC compression experiments. --- src/nvtt/BlockCompressor.cpp | 56 +++++++++++++++++++++++++++++++++++- src/nvtt/BlockCompressor.h | 14 +++++++++ src/nvtt/CMakeLists.txt | 7 ++++- src/nvtt/Context.cpp | 6 ++++ src/nvtt/tests/testsuite.cpp | 12 ++++++++ 5 files changed, 93 insertions(+), 2 deletions(-) diff --git a/src/nvtt/BlockCompressor.cpp b/src/nvtt/BlockCompressor.cpp index ca1a1d5..ffeafd2 100644 --- a/src/nvtt/BlockCompressor.cpp +++ b/src/nvtt/BlockCompressor.cpp @@ -569,7 +569,7 @@ void EtcLibCompressor::compress(AlphaMode alphaMode, uint w, uint h, uint d, con #if defined(HAVE_RGETC) #include "rg_etc1.h" -NV_AT_STARTUP(rg_etc1::pack_etc1_block_init()); +NV_AT_STARTUP(rg_etc1::pack_etc1_block_init()); // @@ Do this in context init. void RgEtcCompressor::compressBlock(ColorBlock & rgba, AlphaMode alphaMode, const CompressionOptions::Private & compressionOptions, void * output) { @@ -591,6 +591,60 @@ void RgEtcCompressor::compressBlock(ColorBlock & rgba, AlphaMode alphaMode, cons #endif +#if defined(HAVE_ETCPACK) + +void EtcPackCompressor::compress(nvtt::AlphaMode alphaMode, uint w, uint h, uint d, const float * data, nvtt::TaskDispatcher * dispatcher, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions) +{ + uint8 *imgdec = (uint8 *)malloc(expandedwidth*expandedheight * 3); + + uint32 block1, block2; + + if (compressionOptions.quality == Quality_Fastest) { + compressBlockDiffFlipFast(img, imgdec, expandedwidth, expandedheight, 4 * x, 4 * y, block1, block2); + } + else { + compressBlockETC1Exhaustive(img, imgdec, expandedwidth, expandedheight, 4 * x, 4 * y, block1, block2); + } +} + +#endif + +#if defined(HAVE_ETCINTEL) +#include "kernel_ispc.h" + +void EtcIntelCompressor::compress(nvtt::AlphaMode alphaMode, uint w, uint h, uint d, const float * data, nvtt::TaskDispatcher * dispatcher, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions) +{ + nvCheck(d == 1); + + // Allocate and convert input. + nv::Array src; + const uint count = w * h; + src.resize(4 * count); + + for (uint i = 0; i < count; i++) { + src[4 * i + 0] = data[count * 0 + i]; // @@ Scale by 256? + src[4 * i + 1] = data[count * 1 + i]; + src[4 * i + 2] = data[count * 2 + i]; + src[4 * i + 3] = data[count * 3 + i]; + } + + int bw = (w + 3) / 4; + int bw = (w + 3) / 4; + + // Allocate output. + nv::Array dst; + dst.resize(bw * bh * 4); + + ispc::rgba_surface surface; + surface.ptr = src.buffer(); + surface.width = w; + surface.height = h; + surface.stride = w * 4; + + ispc::CompressBlocksBC1_ispc(&surface, dst) +} + +#endif #if defined(HAVE_PVRTEXTOOL) diff --git a/src/nvtt/BlockCompressor.h b/src/nvtt/BlockCompressor.h index f23fb99..9187ebf 100644 --- a/src/nvtt/BlockCompressor.h +++ b/src/nvtt/BlockCompressor.h @@ -157,6 +157,20 @@ namespace nv }; #endif +#if defined(HAVE_ETCPACK) + struct EtcPackCompressor : public CompressorInterface + { + virtual void compress(nvtt::AlphaMode alphaMode, uint w, uint h, uint d, const float * data, nvtt::TaskDispatcher * dispatcher, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions); + }; +#endif + +#if defined(HAVE_ETCINTEL) + struct EtcIntelCompressor : public CompressorInterface + { + virtual void compress(nvtt::AlphaMode alphaMode, uint w, uint h, uint d, const float * data, nvtt::TaskDispatcher * dispatcher, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions); + }; +#endif + #if defined(HAVE_PVRTEXTOOL) struct CompressorPVR : public CompressorInterface { diff --git a/src/nvtt/CMakeLists.txt b/src/nvtt/CMakeLists.txt index 7b92379..8b0a8ee 100644 --- a/src/nvtt/CMakeLists.txt +++ b/src/nvtt/CMakeLists.txt @@ -27,7 +27,10 @@ SET(NVTT_SRCS cuda/CudaUtils.h cuda/CudaUtils.cpp cuda/CudaMath.h cuda/BitmapTable.h - cuda/CudaCompressorDXT.h cuda/CudaCompressorDXT.cpp) + cuda/CudaCompressorDXT.h cuda/CudaCompressorDXT.cpp + ${NV_SOURCE_DIR}/extern/rg_etc1_v104/rg_etc1.h ${NV_SOURCE_DIR}/extern/rg_etc1_v104/rg_etc1.cpp + ${NV_SOURCE_DIR}/extern/etcpack/etcpack.cxx ${NV_SOURCE_DIR}/extern/etcpack/etcdec.cxx + ) IF (CUDA_FOUND) ADD_DEFINITIONS(-DHAVE_CUDA) @@ -41,6 +44,8 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) INCLUDE_DIRECTORIES(${NV_SOURCE_DIR}/extern/rg_etc1_v104) ADD_DEFINITIONS(-DNVTT_EXPORTS) +ADD_DEFINITIONS(-DHAVE_RGETC) +#ADD_DEFINITIONS(-DHAVE_ETCPACK) IF(NVTT_SHARED) ADD_LIBRARY(nvtt SHARED ${NVTT_SRCS}) diff --git a/src/nvtt/Context.cpp b/src/nvtt/Context.cpp index af0b0f1..08d723f 100644 --- a/src/nvtt/Context.cpp +++ b/src/nvtt/Context.cpp @@ -1057,6 +1057,12 @@ CompressorInterface * Compressor::Private::chooseCpuCompressor(const Compression #endif #if defined(HAVE_ETCLIB) if (compressionOptions.externalCompressor == "etclib") return new EtcLibCompressor; +#endif +#if defined(HAVE_ETCPACK) + if (compressionOptions.format == Format_ETC1 && compressionOptions.externalCompressor == "etcpack") return new EtcPackCompressor; +#endif +#if defined(HAVE_ETCINTEL) + if (compressionOptions.format == Format_ETC1 && compressionOptions.externalCompressor == "intel") return new EtcIntelCompressor; #endif if (compressionOptions.format == Format_ETC1) return new CompressorETC1; else if (compressionOptions.format == Format_ETC2_R) return new CompressorETC2_R; diff --git a/src/nvtt/tests/testsuite.cpp b/src/nvtt/tests/testsuite.cpp index 652dcfc..3fdfeaf 100644 --- a/src/nvtt/tests/testsuite.cpp +++ b/src/nvtt/tests/testsuite.cpp @@ -200,6 +200,7 @@ enum Mode { Mode_ETC1_EtcLib, Mode_ETC2_EtcLib, Mode_ETC1_RgEtc, + Mode_ETC1_Intel, Mode_ETC2_RGBM, Mode_PVR, Mode_Count @@ -226,6 +227,7 @@ static const char * s_modeNames[] = { "ETC1-EtcLib", "ETC2-EtcLib", "ETC1-RgEtc", + "ETC1-Intel", "ETC2-RGBM", "PVR", }; @@ -666,6 +668,16 @@ int main(int argc, char *argv[]) format = nvtt::Format_ETC1; compressor_name = "rg_etc"; } + else if (mode == Mode_ETC1_Ericson) + { + format = nvtt::Format_ETC1; + compressor_name = "etcpack"; + } + else if (mode == Mode_ETC1_Intel) + { + format = nvtt::Format_ETC1; + compressor_name = "intel"; + } else if (mode == Mode_ETC2_RGBM) { format = nvtt::Format_ETC2_RGBM;