Add bc7enc16 encored for BC7 textures compression on Linux

This commit is contained in:
Wojtek Figat
2021-10-11 14:01:29 +02:00
parent ee2c9a3970
commit faf266800c
6 changed files with 1656 additions and 6 deletions

View File

@@ -53,6 +53,7 @@ public class TextureTool : EngineModule
{
// Use helper lib for decompression
options.PrivateDependencies.Add("detex");
options.PrivateDependencies.Add("bc7enc16");
}
}

View File

@@ -45,9 +45,9 @@
#include <ThirdParty/stb/stb_dxt.h>
#if USE_EDITOR
// Compression libs for Editor
#include <ThirdParty/detex/detex.h>
#include <ThirdParty/bc7enc16/bc7enc16.h>
#endif
static void stbWrite(void* context, void* data, int size)
@@ -523,6 +523,7 @@ bool TextureTool::ConvertStb(TextureData& dst, const TextureData& src, const Pix
return true;
}
#if USE_EDITOR
if (PixelFormatExtensions::IsCompressed(dstFormat))
{
int32 bytesPerBlock;
@@ -539,6 +540,14 @@ bool TextureTool::ConvertStb(TextureData& dst, const TextureData& src, const Pix
}
bool isDstSRGB = PixelFormatExtensions::IsSRGB(dstFormat);
// bc7enc init
bc7enc16_compress_block_params params;
if (dstFormat == PixelFormat::BC7_UNorm || dstFormat == PixelFormat::BC7_UNorm_sRGB)
{
bc7enc16_compress_block_params_init(&params);
bc7enc16_compress_block_init();
}
// Compress all array slices
for (int32 arrayIndex = 0; arrayIndex < arraySize; arrayIndex++)
{
@@ -582,25 +591,30 @@ bool TextureTool::ConvertStb(TextureData& dst, const TextureData& src, const Pix
}
// Compress block
byte* dstBlock = dstMip.Data.Get() + (yBlock * blocksWidth + xBlock) * bytesPerBlock;
switch (dstFormat)
{
case PixelFormat::BC1_UNorm:
case PixelFormat::BC1_UNorm_sRGB:
stb_compress_dxt_block((byte*)dstMip.Data.Get() + (yBlock * blocksWidth + xBlock) * bytesPerBlock, (byte*)&srcBlock, 0, STB_DXT_HIGHQUAL);
stb_compress_dxt_block(dstBlock, (byte*)&srcBlock, 0, STB_DXT_HIGHQUAL);
break;
case PixelFormat::BC3_UNorm:
case PixelFormat::BC3_UNorm_sRGB:
stb_compress_dxt_block((byte*)dstMip.Data.Get() + (yBlock * blocksWidth + xBlock) * bytesPerBlock, (byte*)&srcBlock, 1, STB_DXT_HIGHQUAL);
stb_compress_dxt_block(dstBlock, (byte*)&srcBlock, 1, STB_DXT_HIGHQUAL);
break;
case PixelFormat::BC4_UNorm:
for (int32 i = 1; i < 16; i++)
((byte*)&srcBlock)[i] = srcBlock[i].R;
stb_compress_bc4_block((byte*)dstMip.Data.Get() + (yBlock * blocksWidth + xBlock) * bytesPerBlock, (byte*)&srcBlock);
stb_compress_bc4_block(dstBlock, (byte*)&srcBlock);
break;
case PixelFormat::BC5_UNorm:
for (int32 i = 0; i < 16; i++)
((uint16*)&srcBlock)[i] = srcBlock[i].R << 8 | srcBlock[i].G;
stb_compress_bc5_block((byte*)dstMip.Data.Get() + (yBlock * blocksWidth + xBlock) * bytesPerBlock, (byte*)&srcBlock);
stb_compress_bc5_block(dstBlock, (byte*)&srcBlock);
break;
case PixelFormat::BC7_UNorm:
case PixelFormat::BC7_UNorm_sRGB:
bc7enc16_compress_block(dstBlock, &srcBlock, &params);
break;
default:
LOG(Warning, "Cannot compress image. Unsupported format {0}", static_cast<int32>(dstFormat));
@@ -612,6 +626,7 @@ bool TextureTool::ConvertStb(TextureData& dst, const TextureData& src, const Pix
}
}
else
#endif
{
int32 bytesPerPixel = PixelFormatExtensions::SizeInBytes(dstFormat);
auto dstSampler = TextureTool::GetSampler(dstFormat);

38
Source/ThirdParty/bc7enc16/LICENSE vendored Normal file
View File

@@ -0,0 +1,38 @@
bc7enc16.c/.h is available under 2 licenses -- choose whichever you prefer:
ALTERNATIVE A for bc7enc.c/.h - MIT License
Copyright(c) 2018 Richard Geldreich, Jr.
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files(the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
------------------------------------------------------------------------------
ALTERNATIVE B for bc7enc.c/.h - Public Domain(www.unlicense.org)
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
software, either in source code form or as a compiled binary, for any purpose,
commercial or non - commercial, and by any means.
In jurisdictions that recognize copyright laws, the author or authors of this
software dedicate any and all copyright interest in the software to the public
domain.We make this dedication for the benefit of the public at large and to
the detriment of our heirs and successors.We intend this dedication to be an
overt act of relinquishment in perpetuity of all present and future rights to
this software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
------------------------------------------------------------------------------

View File

@@ -0,0 +1,21 @@
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
using Flax.Build;
/// <summary>
/// https://github.com/richgel999/bc7enc16
/// </summary>
public class bc7enc16 : ThirdPartyModule
{
/// <inheritdoc />
public override void Init()
{
base.Init();
LicenseType = LicenseTypes.MIT;
LicenseFilePath = "LICENSE";
// Merge third-party modules into engine binary
BinaryModuleName = "FlaxEngine";
}
}

1498
Source/ThirdParty/bc7enc16/bc7enc16.cpp vendored Normal file

File diff suppressed because it is too large Load Diff

77
Source/ThirdParty/bc7enc16/bc7enc16.h vendored Normal file
View File

@@ -0,0 +1,77 @@
// File: bc7enc16.h - Richard Geldreich, Jr. - MIT license or public domain (see end of bc7enc16.c)
#include <stdlib.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#define BC7ENC16_BLOCK_SIZE (16)
#define BC7ENC16_MAX_PARTITIONS1 (64)
#define BC7ENC16_MAX_UBER_LEVEL (4)
typedef uint8_t bc7enc16_bool;
#define BC7ENC16_TRUE (1)
#define BC7ENC16_FALSE (0)
typedef struct
{
// m_max_partitions_mode1 may range from 0 (disables mode 1) to BC7ENC16_MAX_PARTITIONS1. The higher this value, the slower the compressor, but the higher the quality.
uint32_t m_max_partitions_mode1;
// Relative RGBA or YCbCrA weights.
uint32_t m_weights[4];
// m_uber_level may range from 0 to BC7ENC16_MAX_UBER_LEVEL. The higher this value, the slower the compressor, but the higher the quality.
uint32_t m_uber_level;
// If m_perceptual is true, colorspace error is computed in YCbCr space, otherwise RGB.
bc7enc16_bool m_perceptual;
// Set m_try_least_squares to false for slightly faster/lower quality compression.
bc7enc16_bool m_try_least_squares;
// When m_mode1_partition_estimation_filterbank, the mode1 partition estimator skips lesser used partition patterns unless they are strongly predicted to be potentially useful.
// There's a slight loss in quality with this enabled (around .08 dB RGB PSNR or .05 dB Y PSNR), but up to a 11% gain in speed depending on the other settings.
bc7enc16_bool m_mode1_partition_estimation_filterbank;
} bc7enc16_compress_block_params;
inline void bc7enc16_compress_block_params_init_linear_weights(bc7enc16_compress_block_params *p)
{
p->m_perceptual = BC7ENC16_FALSE;
p->m_weights[0] = 1;
p->m_weights[1] = 1;
p->m_weights[2] = 1;
p->m_weights[3] = 1;
}
inline void bc7enc16_compress_block_params_init_perceptual_weights(bc7enc16_compress_block_params *p)
{
p->m_perceptual = BC7ENC16_TRUE;
p->m_weights[0] = 128;
p->m_weights[1] = 64;
p->m_weights[2] = 16;
p->m_weights[3] = 32;
}
inline void bc7enc16_compress_block_params_init(bc7enc16_compress_block_params *p)
{
p->m_max_partitions_mode1 = BC7ENC16_MAX_PARTITIONS1;
p->m_try_least_squares = BC7ENC16_TRUE;
p->m_mode1_partition_estimation_filterbank = BC7ENC16_TRUE;
p->m_uber_level = 0;
bc7enc16_compress_block_params_init_perceptual_weights(p);
}
// bc7enc16_compress_block_init() MUST be called before calling bc7enc16_compress_block() (or you'll get artifacts).
void bc7enc16_compress_block_init();
// Packs a single block of 16x16 RGBA pixels (R first in memory) to 128-bit BC7 block pBlock, using either mode 1 and/or 6.
// Alpha blocks will always use mode 6, and by default opaque blocks will use either modes 1 or 6.
// Returns BC7ENC16_TRUE if the block had any pixels with alpha < 255, otherwise it return BC7ENC16_FALSE. (This is not an error code - a block is always encoded.)
bc7enc16_bool bc7enc16_compress_block(void *pBlock, const void *pPixelsRGBA, const bc7enc16_compress_block_params *pComp_params);
#ifdef __cplusplus
}
#endif