diff options
Diffstat (limited to '3rdparty/bimg/src/image_encode.cpp')
-rw-r--r-- | 3rdparty/bimg/src/image_encode.cpp | 147 |
1 files changed, 126 insertions, 21 deletions
diff --git a/3rdparty/bimg/src/image_encode.cpp b/3rdparty/bimg/src/image_encode.cpp index 09586fe5105..e006940a3a8 100644 --- a/3rdparty/bimg/src/image_encode.cpp +++ b/3rdparty/bimg/src/image_encode.cpp @@ -1,6 +1,6 @@ /* - * Copyright 2011-2018 Branimir Karadzic. All rights reserved. - * License: https://github.com/bkaradzic/bimg#license-bsd-2-clause + * Copyright 2011-2022 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bimg/blob/master/LICENSE */ #include <bimg/encode.h> @@ -12,7 +12,7 @@ #include <nvtt/nvtt.h> #include <pvrtc/PvrTcEncoder.h> #include <edtaa3/edtaa3func.h> -#include <astc/astc_lib.h> +#include <astcenc.h> BX_PRAGMA_DIAGNOSTIC_PUSH(); BX_PRAGMA_DIAGNOSTIC_IGNORED_MSVC(4100) // warning C4100: 'alloc_context': unreferenced formal parameter @@ -30,19 +30,29 @@ namespace bimg { static uint32_t s_squishQuality[] = { + // Standard + squish::kColourClusterFit, // Default + squish::kColourIterativeClusterFit, // Highest + squish::kColourRangeFit, // Fastest + // Normal map squish::kColourClusterFit, // Default squish::kColourIterativeClusterFit, // Highest squish::kColourRangeFit, // Fastest }; BX_STATIC_ASSERT(Quality::Count == BX_COUNTOF(s_squishQuality) ); - static const ASTC_COMPRESS_MODE s_astcQuality[] = - { - ASTC_COMPRESS_MEDIUM, // Default - ASTC_COMPRESS_THOROUGH, // Highest - ASTC_COMPRESS_FAST, // Fastest - }; - BX_STATIC_ASSERT(Quality::Count == BX_COUNTOF(s_astcQuality)); + static const float s_astcQuality[] = + { + // Standard + ASTCENC_PRE_MEDIUM, // Default + ASTCENC_PRE_THOROUGH, // Highest + ASTCENC_PRE_FAST, // Fastest + // Normal map + ASTCENC_PRE_MEDIUM, // Default + ASTCENC_PRE_THOROUGH, // Highest + ASTCENC_PRE_FAST, // Fastest + }; + BX_STATIC_ASSERT(Quality::Count == BX_COUNTOF(s_astcQuality) ); void imageEncodeFromRgba8(bx::AllocatorI* _allocator, void* _dst, const void* _src, uint32_t _width, uint32_t _height, uint32_t _depth, TextureFormat::Enum _format, Quality::Enum _quality, bx::Error* _err) { @@ -132,18 +142,103 @@ namespace bimg break; case TextureFormat::ASTC4x4: + case TextureFormat::ASTC5x4: case TextureFormat::ASTC5x5: + case TextureFormat::ASTC6x5: case TextureFormat::ASTC6x6: case TextureFormat::ASTC8x5: case TextureFormat::ASTC8x6: + case TextureFormat::ASTC8x8: case TextureFormat::ASTC10x5: + case TextureFormat::ASTC10x6: + case TextureFormat::ASTC10x8: + case TextureFormat::ASTC10x10: + case TextureFormat::ASTC12x10: + case TextureFormat::ASTC12x12: { - const bimg::ImageBlockInfo& astcBlockInfo = bimg::getBlockInfo(_format); + const bimg::ImageBlockInfo& astcBlockInfo = bimg::getBlockInfo(_format); + + astcenc_config config{}; + + uint32_t astcFlags = ASTCENC_FLG_SELF_DECOMPRESS_ONLY; + + if (Quality::NormalMapDefault <= _quality) + { + astcFlags |= ASTCENC_FLG_MAP_NORMAL; + } + + astcenc_error status = astcenc_config_init( + ASTCENC_PRF_LDR + , astcBlockInfo.blockWidth + , astcBlockInfo.blockHeight + , 1 + , s_astcQuality[_quality] + , astcFlags + , &config + ); + + if (status != ASTCENC_SUCCESS) + { + BX_TRACE("astc error in config init %s", astcenc_get_error_string(status) ); + BX_ERROR_SET(_err, BIMG_ERROR, "Unable to initialize astc config!"); + break; + } + + astcenc_context* context; + status = astcenc_context_alloc(&config, 1, &context); + + if (status != ASTCENC_SUCCESS) + { + BX_TRACE("astc error in context alloc %s", astcenc_get_error_string(status) ); + BX_ERROR_SET(_err, BIMG_ERROR, "Unable to alloc astc context!"); + break; + } + + astcenc_image image{}; + image.dim_x = _width; + image.dim_y = _height; + image.dim_z = 1; + image.data_type = ASTCENC_TYPE_U8; + image.data = (void**)&src; + + const size_t blockCountX = (_width + astcBlockInfo.blockWidth - 1) / astcBlockInfo.blockWidth; + const size_t blockCountY = (_height + astcBlockInfo.blockHeight - 1) / astcBlockInfo.blockHeight; + const size_t compLen = blockCountX * blockCountY * 16; - ASTC_COMPRESS_MODE compress_mode = s_astcQuality[_quality]; - ASTC_DECODE_MODE decode_mode = ASTC_DECODE_LDR_LINEAR; + if (Quality::NormalMapDefault <= _quality) + { + static const astcenc_swizzle swizzle + { //0001/rrrg swizzle corresponds to ASTC_ENC_NORMAL_RA + ASTCENC_SWZ_R, + ASTCENC_SWZ_R, + ASTCENC_SWZ_R, + ASTCENC_SWZ_G, + }; + + status = astcenc_compress_image(context, &image, &swizzle, dst, compLen, 0); + } + else + { + static const astcenc_swizzle swizzle + { //0123/rgba swizzle corresponds to ASTC_RGBA + ASTCENC_SWZ_R, + ASTCENC_SWZ_G, + ASTCENC_SWZ_B, + ASTCENC_SWZ_A, + }; + + status = astcenc_compress_image(context, &image, &swizzle, dst, compLen, 0); + } + + if (status != ASTCENC_SUCCESS) + { + BX_TRACE("astc error in compress image %s", astcenc_get_error_string(status) ); + BX_ERROR_SET(_err, BIMG_ERROR, "Unable to compress astc image!"); + astcenc_context_free(context); + break; + } - astc_compress(_width, _height, src, ASTC_RGBA, srcPitch, astcBlockInfo.blockWidth, astcBlockInfo.blockHeight, compress_mode, decode_mode, dst); + astcenc_context_free(context); } break; @@ -152,7 +247,7 @@ namespace bimg break; case TextureFormat::RGBA8: - bx::memCopy(_dst, _src, srcPitch, _height, srcPitch, dstPitch); + bx::memCopy(_dst, dstPitch, _src, srcPitch, srcPitch, _height); break; default: @@ -235,11 +330,19 @@ namespace bimg case TextureFormat::PTC14: case TextureFormat::PTC14A: case TextureFormat::ASTC4x4: + case TextureFormat::ASTC5x4: case TextureFormat::ASTC5x5: + case TextureFormat::ASTC6x5: case TextureFormat::ASTC6x6: case TextureFormat::ASTC8x5: case TextureFormat::ASTC8x6: + case TextureFormat::ASTC8x8: case TextureFormat::ASTC10x5: + case TextureFormat::ASTC10x6: + case TextureFormat::ASTC10x8: + case TextureFormat::ASTC10x10: + case TextureFormat::ASTC12x10: + case TextureFormat::ASTC12x12: { uint8_t* temp = (uint8_t*)BX_ALLOC(_allocator, _width*_height*_depth*4); imageDecodeToRgba8(_allocator, temp, _src, _width, _height, _width*4, _srcFormat); @@ -490,7 +593,7 @@ namespace bimg return rgba[3]; } - float imageAlphaTestCoverage(TextureFormat::Enum _format, uint32_t _width, uint32_t _height, uint32_t _srcPitch, const void* _src, float _alphaRef, float _scale) + float imageAlphaTestCoverage(TextureFormat::Enum _format, uint32_t _width, uint32_t _height, uint32_t _srcPitch, const void* _src, float _alphaRef, float _scale, uint32_t _upscale) { UnpackFn unpack = getUnpack(_format); if (NULL == unpack) @@ -501,7 +604,8 @@ namespace bimg float coverage = 0.0f; const uint8_t* src = (const uint8_t*)_src; const uint32_t xstep = getBitsPerPixel(_format) / 8; - const float numSamples = 8.0f; + const uint32_t numSamples = _upscale; + const float sampleStep = 1.0f / numSamples; for (uint32_t yy = 0, ystep = _srcPitch; yy < _height-1; ++yy, src += ystep) { @@ -513,9 +617,9 @@ namespace bimg float alpha01 = _scale * getAlpha(unpack, data+ystep); float alpha11 = _scale * getAlpha(unpack, data+ystep+xstep); - for (float fy = 0.5f/numSamples; fy < 1.0f; fy += 1.0f) + for (float fy = 0.0f; fy < 1.0f; fy += sampleStep) { - for (float fx = 0.5f/numSamples; fx < 1.0f; fx += 1.0f) + for (float fx = 0.0f; fx < 1.0f; fx += sampleStep) { float alpha = 0.0f + alpha00 * (1.0f - fx) * (1.0f - fy) @@ -536,7 +640,7 @@ namespace bimg return coverage / float(_width*_height*numSamples*numSamples); } - void imageScaleAlphaToCoverage(TextureFormat::Enum _format, uint32_t _width, uint32_t _height, uint32_t _srcPitch, void* _src, float _desiredCoverage, float _alphaRef) + void imageScaleAlphaToCoverage(TextureFormat::Enum _format, uint32_t _width, uint32_t _height, uint32_t _srcPitch, void* _src, float _desiredCoverage, float _alphaRef, uint32_t _upscale) { PackFn pack = getPack(_format); UnpackFn unpack = getUnpack(_format); @@ -550,7 +654,7 @@ namespace bimg float max = 4.0f; float scale = 1.0f; - for (uint32_t ii = 0; ii < 8; ++ii) + for (uint32_t ii = 0; ii < 10; ++ii) { float coverage = imageAlphaTestCoverage( _format @@ -560,6 +664,7 @@ namespace bimg , _src , _alphaRef , scale + , _upscale ); if (coverage < _desiredCoverage) |