Add stats function to serial encoder. Otherwise, continue to use non-stats function in threaded mode.

This commit is contained in:
Pavel Krajcevski 2012-10-07 00:34:06 -04:00
parent 1e6a2d4c7b
commit 99534bc5d0
6 changed files with 98 additions and 15 deletions

View File

@ -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?

View File

@ -2,6 +2,7 @@
#include <stdio.h>
#include <string.h>
#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;
}

View File

@ -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);

View File

@ -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);

View File

@ -5,6 +5,8 @@
#include <string.h>
#include <assert.h>
#include "FileStream.h"
template <typename T>
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();
}
}
}

View File

@ -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