From 99534bc5d028c8cc01af1ef5ba2445a04e95d9f1 Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Sun, 7 Oct 2012 00:34:06 -0400 Subject: [PATCH] Add stats function to serial encoder. Otherwise, continue to use non-stats function in threaded mode. --- BPTCEncoder/src/BC7Compressor.cpp | 6 ++++- CLTool/src/clunix.cpp | 12 +++++++++- Core/include/BlockStats.h | 5 +++- Core/include/TexComp.h | 19 ++++++++++++++++ Core/src/BlockStats.cpp | 33 ++++++++++++++++++++++++--- Core/src/TexComp.cpp | 38 +++++++++++++++++++++++-------- 6 files changed, 98 insertions(+), 15 deletions(-) diff --git a/BPTCEncoder/src/BC7Compressor.cpp b/BPTCEncoder/src/BC7Compressor.cpp index 93949b2..f645cf5 100755 --- a/BPTCEncoder/src/BC7Compressor.cpp +++ b/BPTCEncoder/src/BC7Compressor.cpp @@ -1466,7 +1466,7 @@ namespace BC7C } } - void CompressImageBC7( + void CompressImageBC7Stats( const unsigned char *inBuf, unsigned char *outBuf, unsigned int width, @@ -1655,6 +1655,10 @@ namespace BC7C uint32 blockIdx = 0; if(statManager) { blockIdx = statManager->BeginBlock(); + + for(int i = 0; i < kNumBlockStats; i++) { + statManager->AddStat(blockIdx, BlockStat(kBlockStatString[i], 0)); + } } // All a single color? diff --git a/CLTool/src/clunix.cpp b/CLTool/src/clunix.cpp index ded6e88..64ebe60 100644 --- a/CLTool/src/clunix.cpp +++ b/CLTool/src/clunix.cpp @@ -2,6 +2,7 @@ #include #include +#include "BlockStats.h" #include "TexComp.h" #include "ImageFile.h" #include "Image.h" @@ -99,7 +100,12 @@ int main(int argc, char **argv) { if(NULL == img) { fprintf(stderr, "Error loading file: %s\n", argv[fileArg]); return 1; - } + } + + const Image *img = file.GetImage(); + + int numBlocks = (img->GetWidth() * img->GetHeight())/16; + BlockStatManager *statManager = new BlockStatManager(numBlocks); SCompressionSettings settings; settings.bUseSIMD = bUseSIMD; @@ -107,6 +113,7 @@ int main(int argc, char **argv) { settings.iQuality = quality; settings.iNumCompressions = numCompressions; settings.iJobSize = numJobs; + settings.pStatManager = statManager; CompressedImage *ci = img->Compress(settings); if(NULL == ci) { @@ -122,8 +129,11 @@ int main(int argc, char **argv) { fprintf(stderr, "Error computing PSNR\n"); } + statManager->ToFile(strcat(argv[fileArg], "-log.txt")); + // Cleanup delete ci; + delete statManager; return 0; } diff --git a/Core/include/BlockStats.h b/Core/include/BlockStats.h index 8c0a5d3..47c6af3 100644 --- a/Core/include/BlockStats.h +++ b/Core/include/BlockStats.h @@ -16,7 +16,7 @@ public: private: static const int kStatNameSz = 32; - char m_StatName[kStatNameSz]; + CHAR m_StatName[kStatNameSz]; union { uint64 m_IntStat; double m_FloatStat; @@ -31,6 +31,7 @@ class BlockStatManager { uint32 BeginBlock(); void AddStat(uint32 blockIdx, const BlockStat &stat); + void ToFile(const CHAR *filename); private: @@ -40,6 +41,8 @@ class BlockStatManager { ~BlockStatList(); void AddStat(const BlockStat &stat); + BlockStat GetStat() const { return m_Stat; } + const BlockStatList *GetTail() const { return m_Tail; } private: BlockStatList(const BlockStat &stat); diff --git a/Core/include/TexComp.h b/Core/include/TexComp.h index 012df35..4661797 100644 --- a/Core/include/TexComp.h +++ b/Core/include/TexComp.h @@ -6,6 +6,7 @@ // Forward declarations class ImageFile; class CompressedImage; +class BlockStatManager; struct SCompressionSettings { SCompressionSettings(); // defaults @@ -34,6 +35,12 @@ struct SCompressionSettings { // number of threads, and each thread will do it's job and // exit. int iJobSize; + + // This is an optinal pointer to a stat manager class. If + // instantiated and the proper function pointer is defined + // then the compression routine that collects the stats will + // be called. + BlockStatManager *pStatManager; }; extern bool CompressImageData( @@ -55,6 +62,18 @@ typedef void (* CompressionFunc)( unsigned int height // Image height ); +// A compression function format. It takes the raw data and image dimensions and +// returns the compressed image data into outData. It is assumed that there is +// enough space allocated for outData to store the compressed data. Allocation +// is dependent on the compression format. +typedef void (* CompressionFuncWithStats)( + const unsigned char *inData, // Raw image data + unsigned char *outData, // Buffer to store compressed data. + unsigned int width, // Image width + unsigned int height, // Image height + BlockStatManager &statManager// Stat manager +); + // This function computes the Peak Signal to Noise Ratio between a // compressed image and a raw image. extern double ComputePSNR(const CompressedImage &ci, const ImageFile &file); diff --git a/Core/src/BlockStats.cpp b/Core/src/BlockStats.cpp index 72ac454..bda3d79 100644 --- a/Core/src/BlockStats.cpp +++ b/Core/src/BlockStats.cpp @@ -5,6 +5,8 @@ #include #include +#include "FileStream.h" + template static T max(const T &a, const T &b) { return (a > b)? a : b; @@ -59,10 +61,10 @@ BlockStatManager::~BlockStatManager() { } uint32 BlockStatManager::BeginBlock() { - if((m_NextBlock + 1) == m_BlockStatListSz) { + if(m_NextBlock == m_BlockStatListSz) { fprintf(stderr, "WARNING -- BlockStatManager::BeginBlock(), reached end of block list.\n"); assert(false); - return m_NextBlock; + return m_NextBlock-1; } TCLock lock(m_Mutex); @@ -108,7 +110,7 @@ void BlockStatManager::BlockStatList::AddStat(const BlockStat &stat) { if(strncmp(stat.m_StatName, m_Stat.m_StatName, BlockStat::kStatNameSz) == 0) { m_Stat = stat; } - else if(!m_Tail) { + else if(m_Tail) { m_Tail->AddStat(stat); } else { @@ -120,3 +122,28 @@ void BlockStatManager::BlockStatList::AddStat(const BlockStat &stat) { } } } + +void BlockStatManager::ToFile(const CHAR *filename) { + + FileStream fstr (filename, eFileMode_Write); + + for(int i = 0; i < m_BlockStatListSz; i++) { + const BlockStatList *head = &(m_BlockStatList[i]); + while(head) { + BlockStat s = head->GetStat(); + + CHAR statStr[256]; + snprintf(statStr, 256, "%d: %s, %llu, %f\n", i, s.m_StatName, s.m_IntStat, s.m_FloatStat); + + int statStrLen = strlen(statStr); + if(statStrLen > 255) { + statStr[255] = '\n'; + statStrLen = 255; + } + fstr.Write((uint8 *)statStr, statStrLen); + + head = head->GetTail(); + } + } + +} diff --git a/Core/src/TexComp.cpp b/Core/src/TexComp.cpp index 9f7f43a..45a45a3 100644 --- a/Core/src/TexComp.cpp +++ b/Core/src/TexComp.cpp @@ -43,6 +43,17 @@ SCompressionSettings:: SCompressionSettings() clamp(iQuality, 0, 256); } +static CompressionFuncWithStats ChooseFuncFromSettingsWithStats(const SCompressionSettings &s) { + switch(s.format) { + case eCompressionFormat_BPTC: + { + return BC7C::CompressImageBC7Stats; + } + break; + } + return NULL; +} + static CompressionFunc ChooseFuncFromSettings(const SCompressionSettings &s) { switch(s.format) { case eCompressionFormat_BPTC: @@ -54,7 +65,7 @@ static CompressionFunc ChooseFuncFromSettings(const SCompressionSettings &s) { } else { #endif - return BC7C::CompressImageBC7; + return BC7C::CompressImageBC7; #ifdef HAS_SSE_41 } #endif @@ -72,9 +83,11 @@ static double CompressImageInSerial( const unsigned char *imgData, const unsigned int imgDataSz, const SCompressionSettings &settings, - const CompressionFunc f, unsigned char *outBuf ) { + CompressionFunc f = ChooseFuncFromSettings(settings); + CompressionFuncWithStats fStats = ChooseFuncFromSettingsWithStats(settings); + double cmpTimeTotal = 0.0; for(int i = 0; i < settings.iNumCompressions; i++) { @@ -84,7 +97,12 @@ static double CompressImageInSerial( stopWatch.Start(); // !FIXME! We're assuming that we have 4x4 blocks here... - (*f)(imgData, outBuf, imgDataSz / 16, 4); + if(fStats && settings.pStatManager) { + (*fStats)(imgData, outBuf, imgDataSz / 16, 4, *(settings.pStatManager)); + } + else { + (*f)(imgData, outBuf, imgDataSz / 16, 4); + } stopWatch.Stop(); @@ -99,10 +117,11 @@ static double CompressImageWithThreads( const unsigned char *imgData, const unsigned int imgDataSz, const SCompressionSettings &settings, - const CompressionFunc f, unsigned char *outBuf ) { + CompressionFunc f = ChooseFuncFromSettings(settings); + ThreadGroup tgrp (settings.iNumThreads, imgData, imgDataSz, f, outBuf); if(!(tgrp.PrepareThreads())) { assert(!"Thread group failed to prepare threads?!"); @@ -121,7 +140,7 @@ static double CompressImageWithThreads( cmpTimeTotal += tgrp.GetStopWatch().TimeInMilliseconds(); } - tgrp.CleanUpThreads(); + tgrp.CleanUpThreads(); double cmpTime = cmpTimeTotal / double(settings.iNumCompressions); return cmpTime; @@ -131,9 +150,10 @@ static double CompressImageWithWorkerQueue( const unsigned char *imgData, const unsigned int imgDataSz, const SCompressionSettings &settings, - const CompressionFunc f, unsigned char *outBuf ) { + CompressionFunc f = ChooseFuncFromSettings(settings); + WorkerQueue wq ( settings.iNumCompressions, settings.iNumThreads, @@ -196,12 +216,12 @@ bool CompressImageData( if(settings.iNumThreads > 1) { if(settings.iJobSize > 0) - cmpMSTime = CompressImageWithWorkerQueue(data, dataSz, settings, f, cmpData); + cmpMSTime = CompressImageWithWorkerQueue(data, dataSz, settings, cmpData); else - cmpMSTime = CompressImageWithThreads(data, dataSz, settings, f, cmpData); + cmpMSTime = CompressImageWithThreads(data, dataSz, settings, cmpData); } else { - cmpMSTime = CompressImageInSerial(data, dataSz, settings, f, cmpData); + cmpMSTime = CompressImageInSerial(data, dataSz, settings, cmpData); } // Report compression time