Testsuite outputs graphs using google api.
This commit is contained in:
parent
5f845513ee
commit
1d4a2ea710
@ -72,7 +72,7 @@ ELSE(MAYA_FOUND)
|
|||||||
ENDIF(MAYA_FOUND)
|
ENDIF(MAYA_FOUND)
|
||||||
|
|
||||||
# FreeImage
|
# FreeImage
|
||||||
INCLUDE(${NV_CMAKE_DIR}/FindFreeImage.cmake)
|
#INCLUDE(${NV_CMAKE_DIR}/FindFreeImage.cmake)
|
||||||
IF(FREEIMAGE_FOUND)
|
IF(FREEIMAGE_FOUND)
|
||||||
SET(HAVE_FREEIMAGE ${FREEIMAGE_FOUND} CACHE BOOL "Set to TRUE if FreeImage is found, FALSE otherwise")
|
SET(HAVE_FREEIMAGE ${FREEIMAGE_FOUND} CACHE BOOL "Set to TRUE if FreeImage is found, FALSE otherwise")
|
||||||
MESSAGE(STATUS "Looking for FreeImage - found")
|
MESSAGE(STATUS "Looking for FreeImage - found")
|
||||||
|
@ -22,6 +22,7 @@ SET(IMAGE_SRCS
|
|||||||
NormalMap.cpp
|
NormalMap.cpp
|
||||||
PsdFile.h
|
PsdFile.h
|
||||||
TgaFile.h
|
TgaFile.h
|
||||||
|
PixelFormat.h
|
||||||
ColorSpace.h
|
ColorSpace.h
|
||||||
ColorSpace.cpp)
|
ColorSpace.cpp)
|
||||||
|
|
||||||
|
@ -30,52 +30,87 @@
|
|||||||
|
|
||||||
namespace nv
|
namespace nv
|
||||||
{
|
{
|
||||||
namespace PixelFormat
|
namespace PixelFormat
|
||||||
|
{
|
||||||
|
|
||||||
|
// Convert component @a c having @a inbits to the returned value having @a outbits.
|
||||||
|
inline uint convert(uint c, uint inbits, uint outbits)
|
||||||
{
|
{
|
||||||
|
if (inbits == 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if (inbits >= outbits)
|
||||||
|
{
|
||||||
|
// truncate
|
||||||
|
return c >> (inbits - outbits);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// bitexpand
|
||||||
|
return (c << (outbits - inbits)) | convert(c, inbits, outbits - inbits);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Convert component @a c having @a inbits to the returned value having @a outbits.
|
// Get pixel component shift and size given its mask.
|
||||||
inline uint convert(uint c, uint inbits, uint outbits)
|
inline void maskShiftAndSize(uint mask, uint * shift, uint * size)
|
||||||
{
|
{
|
||||||
if (inbits == 0)
|
if (!mask)
|
||||||
{
|
{
|
||||||
return 0;
|
*shift = 0;
|
||||||
}
|
*size = 0;
|
||||||
else if (inbits >= outbits)
|
return;
|
||||||
{
|
}
|
||||||
// truncate
|
|
||||||
return c >> (inbits - outbits);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// bitexpand
|
|
||||||
return (c << (outbits - inbits)) | convert(c, inbits, outbits - inbits);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get pixel component shift and size given its mask.
|
*shift = 0;
|
||||||
inline void maskShiftAndSize(uint mask, uint * shift, uint * size)
|
while((mask & 1) == 0) {
|
||||||
{
|
++(*shift);
|
||||||
if (!mask)
|
mask >>= 1;
|
||||||
{
|
}
|
||||||
*shift = 0;
|
|
||||||
*size = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
*shift = 0;
|
*size = 0;
|
||||||
while((mask & 1) == 0) {
|
while((mask & 1) == 1) {
|
||||||
++(*shift);
|
++(*size);
|
||||||
mask >>= 1;
|
mask >>= 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
*size = 0;
|
|
||||||
while((mask & 1) == 1) {
|
|
||||||
++(*size);
|
|
||||||
mask >>= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // PixelFormat namespace
|
inline float quantizeCeil(float f, int inbits, int outbits)
|
||||||
|
{
|
||||||
|
nvDebugCheck(f >= 0.0f && f <= 1.0f);
|
||||||
|
//uint i = f * (float(1 << inbits) - 1);
|
||||||
|
//i = convert(i, inbits, outbits);
|
||||||
|
//float result = float(i) / (float(1 << outbits) - 1);
|
||||||
|
//nvCheck(result >= f);
|
||||||
|
float result;
|
||||||
|
int offset = 0;
|
||||||
|
do {
|
||||||
|
uint i = offset + f * (float(1 << inbits) - 1);
|
||||||
|
i = convert(i, inbits, outbits);
|
||||||
|
result = float(i) / (float(1 << outbits) - 1);
|
||||||
|
offset++;
|
||||||
|
} while (result < f);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
inline float quantizeRound(float f, int bits)
|
||||||
|
{
|
||||||
|
nvDebugCheck(f >= 0.0f && f <= 1.0f);
|
||||||
|
float scale = float(1 << bits);
|
||||||
|
return fround(f * scale) / scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float quantizeFloor(float f, int bits)
|
||||||
|
{
|
||||||
|
nvDebugCheck(f >= 0.0f && f <= 1.0f);
|
||||||
|
float scale = float(1 << bits);
|
||||||
|
return floor(f * scale) / scale;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
} // PixelFormat namespace
|
||||||
|
|
||||||
} // nv namespace
|
} // nv namespace
|
||||||
|
|
||||||
|
@ -200,27 +200,6 @@ namespace nv
|
|||||||
return float(iround(f));
|
return float(iround(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline float quantizeCeil(float f, int bits)
|
|
||||||
{
|
|
||||||
nvDebugCheck(f >= 0.0f && f <= 1.0f);
|
|
||||||
float scale = float(1 << bits);
|
|
||||||
return ceilf(f * scale) / scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline float quantizeRound(float f, int bits)
|
|
||||||
{
|
|
||||||
nvDebugCheck(f >= 0.0f && f <= 1.0f);
|
|
||||||
float scale = float(1 << bits);
|
|
||||||
return fround(f * scale) / scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline float quantizeFloor(float f, int bits)
|
|
||||||
{
|
|
||||||
nvDebugCheck(f >= 0.0f && f <= 1.0f);
|
|
||||||
float scale = float(1 << bits);
|
|
||||||
return floor(f * scale) / scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // nv
|
} // nv
|
||||||
|
|
||||||
#endif // NV_MATH_H
|
#endif // NV_MATH_H
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include "nvimage/NormalMap.h"
|
#include "nvimage/NormalMap.h"
|
||||||
#include "nvimage/BlockDXT.h"
|
#include "nvimage/BlockDXT.h"
|
||||||
#include "nvimage/ColorBlock.h"
|
#include "nvimage/ColorBlock.h"
|
||||||
|
#include "nvimage/PixelFormat.h"
|
||||||
|
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
|
|
||||||
@ -1154,7 +1155,7 @@ void TexImage::blockScaleCoCg(int bits/*= 5*/, float threshold/*= 0.0*/)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float scale = quantizeCeil(m, bits);
|
float scale = PixelFormat::quantizeCeil(m, bits, 8);
|
||||||
nvDebugCheck(scale >= m);
|
nvDebugCheck(scale >= m);
|
||||||
|
|
||||||
// Store block scale in blue channel and scale CoCg.
|
// Store block scale in blue channel and scale CoCg.
|
||||||
@ -1212,6 +1213,41 @@ void TexImage::fromYCoCg()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TexImage::toLUVW(float range/*= 1.0f*/)
|
||||||
|
{
|
||||||
|
if (m->image == NULL) return;
|
||||||
|
|
||||||
|
detach();
|
||||||
|
|
||||||
|
float irange = 1.0f / range;
|
||||||
|
|
||||||
|
FloatImage * img = m->image;
|
||||||
|
float * r = img->channel(0);
|
||||||
|
float * g = img->channel(1);
|
||||||
|
float * b = img->channel(2);
|
||||||
|
float * a = img->channel(3);
|
||||||
|
|
||||||
|
const uint count = img->width() * img->height();
|
||||||
|
for (uint i = 0; i < count; i++) {
|
||||||
|
float R = nv::clamp(r[i] * irange, 0.0f, 1.0f);
|
||||||
|
float G = nv::clamp(g[i] * irange, 0.0f, 1.0f);
|
||||||
|
float B = nv::clamp(b[i] * irange, 0.0f, 1.0f);
|
||||||
|
|
||||||
|
float L = max(sqrtf(R*R + G*G + B*B), 1e-6f)); // Avoid division by zero.
|
||||||
|
//m = quantizeCeil(m, 8);
|
||||||
|
|
||||||
|
r[i] = R / L;
|
||||||
|
g[i] = G / L;
|
||||||
|
b[i] = B / L;
|
||||||
|
a[i] = L;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TexImage::fromLUVW(float range/*= 1.0f*/)
|
||||||
|
{
|
||||||
|
// Decompression is the same as in RGBM.
|
||||||
|
fromRGBM(range);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void TexImage::binarize(int channel, float threshold, bool dither)
|
void TexImage::binarize(int channel, float threshold, bool dither)
|
||||||
|
@ -432,6 +432,8 @@ namespace nvtt
|
|||||||
NVTT_API void toYCoCg();
|
NVTT_API void toYCoCg();
|
||||||
NVTT_API void blockScaleCoCg(int bits = 5, float threshold = 0.0f);
|
NVTT_API void blockScaleCoCg(int bits = 5, float threshold = 0.0f);
|
||||||
NVTT_API void fromYCoCg();
|
NVTT_API void fromYCoCg();
|
||||||
|
NVTT_API void toLUVW(float range = 1.0f);
|
||||||
|
NVTT_API void fromLUVW(float range = 1.0f);
|
||||||
|
|
||||||
// Color quantization.
|
// Color quantization.
|
||||||
NVTT_API void binarize(int channel, float threshold, bool dither);
|
NVTT_API void binarize(int channel, float threshold, bool dither);
|
||||||
@ -449,9 +451,9 @@ namespace nvtt
|
|||||||
NVTT_API bool copyChannel(const TexImage & srcImage, int srcChannel, int dstChannel);
|
NVTT_API bool copyChannel(const TexImage & srcImage, int srcChannel, int dstChannel);
|
||||||
|
|
||||||
// Error compare.
|
// Error compare.
|
||||||
friend NVTT_API float rmsError(const TexImage & reference, const TexImage & img);
|
friend float rmsError(const TexImage & reference, const TexImage & img);
|
||||||
friend NVTT_API float rmsAlphaError(const TexImage & reference, const TexImage & img);
|
friend float rmsAlphaError(const TexImage & reference, const TexImage & img);
|
||||||
friend NVTT_API TexImage diff(const TexImage & reference, const TexImage & img);
|
friend TexImage diff(const TexImage & reference, const TexImage & img);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void detach();
|
void detach();
|
||||||
@ -467,6 +469,10 @@ namespace nvtt
|
|||||||
// Return NVTT version.
|
// Return NVTT version.
|
||||||
NVTT_API unsigned int version();
|
NVTT_API unsigned int version();
|
||||||
|
|
||||||
|
NVTT_API float rmsError(const TexImage & reference, const TexImage & img);
|
||||||
|
NVTT_API float rmsAlphaError(const TexImage & reference, const TexImage & img);
|
||||||
|
NVTT_API TexImage diff(const TexImage & reference, const TexImage & img);
|
||||||
|
|
||||||
} // nvtt namespace
|
} // nvtt namespace
|
||||||
|
|
||||||
#endif // NVTT_H
|
#endif // NVTT_H
|
||||||
|
@ -98,7 +98,7 @@ int main(int argc, char *argv[])
|
|||||||
colorMap.flipVertically();
|
colorMap.flipVertically();
|
||||||
colorMap.setAlphaMode(nvtt::AlphaMode_Transparency);
|
colorMap.setAlphaMode(nvtt::AlphaMode_Transparency);
|
||||||
|
|
||||||
context.compress(colorMap, colorCompressionOptions, colorOutputOptions);
|
context.compress(colorMap, 0, 0, colorCompressionOptions, colorOutputOptions);
|
||||||
|
|
||||||
if (inputFileNameNormal != NULL) {
|
if (inputFileNameNormal != NULL) {
|
||||||
context.outputHeader(normalMap, normalMap.countMipmaps(), normalCompressionOptions, normalOutputOptions);
|
context.outputHeader(normalMap, normalMap.countMipmaps(), normalCompressionOptions, normalOutputOptions);
|
||||||
@ -108,7 +108,7 @@ int main(int argc, char *argv[])
|
|||||||
normalMap.normalizeNormalMap();
|
normalMap.normalizeNormalMap();
|
||||||
normalMap.copyChannel(colorMap, 3); // Copy alpha channel from color to normal map.
|
normalMap.copyChannel(colorMap, 3); // Copy alpha channel from color to normal map.
|
||||||
|
|
||||||
context.compress(normalMap, normalCompressionOptions, normalOutputOptions);
|
context.compress(normalMap, 0, 0, normalCompressionOptions, normalOutputOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
const float gamma = 2.2f;
|
const float gamma = 2.2f;
|
||||||
@ -118,6 +118,7 @@ int main(int argc, char *argv[])
|
|||||||
const float coverage = colorMap.alphaTestCoverage(alphaRef);
|
const float coverage = colorMap.alphaTestCoverage(alphaRef);
|
||||||
|
|
||||||
// Build and output mipmaps.
|
// Build and output mipmaps.
|
||||||
|
int m = 1;
|
||||||
while (colorMap.buildNextMipmap(nvtt::MipmapFilter_Kaiser))
|
while (colorMap.buildNextMipmap(nvtt::MipmapFilter_Kaiser))
|
||||||
{
|
{
|
||||||
colorMap.scaleAlphaToCoverage(coverage, alphaRef);
|
colorMap.scaleAlphaToCoverage(coverage, alphaRef);
|
||||||
@ -125,15 +126,17 @@ int main(int argc, char *argv[])
|
|||||||
nvtt::TexImage tmpColorMap = colorMap;
|
nvtt::TexImage tmpColorMap = colorMap;
|
||||||
tmpColorMap.toGamma(gamma);
|
tmpColorMap.toGamma(gamma);
|
||||||
|
|
||||||
context.compress(tmpColorMap, colorCompressionOptions, colorOutputOptions);
|
context.compress(tmpColorMap, 0, m, colorCompressionOptions, colorOutputOptions);
|
||||||
|
|
||||||
if (inputFileNameNormal != NULL) {
|
if (inputFileNameNormal != NULL) {
|
||||||
normalMap.buildNextMipmap(nvtt::MipmapFilter_Kaiser);
|
normalMap.buildNextMipmap(nvtt::MipmapFilter_Kaiser);
|
||||||
normalMap.normalizeNormalMap();
|
normalMap.normalizeNormalMap();
|
||||||
normalMap.copyChannel(tmpColorMap, 3);
|
normalMap.copyChannel(tmpColorMap, 3);
|
||||||
|
|
||||||
context.compress(normalMap, normalCompressionOptions, normalOutputOptions);
|
context.compress(normalMap, 0, m, normalCompressionOptions, normalOutputOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
@ -42,6 +42,8 @@
|
|||||||
|
|
||||||
using namespace nv;
|
using namespace nv;
|
||||||
|
|
||||||
|
#define ARRAY_SIZE(a) sizeof(a)/sizeof(a[0])
|
||||||
|
|
||||||
// Kodak image set
|
// Kodak image set
|
||||||
static const char * s_kodakImageSet[] = {
|
static const char * s_kodakImageSet[] = {
|
||||||
"kodim01.png",
|
"kodim01.png",
|
||||||
@ -94,17 +96,17 @@ static const char * s_epicImageSet[] = {
|
|||||||
|
|
||||||
// Farbrausch
|
// Farbrausch
|
||||||
static const char * s_farbrauschImageSet[] = {
|
static const char * s_farbrauschImageSet[] = {
|
||||||
"t.2d.pn02.bmp",
|
"t.2d.pn02.png",
|
||||||
"t.aircondition.01.bmp",
|
"t.aircondition.01.png",
|
||||||
"t.bricks.02.bmp",
|
"t.bricks.02.png",
|
||||||
"t.bricks.05.bmp",
|
"t.bricks.05.png",
|
||||||
"t.concrete.cracked.01.bmp",
|
"t.concrete.cracked.01.png",
|
||||||
"t.envi.colored02.bmp",
|
"t.envi.colored02.png",
|
||||||
"t.envi.colored03.bmp",
|
"t.envi.colored03.png",
|
||||||
"t.font.01.bmp",
|
"t.font.01.png",
|
||||||
"t.sewers.01.bmp",
|
"t.sewers.01.png",
|
||||||
"t.train.03.bmp",
|
"t.train.03.png",
|
||||||
"t.yello.01.bmp",
|
"t.yello.01.png",
|
||||||
};
|
};
|
||||||
|
|
||||||
// Lugaru
|
// Lugaru
|
||||||
@ -128,39 +130,75 @@ static const char * s_quake3ImageSet[] = {
|
|||||||
"q3-wires02.tga",
|
"q3-wires02.tga",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const char * s_witnessImageSet[] = {
|
||||||
|
"applebark.tga",
|
||||||
|
"grass-01.tga",
|
||||||
|
"brownRock.tga",
|
||||||
|
"rock-01.tga",
|
||||||
|
"rock-02.tga",
|
||||||
|
"Lao-picture.tga",
|
||||||
|
"laser-base.tga",
|
||||||
|
"skydome.tga",
|
||||||
|
"speaker.tga",
|
||||||
|
"specRuin-base.tga",
|
||||||
|
"vault.tga",
|
||||||
|
"specRuin-puzzle.tga"
|
||||||
|
};
|
||||||
|
|
||||||
enum Mode {
|
enum Mode {
|
||||||
Mode_BC1,
|
Mode_BC1,
|
||||||
|
Mode_BC1_Alpha,
|
||||||
|
Mode_BC2_Alpha,
|
||||||
Mode_BC3_Alpha,
|
Mode_BC3_Alpha,
|
||||||
Mode_BC3_YCoCg,
|
Mode_BC3_YCoCg,
|
||||||
Mode_BC3_RGBM,
|
Mode_BC3_RGBM,
|
||||||
|
Mode_BC1_Normal,
|
||||||
Mode_BC3_Normal,
|
Mode_BC3_Normal,
|
||||||
Mode_BC5_Normal,
|
Mode_BC5_Normal,
|
||||||
};
|
};
|
||||||
|
static const char * s_modeNames[] = {
|
||||||
|
"BC1",
|
||||||
|
"BC1-Alpha",
|
||||||
|
"BC2-Alpha",
|
||||||
|
"BC3-Alpha",
|
||||||
|
"BC3-YCoCg",
|
||||||
|
"BC3-RGBM",
|
||||||
|
"BC3-LUVW",
|
||||||
|
"BC1-Normal",
|
||||||
|
"BC3-Normal",
|
||||||
|
"BC5-Normal",
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Test {
|
||||||
|
const char * name;
|
||||||
|
int count;
|
||||||
|
Mode modes[4];
|
||||||
|
};
|
||||||
|
static Test s_imageTests[] = {
|
||||||
|
{"DXT Color", 3, {Mode_BC1, Mode_BC3_YCoCg, Mode_BC3_RGBM}},
|
||||||
|
{"DXT Alpha", 3, {Mode_BC1_Alpha, Mode_BC2_Alpha, Mode_BC3_Alpha}},
|
||||||
|
{"DXT Normal", 3, {Mode_BC1_Normal, Mode_BC3_Normal, Mode_BC5_Normal}},
|
||||||
|
};
|
||||||
|
const int s_testCount = ARRAY_SIZE(s_imageTests);
|
||||||
|
|
||||||
struct ImageSet
|
struct ImageSet
|
||||||
{
|
{
|
||||||
const char * name;
|
const char * name;
|
||||||
const char ** fileNames;
|
const char ** fileNames;
|
||||||
int fileCount;
|
int fileCount;
|
||||||
Mode mode;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ARRAY_SIZE(a) sizeof(a)/sizeof(a[0])
|
|
||||||
|
|
||||||
static ImageSet s_imageSets[] = {
|
static ImageSet s_imageSets[] = {
|
||||||
{"Kodak - BC1", s_kodakImageSet, ARRAY_SIZE(s_kodakImageSet), Mode_BC1},
|
{"Kodak", s_kodakImageSet, ARRAY_SIZE(s_kodakImageSet)}, // 0
|
||||||
{"Kodak - BC3-YCoCg", s_kodakImageSet, ARRAY_SIZE(s_kodakImageSet), Mode_BC3_YCoCg},
|
{"Waterloo", s_waterlooImageSet, ARRAY_SIZE(s_waterlooImageSet)}, // 1
|
||||||
{"Kodak - BC3-RGBM", s_kodakImageSet, ARRAY_SIZE(s_kodakImageSet), Mode_BC3_RGBM},
|
{"Epic", s_epicImageSet, ARRAY_SIZE(s_epicImageSet)}, // 2
|
||||||
{"Waterloo - BC1", s_waterlooImageSet, ARRAY_SIZE(s_waterlooImageSet), Mode_BC1},
|
{"Farbraush", s_farbrauschImageSet, ARRAY_SIZE(s_farbrauschImageSet)}, // 3
|
||||||
{"Waterloo - BC3-YCoCg", s_waterlooImageSet, ARRAY_SIZE(s_waterlooImageSet), Mode_BC3_YCoCg},
|
{"Lugaru", s_lugaruImageSet, ARRAY_SIZE(s_lugaruImageSet)}, // 4
|
||||||
{"Epic - BC1", s_epicImageSet, ARRAY_SIZE(s_epicImageSet), Mode_BC1},
|
{"Quake3", s_quake3ImageSet, ARRAY_SIZE(s_quake3ImageSet)}, // 5
|
||||||
{"Epic - BC1-YCoCg", s_epicImageSet, ARRAY_SIZE(s_epicImageSet), Mode_BC3_YCoCg},
|
{"Witness", s_witnessImageSet, ARRAY_SIZE(s_witnessImageSet)} // 6
|
||||||
{"Farbraush - BC1", s_farbrauschImageSet, ARRAY_SIZE(s_farbrauschImageSet), Mode_BC1},
|
|
||||||
{"Farbraush - BC1-YCoCg", s_farbrauschImageSet, ARRAY_SIZE(s_farbrauschImageSet), Mode_BC3_YCoCg},
|
|
||||||
{"Lugaru - BC3", s_lugaruImageSet, ARRAY_SIZE(s_lugaruImageSet), Mode_BC3_Alpha},
|
|
||||||
{"Quake3 - BC3", s_quake3ImageSet, ARRAY_SIZE(s_quake3ImageSet), Mode_BC3_Alpha},
|
|
||||||
};
|
};
|
||||||
const int s_imageSetCount = sizeof(s_imageSets)/sizeof(s_imageSets[0]);
|
const int s_imageSetCount = sizeof(s_imageSets)/sizeof(s_imageSets[0]);
|
||||||
|
|
||||||
|
|
||||||
struct MyOutputHandler : public nvtt::OutputHandler
|
struct MyOutputHandler : public nvtt::OutputHandler
|
||||||
{
|
{
|
||||||
MyOutputHandler() : m_data(NULL), m_ptr(NULL) {}
|
MyOutputHandler() : m_data(NULL), m_ptr(NULL) {}
|
||||||
@ -220,6 +258,7 @@ int main(int argc, char *argv[])
|
|||||||
printf("NVIDIA Texture Tools %u.%u.%u - Copyright NVIDIA Corporation 2007\n\n", major, minor, rev);
|
printf("NVIDIA Texture Tools %u.%u.%u - Copyright NVIDIA Corporation 2007\n\n", major, minor, rev);
|
||||||
|
|
||||||
int setIndex = 0;
|
int setIndex = 0;
|
||||||
|
int testIndex = 0;
|
||||||
bool fast = false;
|
bool fast = false;
|
||||||
bool nocuda = false;
|
bool nocuda = false;
|
||||||
bool showHelp = false;
|
bool showHelp = false;
|
||||||
@ -238,6 +277,13 @@ int main(int argc, char *argv[])
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (strcmp("-test", argv[i]) == 0)
|
||||||
|
{
|
||||||
|
if (i+1 < argc && argv[i+1][0] != '-') {
|
||||||
|
testIndex = atoi(argv[i+1]);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (strcmp("-dec", argv[i]) == 0)
|
else if (strcmp("-dec", argv[i]) == 0)
|
||||||
{
|
{
|
||||||
if (i+1 < argc && argv[i+1][0] != '-') {
|
if (i+1 < argc && argv[i+1][0] != '-') {
|
||||||
@ -280,6 +326,16 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Validate inputs.
|
||||||
|
if (testIndex >= s_testCount) {
|
||||||
|
printf("Invalid test %d\n", testIndex);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (setIndex >= s_imageSetCount) {
|
||||||
|
printf("Invalid image set %d\n", setIndex);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (showHelp)
|
if (showHelp)
|
||||||
{
|
{
|
||||||
printf("usage: nvtestsuite [options]\n\n");
|
printf("usage: nvtestsuite [options]\n\n");
|
||||||
@ -287,13 +343,17 @@ int main(int argc, char *argv[])
|
|||||||
printf("Input options:\n");
|
printf("Input options:\n");
|
||||||
printf(" -path <path> \tInput image path.\n");
|
printf(" -path <path> \tInput image path.\n");
|
||||||
printf(" -regress <path>\tRegression directory.\n");
|
printf(" -regress <path>\tRegression directory.\n");
|
||||||
printf(" -set [0:2] \tImage set.\n");
|
printf(" -set [0:5] \tImage set.\n");
|
||||||
printf(" 0: \tKodak.\n");
|
printf(" 0: \tKodak.\n");
|
||||||
printf(" 1: \tWaterloo.\n");
|
printf(" 1: \tWaterloo.\n");
|
||||||
printf(" 2: \tEpic.\n");
|
printf(" 2: \tEpic.\n");
|
||||||
printf(" 3: \tFarbrausch.\n");
|
printf(" 3: \tFarbrausch.\n");
|
||||||
printf(" 4: \tLugaru.\n");
|
printf(" 4: \tLugaru.\n");
|
||||||
printf(" 5: \tQuake 3.\n");
|
printf(" 5: \tQuake 3.\n");
|
||||||
|
printf(" -test [0:2] \tCompression tests to run.");
|
||||||
|
printf(" 0: \tDXT Color.\n");
|
||||||
|
printf(" 1: \tDXT Alpha.\n");
|
||||||
|
printf(" 2: \tDXT Normal.\n");
|
||||||
printf(" -dec x \tDecompressor.\n");
|
printf(" -dec x \tDecompressor.\n");
|
||||||
printf(" 0: \tReference.\n");
|
printf(" 0: \tReference.\n");
|
||||||
printf(" 1: \tNVIDIA.\n");
|
printf(" 1: \tNVIDIA.\n");
|
||||||
@ -325,20 +385,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
|
|
||||||
const ImageSet & set = s_imageSets[setIndex];
|
const ImageSet & set = s_imageSets[setIndex];
|
||||||
|
const Test & test = s_imageTests[testIndex];
|
||||||
if (set.mode == Mode_BC1) {
|
|
||||||
compressionOptions.setFormat(nvtt::Format_BC1);
|
|
||||||
}
|
|
||||||
else if (set.mode == Mode_BC3_Alpha || set.mode == Mode_BC3_YCoCg || set.mode == Mode_BC3_RGBM) {
|
|
||||||
compressionOptions.setFormat(nvtt::Format_BC3);
|
|
||||||
}
|
|
||||||
else if (set.mode == Mode_BC3_Normal) {
|
|
||||||
compressionOptions.setFormat(nvtt::Format_BC3n);
|
|
||||||
}
|
|
||||||
else if (set.mode == Mode_BC5_Normal) {
|
|
||||||
compressionOptions.setFormat(nvtt::Format_BC5);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
nvtt::OutputOptions outputOptions;
|
nvtt::OutputOptions outputOptions;
|
||||||
@ -353,147 +400,230 @@ int main(int argc, char *argv[])
|
|||||||
FileSystem::changeDirectory(basePath);
|
FileSystem::changeDirectory(basePath);
|
||||||
FileSystem::createDirectory(outPath);
|
FileSystem::createDirectory(outPath);
|
||||||
|
|
||||||
Path csvFileName;
|
//Path csvFileName;
|
||||||
csvFileName.format("%s/result-%d.csv", outPath, setIndex);
|
//csvFileName.format("%s/result-%d.csv", outPath, setIndex);
|
||||||
StdOutputStream csvStream(csvFileName.str());
|
//StdOutputStream csvStream(csvFileName.str());
|
||||||
TextWriter csvWriter(&csvStream);
|
//TextWriter csvWriter(&csvStream);
|
||||||
|
|
||||||
|
Path graphFileName;
|
||||||
|
graphFileName.format("%s/result-%d.txt", outPath, setIndex);
|
||||||
|
StdOutputStream graphStream(graphFileName.str());
|
||||||
|
TextWriter graphWriter(&graphStream);
|
||||||
|
|
||||||
|
graphWriter << "http://chart.apis.google.com/chart?";
|
||||||
|
|
||||||
|
// Graph size.
|
||||||
|
graphWriter << "chs=480x240";
|
||||||
|
|
||||||
|
// Graph type: line
|
||||||
|
graphWriter << "&cht=lc";
|
||||||
|
|
||||||
|
// Margins.
|
||||||
|
graphWriter << "&chma=30,10,10|0,40";
|
||||||
|
|
||||||
|
// Grid lines.
|
||||||
|
graphWriter << "&chxt=x,y&chxtc=0,-1000|1,-1000";
|
||||||
|
|
||||||
|
// Labels.
|
||||||
|
graphWriter << "&chxr=0,1," << set.fileCount << ",1|1,0,0.05,0.01";
|
||||||
|
graphWriter << "&chdlp=b"; // Labels at the bottom.
|
||||||
|
|
||||||
|
// Line colors.
|
||||||
|
graphWriter << "&chco=";
|
||||||
|
for (int t = 0; t < test.count; t++)
|
||||||
|
{
|
||||||
|
const char * colors[] = {
|
||||||
|
"3D7930", "952826", "3D1FC1",
|
||||||
|
"3D7930", "952826", "3D1FC1", // pick other colors...
|
||||||
|
};
|
||||||
|
graphWriter << colors[t];
|
||||||
|
if (t != test.count-1) graphWriter << ",";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Line width.
|
||||||
|
graphWriter << "&chls=";
|
||||||
|
for (int t = 0; t < test.count; t++)
|
||||||
|
{
|
||||||
|
graphWriter << "2";
|
||||||
|
if (t != test.count-1) graphWriter << "|";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Data ranges.
|
||||||
|
graphWriter << "&chds=";
|
||||||
|
for (int t = 0; t < test.count; t++)
|
||||||
|
{
|
||||||
|
graphWriter << "0,0.05";
|
||||||
|
if (t != test.count-1) graphWriter << ",";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Leyends.
|
||||||
|
graphWriter << "&chdl=";
|
||||||
|
for (int t = 0; t < test.count; t++)
|
||||||
|
{
|
||||||
|
graphWriter << s_modeNames[test.modes[t]];
|
||||||
|
if (t != test.count-1) graphWriter << "|";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Title
|
||||||
|
graphWriter << "&chtt=" << set.name << " - " << test.name;
|
||||||
|
|
||||||
float totalTime = 0;
|
float totalTime = 0;
|
||||||
float totalRMSE = 0;
|
float totalRMSE = 0;
|
||||||
int failedTests = 0;
|
//int failedTests = 0;
|
||||||
float totalDiff = 0;
|
float totalDiff = 0;
|
||||||
|
|
||||||
const char ** fileNames = set.fileNames;
|
|
||||||
int fileCount = set.fileCount;
|
|
||||||
|
|
||||||
Timer timer;
|
Timer timer;
|
||||||
|
|
||||||
nvtt::TexImage img;
|
nvtt::TexImage img;
|
||||||
if (set.mode == Mode_BC3_Alpha) {
|
|
||||||
img.setAlphaMode(nvtt::AlphaMode_Transparency);
|
|
||||||
}
|
|
||||||
if (set.mode == Mode_BC3_Normal || set.mode == Mode_BC5_Normal) {
|
|
||||||
img.setNormalMap(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("Processing Set: %s\n", set.name);
|
printf("Running Test: %s\n", set.name);
|
||||||
|
|
||||||
for (int i = 0; i < fileCount; i++)
|
graphWriter << "&chd=t:";
|
||||||
|
|
||||||
|
for (int t = 0; t < test.count; t++)
|
||||||
{
|
{
|
||||||
if (!img.load(fileNames[i]))
|
Mode mode = test.modes[t];
|
||||||
|
if (mode == Mode_BC1) {
|
||||||
|
compressionOptions.setFormat(nvtt::Format_BC1);
|
||||||
|
}
|
||||||
|
else if (mode == Mode_BC3_Alpha || mode == Mode_BC3_YCoCg || mode == Mode_BC3_RGBM) {
|
||||||
|
compressionOptions.setFormat(nvtt::Format_BC3);
|
||||||
|
}
|
||||||
|
else if (mode == Mode_BC3_Normal) {
|
||||||
|
compressionOptions.setFormat(nvtt::Format_BC3n);
|
||||||
|
}
|
||||||
|
else if (mode == Mode_BC5_Normal) {
|
||||||
|
compressionOptions.setFormat(nvtt::Format_BC5);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode == Mode_BC3_Alpha) {
|
||||||
|
img.setAlphaMode(nvtt::AlphaMode_Transparency);
|
||||||
|
}
|
||||||
|
if (mode == Mode_BC3_Normal || mode == Mode_BC5_Normal) {
|
||||||
|
img.setNormalMap(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
printf("Processing Set: %s\n", set.name);
|
||||||
|
for (int i = 0; i < set.fileCount; i++)
|
||||||
{
|
{
|
||||||
printf("Input image '%s' not found.\n", fileNames[i]);
|
if (!img.load(set.fileNames[i]))
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (img.isNormalMap()) {
|
|
||||||
img.normalizeNormalMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (set.mode == Mode_BC3_YCoCg) {
|
|
||||||
img.toYCoCg();
|
|
||||||
img.blockScaleCoCg();
|
|
||||||
img.scaleBias(0, 0.5, 0.5);
|
|
||||||
img.scaleBias(1, 0.5, 0.5);
|
|
||||||
}
|
|
||||||
else if (set.mode == Mode_BC3_RGBM) {
|
|
||||||
img.toRGBM();
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("Compressing: \t'%s'\n", fileNames[i]);
|
|
||||||
|
|
||||||
timer.start();
|
|
||||||
|
|
||||||
context.compress(img, 0, 0, compressionOptions, outputOptions);
|
|
||||||
|
|
||||||
timer.stop();
|
|
||||||
printf(" Time: \t%.3f sec\n", timer.elapsed());
|
|
||||||
totalTime += timer.elapsed();
|
|
||||||
|
|
||||||
nvtt::TexImage img_out = outputHandler.decompress(set.mode, decoder);
|
|
||||||
if (set.mode == Mode_BC3_Alpha) {
|
|
||||||
img_out.setAlphaMode(nvtt::AlphaMode_Transparency);
|
|
||||||
}
|
|
||||||
if (set.mode == Mode_BC3_Normal || set.mode == Mode_BC5_Normal) {
|
|
||||||
img_out.setNormalMap(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (set.mode == Mode_BC3_YCoCg) {
|
|
||||||
img_out.scaleBias(0, 1.0, -0.5);
|
|
||||||
img_out.scaleBias(1, 1.0, -0.5);
|
|
||||||
img_out.fromYCoCg();
|
|
||||||
|
|
||||||
img.scaleBias(0, 1.0, -0.5);
|
|
||||||
img.scaleBias(1, 1.0, -0.5);
|
|
||||||
img.fromYCoCg();
|
|
||||||
}
|
|
||||||
else if (set.mode == Mode_BC3_RGBM) {
|
|
||||||
img_out.fromRGBM();
|
|
||||||
img.fromRGBM();
|
|
||||||
}
|
|
||||||
|
|
||||||
Path outputFileName;
|
|
||||||
outputFileName.format("%s/%s", outPath, fileNames[i]);
|
|
||||||
outputFileName.stripExtension();
|
|
||||||
outputFileName.append(".png");
|
|
||||||
if (!img_out.save(outputFileName.str()))
|
|
||||||
{
|
|
||||||
printf("Error saving file '%s'.\n", outputFileName.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
float rmse = nvtt::rmsError(img, img_out);
|
|
||||||
totalRMSE += rmse;
|
|
||||||
|
|
||||||
printf(" RMSE: \t%.4f\n", rmse);
|
|
||||||
|
|
||||||
// Output csv file
|
|
||||||
csvWriter << "\"" << fileNames[i] << "\"," << rmse << "\n";
|
|
||||||
|
|
||||||
if (regressPath != NULL)
|
|
||||||
{
|
|
||||||
Path regressFileName;
|
|
||||||
regressFileName.format("%s/%s", regressPath, fileNames[i]);
|
|
||||||
regressFileName.stripExtension();
|
|
||||||
regressFileName.append(".png");
|
|
||||||
|
|
||||||
nvtt::TexImage img_reg;
|
|
||||||
if (!img_reg.load(regressFileName.str()))
|
|
||||||
{
|
{
|
||||||
printf("Regression image '%s' not found.\n", regressFileName.str());
|
printf("Input image '%s' not found.\n", set.fileNames[i]);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
float rmse_reg = rmsError(img, img_reg);
|
if (img.isNormalMap()) {
|
||||||
|
img.normalizeNormalMap();
|
||||||
float diff = rmse_reg - rmse;
|
|
||||||
totalDiff += diff;
|
|
||||||
|
|
||||||
const char * text = "PASSED";
|
|
||||||
if (equal(diff, 0)) text = "PASSED";
|
|
||||||
else if (diff < 0) {
|
|
||||||
text = "FAILED";
|
|
||||||
failedTests++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
printf(" Diff: \t%.4f (%s)\n", diff, text);
|
nvtt::TexImage tmp = img;
|
||||||
|
if (mode == Mode_BC3_YCoCg) {
|
||||||
|
tmp.toYCoCg();
|
||||||
|
tmp.blockScaleCoCg();
|
||||||
|
tmp.scaleBias(0, 0.5, 0.5);
|
||||||
|
tmp.scaleBias(1, 0.5, 0.5);
|
||||||
|
}
|
||||||
|
else if (mode == Mode_BC3_RGBM) {
|
||||||
|
tmp.toRGBM();
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Compressing: \t'%s'\n", set.fileNames[i]);
|
||||||
|
|
||||||
|
timer.start();
|
||||||
|
|
||||||
|
context.compress(tmp, 0, 0, compressionOptions, outputOptions);
|
||||||
|
|
||||||
|
timer.stop();
|
||||||
|
printf(" Time: \t%.3f sec\n", timer.elapsed());
|
||||||
|
totalTime += timer.elapsed();
|
||||||
|
|
||||||
|
nvtt::TexImage img_out = outputHandler.decompress(mode, decoder);
|
||||||
|
if (mode == Mode_BC3_Alpha) {
|
||||||
|
img_out.setAlphaMode(nvtt::AlphaMode_Transparency);
|
||||||
|
}
|
||||||
|
if (mode == Mode_BC3_Normal || mode == Mode_BC5_Normal) {
|
||||||
|
img_out.setNormalMap(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode == Mode_BC3_YCoCg) {
|
||||||
|
img_out.scaleBias(0, 1.0, -0.5);
|
||||||
|
img_out.scaleBias(1, 1.0, -0.5);
|
||||||
|
img_out.fromYCoCg();
|
||||||
|
}
|
||||||
|
else if (mode == Mode_BC3_RGBM) {
|
||||||
|
img_out.fromRGBM();
|
||||||
|
}
|
||||||
|
|
||||||
|
Path outputFileName;
|
||||||
|
outputFileName.format("%s/%s", outPath, set.fileNames[i]);
|
||||||
|
outputFileName.stripExtension();
|
||||||
|
outputFileName.append(".png");
|
||||||
|
if (!img_out.save(outputFileName.str()))
|
||||||
|
{
|
||||||
|
printf("Error saving file '%s'.\n", outputFileName.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
float rmse = nvtt::rmsError(img, img_out);
|
||||||
|
totalRMSE += rmse;
|
||||||
|
|
||||||
|
printf(" RMSE: \t%.4f\n", rmse);
|
||||||
|
|
||||||
|
graphWriter << rmse;
|
||||||
|
if (i != set.fileCount-1) graphWriter << ",";
|
||||||
|
|
||||||
|
// Output csv file
|
||||||
|
//csvWriter << "\"" << fileNames[i] << "\"," << rmse << "\n";
|
||||||
|
|
||||||
|
/*if (regressPath != NULL)
|
||||||
|
{
|
||||||
|
Path regressFileName;
|
||||||
|
regressFileName.format("%s/%s", regressPath, fileNames[i]);
|
||||||
|
regressFileName.stripExtension();
|
||||||
|
regressFileName.append(".png");
|
||||||
|
|
||||||
|
nvtt::TexImage img_reg;
|
||||||
|
if (!img_reg.load(regressFileName.str()))
|
||||||
|
{
|
||||||
|
printf("Regression image '%s' not found.\n", regressFileName.str());
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
float rmse_reg = rmsError(img, img_reg);
|
||||||
|
|
||||||
|
float diff = rmse_reg - rmse;
|
||||||
|
totalDiff += diff;
|
||||||
|
|
||||||
|
const char * text = "PASSED";
|
||||||
|
if (equal(diff, 0)) text = "PASSED";
|
||||||
|
else if (diff < 0) {
|
||||||
|
text = "FAILED";
|
||||||
|
failedTests++;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf(" Diff: \t%.4f (%s)\n", diff, text);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
fflush(stdout);
|
totalRMSE /= set.fileCount;
|
||||||
|
totalDiff /= set.fileCount;
|
||||||
|
|
||||||
|
printf("Total Results:\n");
|
||||||
|
printf(" Total Time: \t%.3f sec\n", totalTime);
|
||||||
|
printf(" Average RMSE:\t%.4f\n", totalRMSE);
|
||||||
|
|
||||||
|
if (t != s_testCount-1) graphWriter << "|";
|
||||||
}
|
}
|
||||||
|
|
||||||
totalRMSE /= fileCount;
|
/*if (regressPath != NULL)
|
||||||
totalDiff /= fileCount;
|
|
||||||
|
|
||||||
printf("Total Results:\n");
|
|
||||||
printf(" Total Time: \t%.3f sec\n", totalTime);
|
|
||||||
printf(" Average RMSE:\t%.4f\n", totalRMSE);
|
|
||||||
|
|
||||||
if (regressPath != NULL)
|
|
||||||
{
|
{
|
||||||
printf("Regression Results:\n");
|
printf("Regression Results:\n");
|
||||||
printf(" Diff: %.4f\n", totalDiff);
|
printf(" Diff: %.4f\n", totalDiff);
|
||||||
printf(" %d/%d tests failed.\n", failedTests, fileCount);
|
printf(" %d/%d tests failed.\n", failedTests, fileCount);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user