mirror of
https://github.com/yuzu-emu/FasTC.git
synced 2024-11-24 10:25:43 +01:00
Add settings for BPTC compression
This commit is contained in:
parent
6954d7b154
commit
26e816b3db
@ -82,6 +82,67 @@
|
|||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
|
|
||||||
namespace BPTCC {
|
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
|
// 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
|
// 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
|
// 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
|
// Compress the image given as RGBA data to BPTC format. Width and Height are
|
||||||
// the dimensions of the image in pixels.
|
// 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
|
// 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
|
// 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
|
// certain heuristics are working, such as whether or not certain modes are
|
||||||
// being chosen more often than others, etc.
|
// 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
|
#ifdef HAS_SSE_41
|
||||||
// Compress the image given as RGBA data to BPTC format using an algorithm
|
// Compress the image given as RGBA data to BPTC format using an algorithm
|
||||||
@ -146,8 +209,7 @@ namespace BPTCC {
|
|||||||
std::ostream *logStream);
|
std::ostream *logStream);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Decompress the image given as BPTC data to R8G8B8A8 format. Width and Height
|
// Decompress the image given as BPTC data to R8G8B8A8 format.
|
||||||
// are the dimensions of the image in pixels.
|
|
||||||
void Decompress(const FasTC::DecompressionJob &);
|
void Decompress(const FasTC::DecompressionJob &);
|
||||||
} // namespace BPTCC
|
} // namespace BPTCC
|
||||||
|
|
||||||
|
@ -1553,9 +1553,13 @@ std::ostream &operator<<(const BlockLogger &bl, const T &v) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Function prototypes
|
// Function prototypes
|
||||||
static void CompressBC7Block(const uint32 *block, uint8 *outBuf);
|
|
||||||
static void CompressBC7Block(
|
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;
|
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
|
// 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
|
// large enough to store the compressed image. This implementation has an 4:1
|
||||||
// compression ratio.
|
// 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 *inPixels = reinterpret_cast<const uint32 *>(cj.InBuf());
|
||||||
const uint32 kBlockSz = GetBlockSize(FasTC::eCompressionFormat_BPTC);
|
const uint32 kBlockSz = GetBlockSize(FasTC::eCompressionFormat_BPTC);
|
||||||
uint8 *outBuf = cj.OutBuf() + cj.CoordsToBlockIdx(cj.XStart(), cj.YStart()) * kBlockSz;
|
uint8 *outBuf = cj.OutBuf() + cj.CoordsToBlockIdx(cj.XStart(), cj.YStart()) * kBlockSz;
|
||||||
@ -1651,7 +1655,7 @@ void Compress(const FasTC::CompressionJob &cj) {
|
|||||||
|
|
||||||
uint32 block[16];
|
uint32 block[16];
|
||||||
GetBlock(i, j, cj.Width(), inPixels, block);
|
GetBlock(i, j, cj.Width(), inPixels, block);
|
||||||
CompressBC7Block(block, outBuf);
|
CompressBC7Block(block, outBuf, settings);
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
const uint8 *inBlock = reinterpret_cast<const uint8 *>(block);
|
const uint8 *inBlock = reinterpret_cast<const uint8 *>(block);
|
||||||
@ -1740,7 +1744,8 @@ void CompressAtomic(FasTC::CompressionJobList &cjl) {
|
|||||||
}
|
}
|
||||||
#endif // HAS_ATOMICS
|
#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 *inPixels = reinterpret_cast<const uint32 *>(cj.InBuf());
|
||||||
const uint32 kBlockSz = GetBlockSize(FasTC::eCompressionFormat_BPTC);
|
const uint32 kBlockSz = GetBlockSize(FasTC::eCompressionFormat_BPTC);
|
||||||
uint8 *outBuf = cj.OutBuf() + cj.CoordsToBlockIdx(cj.XStart(), cj.YStart()) * kBlockSz;
|
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) {
|
if(logStream) {
|
||||||
uint64 blockIdx = cj.CoordsToBlockIdx(i, j);
|
uint64 blockIdx = cj.CoordsToBlockIdx(i, j);
|
||||||
CompressBC7Block(block, outBuf, BlockLogger(blockIdx, *logStream));
|
CompressBC7Block(block, outBuf, BlockLogger(blockIdx, *logStream), settings);
|
||||||
} else {
|
} else {
|
||||||
CompressBC7Block(block, outBuf);
|
CompressBC7Block(block, outBuf, settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
@ -1992,7 +1997,8 @@ static double EstimateThreeClusterError(RGBACluster &c) {
|
|||||||
return error;
|
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?
|
// All a single color?
|
||||||
if(AllOneColor(block)) {
|
if(AllOneColor(block)) {
|
||||||
BitStream bStrm(outBuf, 128, 0);
|
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...
|
// Compress a single block but collect statistics as well...
|
||||||
static void CompressBC7Block(
|
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 {
|
class RAIIStatSaver {
|
||||||
|
@ -76,6 +76,15 @@ static inline T sad(const T &a, const T &b) {
|
|||||||
return (a > b)? a - b : b - a;
|
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) {
|
static void CompressPVRTC(const CompressionJob &cj) {
|
||||||
PVRTCC::Compress(cj);
|
PVRTCC::Compress(cj);
|
||||||
}
|
}
|
||||||
@ -109,7 +118,7 @@ static CompressionFuncWithStats ChooseFuncFromSettingsWithStats(const SCompress
|
|||||||
return BPTCC::CompressNVTTWithStats;
|
return BPTCC::CompressNVTTWithStats;
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
return BPTCC::CompressWithStats;
|
return CompressBPTCWithStats;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -138,7 +147,7 @@ static CompressionFunc ChooseFuncFromSettings(const SCompressionSettings &s) {
|
|||||||
return BPTCC::CompressNVTT;
|
return BPTCC::CompressNVTT;
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
return BPTCC::Compress;
|
return CompressBPTC;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -223,7 +232,7 @@ class AtomicThreadUnit : public TCCallable {
|
|||||||
virtual ~AtomicThreadUnit() { }
|
virtual ~AtomicThreadUnit() { }
|
||||||
virtual void operator()() {
|
virtual void operator()() {
|
||||||
m_Barrier->Wait();
|
m_Barrier->Wait();
|
||||||
if(m_CmpFnc == BPTCC::Compress) {
|
if(m_CmpFnc == CompressBPTC) {
|
||||||
BPTCC::CompressAtomic(m_CompressionJobList);
|
BPTCC::CompressAtomic(m_CompressionJobList);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
Loading…
Reference in New Issue
Block a user