From 93a3b3b92c167f20d0ff00b2e9f4df94e5842612 Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Sun, 7 Oct 2012 17:33:41 -0400 Subject: [PATCH] Add some more stats to BC7 compressor. NOT THREAD SAFE --- BPTCEncoder/src/BC7Compressor.cpp | 137 +++++++++++++++++++++--------- 1 file changed, 97 insertions(+), 40 deletions(-) diff --git a/BPTCEncoder/src/BC7Compressor.cpp b/BPTCEncoder/src/BC7Compressor.cpp index f645cf5..6ddbce9 100755 --- a/BPTCEncoder/src/BC7Compressor.cpp +++ b/BPTCEncoder/src/BC7Compressor.cpp @@ -41,6 +41,24 @@ enum EBlockStats { eBlockStat_Path, eBlockStat_Mode, + eBlockStat_ModeZeroEstimate, + eBlockStat_ModeOneEstimate, + eBlockStat_ModeTwoEstimate, + eBlockStat_ModeThreeEstimate, + eBlockStat_ModeFourEstimate, + eBlockStat_ModeFiveEstimate, + eBlockStat_ModeSixEstimate, + eBlockStat_ModeSevenEstimate, + + eBlockStat_ModeZeroError, + eBlockStat_ModeOneError, + eBlockStat_ModeTwoError, + eBlockStat_ModeThreeError, + eBlockStat_ModeFourError, + eBlockStat_ModeFiveError, + eBlockStat_ModeSixError, + eBlockStat_ModeSevenError, + kNumBlockStats }; @@ -1423,6 +1441,8 @@ namespace BC7C static int gModeChosen = -1; static int gBestMode = -1; + static double gModeEstimate[ BC7CompressionMode::kNumModes ]; + static double gModeError[ BC7CompressionMode::kNumModes ]; static void DecompressBC7Block(const uint8 block[16], uint32 outBuf[16]); @@ -1525,6 +1545,7 @@ namespace BC7C BC7CompressionMode compressor1(1, opaque); double bestError = compressor1.Compress(tmpStream1, shapeIdx, clusters); + gModeError[1] = bestError; memcpy(outBuf, tempBuf1, 16); gModeChosen = 1; if(bestError == 0.0) { @@ -1535,8 +1556,9 @@ namespace BC7C BitStream tmpStream3(tempBuf3, 128, 0); BC7CompressionMode compressor3(3, opaque); - double error; - if((error = compressor3.Compress(tmpStream3, shapeIdx, clusters)) < bestError) { + double error = compressor3.Compress(tmpStream3, shapeIdx, clusters); + gModeError[3] = error; + if(error < bestError) { gModeChosen = 3; bestError = error; memcpy(outBuf, tempBuf3, 16); @@ -1551,7 +1573,9 @@ namespace BC7C uint8 tempBuf7[16]; BitStream tmpStream7(tempBuf7, 128, 0); BC7CompressionMode compressor7(7, opaque); - if((error = compressor7.Compress(tmpStream7, shapeIdx, clusters)) < bestError) { + error = compressor7.Compress(tmpStream7, shapeIdx, clusters); + gModeError[7] = error; + if(error < bestError) { gModeChosen = 7; memcpy(outBuf, tempBuf7, 16); return error; @@ -1573,13 +1597,16 @@ namespace BC7C BC7CompressionMode compressor2(2, opaque); double error, bestError = (shapeIdx < 16)? compressor0.Compress(tmpStream0, shapeIdx, clusters) : DBL_MAX; + gModeError[0] = bestError; gModeChosen = 0; memcpy(outBuf, tempBuf0, 16); if(bestError == 0.0) { return 0.0; } - if((error = compressor2.Compress(tmpStream2, shapeIdx, clusters)) < bestError) { + error = compressor2.Compress(tmpStream2, shapeIdx, clusters); + gModeError[2] = error; + if(error < bestError) { gModeChosen = 2; memcpy(outBuf, tempBuf2, 16); return error; @@ -1630,11 +1657,18 @@ namespace BC7C c.GetBoundingBox(Min, Max); v = Max - Min; if(v * v == 0) { + gModeEstimate[1] = gModeEstimate[3] = 0.0; return 0.0; } const float *w = BC7C::GetErrorMetric(); - return 0.0001 + c.QuantizedError(Min, Max, 8, 0xFFFFFFFF, RGBAVector(w[0], w[1], w[2], w[3])); + const double err1 = 0.0001 + c.QuantizedError(Min, Max, 8, 0xFFFCFCFC, RGBAVector(w[0], w[1], w[2], w[3])); + gModeEstimate[1] = min(gModeEstimate[1], err1); + + const double err3 = 0.0001 + c.QuantizedError(Min, Max, 8, 0xFFFEFEFE, RGBAVector(w[0], w[1], w[2], w[3])); + gModeEstimate[3] = min(gModeEstimate[3], err3); + + return min(err1, err3); } static double EstimateThreeClusterError(RGBACluster &c) { @@ -1642,25 +1676,64 @@ namespace BC7C c.GetBoundingBox(Min, Max); v = Max - Min; if(v * v == 0) { + gModeEstimate[0] = gModeEstimate[2] = 0.0; return 0.0; } const float *w = BC7C::GetErrorMetric(); - return 0.0001 + c.QuantizedError(Min, Max, 4, 0xFFFFFFFF, RGBAVector(w[0], w[1], w[2], w[3])); + const double err0 = 0.0001 + c.QuantizedError(Min, Max, 4, 0xFFF0F0F0, RGBAVector(w[0], w[1], w[2], w[3])); + gModeEstimate[0] = min(gModeEstimate[0], err0); + + const double err2 = 0.0001 + c.QuantizedError(Min, Max, 4, 0xFFF8F8F8, RGBAVector(w[0], w[1], w[2], w[3])); + gModeEstimate[2] = min(gModeEstimate[2], err2); + + return min(err0, err2); } // Compress a single block. static void CompressBC7Block(const uint32 *block, uint8 *outBuf, BlockStatManager *statManager) { + class RAIIStatSaver { + private: + uint32 m_BlockIdx; + BlockStatManager *m_BSM; + public: + RAIIStatSaver(uint32 blockIdx, BlockStatManager *m) : m_BlockIdx(blockIdx), m_BSM(m) { } + ~RAIIStatSaver() { + if(!m_BSM) + return; + + BlockStat s (kBlockStatString[eBlockStat_Mode], gBestMode); + m_BSM->AddStat(m_BlockIdx, s); + + for(int i = 0; i < BC7CompressionMode::kNumModes; i++) { + s = BlockStat(kBlockStatString[eBlockStat_ModeZeroEstimate + i], gModeEstimate[i]); + m_BSM->AddStat(m_BlockIdx, s); + + s = BlockStat(kBlockStatString[eBlockStat_ModeZeroError + i], gModeError[i]); + m_BSM->AddStat(m_BlockIdx, s); + } + } + }; + uint32 blockIdx = 0; if(statManager) { + + // reset global variables... + gBestMode = 0; + for(int i = 0; i < BC7CompressionMode::kNumModes; i++){ + gModeError[i] = gModeEstimate[i] = DBL_MAX; + } + blockIdx = statManager->BeginBlock(); for(int i = 0; i < kNumBlockStats; i++) { - statManager->AddStat(blockIdx, BlockStat(kBlockStatString[i], 0)); + statManager->AddStat(blockIdx, BlockStat(kBlockStatString[i], 0)); } } + RAIIStatSaver __statsaver__(blockIdx, statManager); + // All a single color? if(AllOneColor(block)) { BitStream bStrm(outBuf, 128, 0); @@ -1670,9 +1743,6 @@ namespace BC7C if(statManager) { BlockStat s = BlockStat(kBlockStatString[eBlockStat_Path], 0); statManager->AddStat(blockIdx, s); - - s = BlockStat(kBlockStatString[eBlockStat_Mode], 5); - statManager->AddStat(blockIdx, s); } return; @@ -1701,14 +1771,26 @@ namespace BC7C if(statManager) { BlockStat s = BlockStat(kBlockStatString[eBlockStat_Path], 1); statManager->AddStat(blockIdx, s); - - s = BlockStat(kBlockStatString[eBlockStat_Mode], gBestMode); - statManager->AddStat(blockIdx, s); } return; } + // First, estimate the error it would take to compress a single line with + // mode 6... + { + RGBAVector Min, Max, v; + blockCluster.GetBoundingBox(Min, Max); + v = Max - Min; + if(v * v == 0) { + gModeEstimate[6] = 0.0; + } + else { + const float *w = GetErrorMetric(); + gModeEstimate[6] = 0.0001 + blockCluster.QuantizedError(Min, Max, 4, 0xFFF0F0F0, RGBAVector(w[0], w[1], w[2], w[3])); + } + } + // First we must figure out which shape to use. To do this, simply // see which shape has the smallest sum of minimum bounding spheres. double bestError[2] = { DBL_MAX, DBL_MAX }; @@ -1769,9 +1851,6 @@ namespace BC7C if(statManager) { BlockStat s = BlockStat(kBlockStatString[eBlockStat_Path], 2); statManager->AddStat(blockIdx, s); - - s = BlockStat(kBlockStatString[eBlockStat_Mode], gBestMode); - statManager->AddStat(blockIdx, s); } return; @@ -1796,15 +1875,10 @@ namespace BC7C BitStream tempStream1 (tempBuf1, 128, 0); BC7CompressionMode compressor(6, opaque); - double best = compressor.Compress(tempStream1, 0, &blockCluster); + double best = compressor.Compress(tempStream1, 0, &blockCluster); + gModeError[6] = best; gBestMode = 6; if(best == 0.0f) { - - if(statManager) { - BlockStat s = BlockStat(kBlockStatString[eBlockStat_Mode], gBestMode); - statManager->AddStat(blockIdx, s); - } - memcpy(outBuf, tempBuf1, 16); return; } @@ -1841,12 +1915,6 @@ namespace BC7C if(error == 0.0f) { memcpy(outBuf, tempBuf2, 16); - - if(statManager) { - BlockStat s = BlockStat(kBlockStatString[eBlockStat_Mode], gBestMode); - statManager->AddStat(blockIdx, s); - } - return; } else { @@ -1859,22 +1927,11 @@ namespace BC7C gBestMode = gModeChosen; memcpy(outBuf, tempBuf2, 16); - - if(statManager) { - BlockStat s = BlockStat(kBlockStatString[eBlockStat_Mode], gBestMode); - statManager->AddStat(blockIdx, s); - } - return; } } memcpy(outBuf, tempBuf1, 16); - - if(statManager) { - BlockStat s = BlockStat(kBlockStatString[eBlockStat_Mode], gBestMode); - statManager->AddStat(blockIdx, s); - } } static void DecompressBC7Block(const uint8 block[16], uint32 outBuf[16]) {