mirror of
https://github.com/yuzu-emu/FasTC
synced 2024-11-25 14:18:56 +00:00
Add settings for BPTC compression
This commit is contained in:
parent
6954d7b154
commit
26e816b3db
3 changed files with 94 additions and 16 deletions
|
@ -82,6 +82,67 @@
|
|||
#include <iosfwd>
|
||||
|
||||
namespace BPTCC {
|
||||
// The various available block modes that a BPTC compressor can choose from.
|
||||
// The enum is specialized to be power-of-two values so that an EBlockMode
|
||||
// variable can be used as a bit mask.
|
||||
enum EBlockMode {
|
||||
eBlockMode_Zero = 0,
|
||||
eBlockMode_One = 1,
|
||||
eBlockMode_Two = 2,
|
||||
eBlockMode_Three = 4,
|
||||
eBlockMode_Four = 8,
|
||||
eBlockMode_Five = 16,
|
||||
eBlockMode_Six = 32,
|
||||
eBlockMode_Seven = 64
|
||||
};
|
||||
|
||||
// A shape selection can influence the results of the compressor by choosing
|
||||
// different modes to compress or not compress. The shape index is a value
|
||||
// between zero and sixty-four that corresponds to one of the available
|
||||
// partitioning schemes defined by the BPTC format.
|
||||
struct ShapeSelection {
|
||||
// This is the shape index to use when evaluating two-partition shapes.
|
||||
uint32 m_TwoShapeIndex;
|
||||
|
||||
// This is the shape index to use when evaluating three-partition shapes.
|
||||
uint32 m_ThreeShapeIndex;
|
||||
|
||||
// This is the additional mask to prevent modes once shape selection
|
||||
// is done. This value is &-ed with m_BlockModes from CompressionSettings
|
||||
// to determine what the final considered blocks are.
|
||||
EBlockMode m_AdditionalModes;
|
||||
};
|
||||
|
||||
// A shape selection function is one that selects a BPTC shape from a given
|
||||
// block position and pixel array.
|
||||
typedef ShapeSelection
|
||||
(*ShapeSelectionFn)(uint32 x, uint32 y, uint32 pixels[16]);
|
||||
|
||||
// Compression parameters used to control the BPTC compressor. Each of the
|
||||
// values has a default, so this is not strictly required to perform
|
||||
// compression, but some aspects of the compressor can be user-defined or
|
||||
// overridden.
|
||||
struct CompressionSettings {
|
||||
// The shape selection function to use during compression. The default (when
|
||||
// this variable is set to NULL) is to use the diagonal of the axis-aligned
|
||||
// bounding box of every partition to estimate the error using that
|
||||
// partition would accrue. The shape with the least error is then chosen.
|
||||
// This procedure is done for both two and three partition shapes, and then
|
||||
// every block mode is still available.
|
||||
ShapeSelectionFn m_ShapeSelectionFn;
|
||||
|
||||
// The block modes that the compressor will consider during compression.
|
||||
// This variable is a bit mask of EBlockMode values and by default contains
|
||||
// every mode. This setting can be used to further restrict the search space
|
||||
// and increase compression times.
|
||||
EBlockMode m_BlockModes;
|
||||
|
||||
CompressionSettings()
|
||||
: m_ShapeSelectionFn(NULL)
|
||||
, m_BlockModes(static_cast<EBlockMode>((1 << 7) - 1))
|
||||
{ }
|
||||
};
|
||||
|
||||
// This is the error metric that is applied to our error measurement algorithm
|
||||
// in order to bias calculation towards results that are more in-line with
|
||||
// how the Human Visual System works. Uniform error means that each color
|
||||
|
@ -114,13 +175,15 @@ namespace BPTCC {
|
|||
|
||||
// Compress the image given as RGBA data to BPTC format. Width and Height are
|
||||
// the dimensions of the image in pixels.
|
||||
void Compress(const FasTC::CompressionJob &);
|
||||
void Compress(const FasTC::CompressionJob &,
|
||||
CompressionSettings settings = CompressionSettings());
|
||||
|
||||
// Perform a compression while recording all of the choices the compressor
|
||||
// made into a list of statistics. We can use this to see whether or not
|
||||
// certain heuristics are working, such as whether or not certain modes are
|
||||
// being chosen more often than others, etc.
|
||||
void CompressWithStats(const FasTC::CompressionJob &, std::ostream *logStream);
|
||||
void CompressWithStats(const FasTC::CompressionJob &, std::ostream *logStream,
|
||||
CompressionSettings settings = CompressionSettings());
|
||||
|
||||
#ifdef HAS_SSE_41
|
||||
// Compress the image given as RGBA data to BPTC format using an algorithm
|
||||
|
@ -146,8 +209,7 @@ namespace BPTCC {
|
|||
std::ostream *logStream);
|
||||
#endif
|
||||
|
||||
// Decompress the image given as BPTC data to R8G8B8A8 format. Width and Height
|
||||
// are the dimensions of the image in pixels.
|
||||
// Decompress the image given as BPTC data to R8G8B8A8 format.
|
||||
void Decompress(const FasTC::DecompressionJob &);
|
||||
} // namespace BPTCC
|
||||
|
||||
|
|
|
@ -1553,9 +1553,13 @@ std::ostream &operator<<(const BlockLogger &bl, const T &v) {
|
|||
}
|
||||
|
||||
// Function prototypes
|
||||
static void CompressBC7Block(const uint32 *block, uint8 *outBuf);
|
||||
static void CompressBC7Block(
|
||||
const uint32 *block, uint8 *outBuf, const BlockLogger &logStream
|
||||
const uint32 block[16], uint8 *outBuf,
|
||||
const CompressionSettings = CompressionSettings()
|
||||
);
|
||||
static void CompressBC7Block(
|
||||
const uint32 block[16], uint8 *outBuf, const BlockLogger &logStream,
|
||||
const CompressionSettings = CompressionSettings()
|
||||
);
|
||||
|
||||
static int gQualityLevel = 50;
|
||||
|
@ -1638,7 +1642,7 @@ void GetBlock(const uint32 x, const uint32 y, const uint32 pixelsWide,
|
|||
// the size of the image in pixels. The buffer pointed to by outBuf should be
|
||||
// large enough to store the compressed image. This implementation has an 4:1
|
||||
// compression ratio.
|
||||
void Compress(const FasTC::CompressionJob &cj) {
|
||||
void Compress(const FasTC::CompressionJob &cj, CompressionSettings settings) {
|
||||
const uint32 *inPixels = reinterpret_cast<const uint32 *>(cj.InBuf());
|
||||
const uint32 kBlockSz = GetBlockSize(FasTC::eCompressionFormat_BPTC);
|
||||
uint8 *outBuf = cj.OutBuf() + cj.CoordsToBlockIdx(cj.XStart(), cj.YStart()) * kBlockSz;
|
||||
|
@ -1651,7 +1655,7 @@ void Compress(const FasTC::CompressionJob &cj) {
|
|||
|
||||
uint32 block[16];
|
||||
GetBlock(i, j, cj.Width(), inPixels, block);
|
||||
CompressBC7Block(block, outBuf);
|
||||
CompressBC7Block(block, outBuf, settings);
|
||||
|
||||
#ifndef NDEBUG
|
||||
const uint8 *inBlock = reinterpret_cast<const uint8 *>(block);
|
||||
|
@ -1740,7 +1744,8 @@ void CompressAtomic(FasTC::CompressionJobList &cjl) {
|
|||
}
|
||||
#endif // HAS_ATOMICS
|
||||
|
||||
void CompressWithStats(const FasTC::CompressionJob &cj, std::ostream *logStream) {
|
||||
void CompressWithStats(const FasTC::CompressionJob &cj, std::ostream *logStream,
|
||||
CompressionSettings settings) {
|
||||
const uint32 *inPixels = reinterpret_cast<const uint32 *>(cj.InBuf());
|
||||
const uint32 kBlockSz = GetBlockSize(FasTC::eCompressionFormat_BPTC);
|
||||
uint8 *outBuf = cj.OutBuf() + cj.CoordsToBlockIdx(cj.XStart(), cj.YStart()) * kBlockSz;
|
||||
|
@ -1755,9 +1760,9 @@ void CompressWithStats(const FasTC::CompressionJob &cj, std::ostream *logStream)
|
|||
|
||||
if(logStream) {
|
||||
uint64 blockIdx = cj.CoordsToBlockIdx(i, j);
|
||||
CompressBC7Block(block, outBuf, BlockLogger(blockIdx, *logStream));
|
||||
CompressBC7Block(block, outBuf, BlockLogger(blockIdx, *logStream), settings);
|
||||
} else {
|
||||
CompressBC7Block(block, outBuf);
|
||||
CompressBC7Block(block, outBuf, settings);
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
@ -1992,7 +1997,8 @@ static double EstimateThreeClusterError(RGBACluster &c) {
|
|||
return error;
|
||||
}
|
||||
|
||||
static void CompressBC7Block(const uint32 *block, uint8 *outBuf) {
|
||||
static void CompressBC7Block(const uint32 block[16], uint8 *outBuf,
|
||||
const CompressionSettings settings) {
|
||||
// All a single color?
|
||||
if(AllOneColor(block)) {
|
||||
BitStream bStrm(outBuf, 128, 0);
|
||||
|
@ -2253,7 +2259,8 @@ static void PrintStat(const BlockLogger &lgr, const char *stat, const T &v) {
|
|||
|
||||
// Compress a single block but collect statistics as well...
|
||||
static void CompressBC7Block(
|
||||
const uint32 *block, uint8 *outBuf, const BlockLogger &logStream
|
||||
const uint32 block[16], uint8 *outBuf, const BlockLogger &logStream,
|
||||
const CompressionSettings settings
|
||||
) {
|
||||
|
||||
class RAIIStatSaver {
|
||||
|
|
|
@ -76,6 +76,15 @@ static inline T sad(const T &a, const T &b) {
|
|||
return (a > b)? a - b : b - a;
|
||||
}
|
||||
|
||||
static void CompressBPTC(const CompressionJob &cj) {
|
||||
BPTCC::Compress(cj);
|
||||
}
|
||||
|
||||
static void CompressBPTCWithStats(const CompressionJob &cj,
|
||||
std::ostream *strm) {
|
||||
BPTCC::CompressWithStats(cj, strm);
|
||||
}
|
||||
|
||||
static void CompressPVRTC(const CompressionJob &cj) {
|
||||
PVRTCC::Compress(cj);
|
||||
}
|
||||
|
@ -109,7 +118,7 @@ static CompressionFuncWithStats ChooseFuncFromSettingsWithStats(const SCompress
|
|||
return BPTCC::CompressNVTTWithStats;
|
||||
else
|
||||
#endif
|
||||
return BPTCC::CompressWithStats;
|
||||
return CompressBPTCWithStats;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -138,7 +147,7 @@ static CompressionFunc ChooseFuncFromSettings(const SCompressionSettings &s) {
|
|||
return BPTCC::CompressNVTT;
|
||||
else
|
||||
#endif
|
||||
return BPTCC::Compress;
|
||||
return CompressBPTC;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -223,7 +232,7 @@ class AtomicThreadUnit : public TCCallable {
|
|||
virtual ~AtomicThreadUnit() { }
|
||||
virtual void operator()() {
|
||||
m_Barrier->Wait();
|
||||
if(m_CmpFnc == BPTCC::Compress) {
|
||||
if(m_CmpFnc == CompressBPTC) {
|
||||
BPTCC::CompressAtomic(m_CompressionJobList);
|
||||
}
|
||||
else {
|
||||
|
|
Loading…
Reference in a new issue