More work toward 2.1: Implement InputOptions using TexImage.

This commit is contained in:
castano 2010-11-03 18:31:16 +00:00
parent 8838b5220a
commit 1e2567e4a3
29 changed files with 2172 additions and 2878 deletions

View File

@ -35,7 +35,7 @@
# include <signal.h> # include <signal.h>
#endif #endif
#if NV_OS_LINUX || NV_OS_DARWIN #if NV_OS_LINUX || NV_OS_DARWIN || NV_OS_FREEBSD
# include <unistd.h> // getpid # include <unistd.h> // getpid
#endif #endif
@ -195,69 +195,69 @@ namespace
static NV_NOINLINE void printStackTrace(void * trace[], int size, int start=0) static NV_NOINLINE void printStackTrace(void * trace[], int size, int start=0)
{ {
HANDLE hProcess = GetCurrentProcess(); HANDLE hProcess = GetCurrentProcess();
nvDebug( "\nDumping stacktrace:\n" ); nvDebug( "\nDumping stacktrace:\n" );
// Resolve PC to function names // Resolve PC to function names
for (int i = start; i < size; i++) for (int i = start; i < size; i++)
{ {
// Check for end of stack walk // Check for end of stack walk
DWORD64 ip = (DWORD64)trace[i]; DWORD64 ip = (DWORD64)trace[i];
if (ip == NULL) if (ip == NULL)
break; break;
// Get function name // Get function name
#define MAX_STRING_LEN (512) #define MAX_STRING_LEN (512)
unsigned char byBuffer[sizeof(IMAGEHLP_SYMBOL64) + MAX_STRING_LEN] = { 0 }; unsigned char byBuffer[sizeof(IMAGEHLP_SYMBOL64) + MAX_STRING_LEN] = { 0 };
IMAGEHLP_SYMBOL64 * pSymbol = (IMAGEHLP_SYMBOL64*)byBuffer; IMAGEHLP_SYMBOL64 * pSymbol = (IMAGEHLP_SYMBOL64*)byBuffer;
pSymbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64); pSymbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
pSymbol->MaxNameLength = MAX_STRING_LEN; pSymbol->MaxNameLength = MAX_STRING_LEN;
DWORD64 dwDisplacement; DWORD64 dwDisplacement;
if (SymGetSymFromAddr64(hProcess, ip, &dwDisplacement, pSymbol))
{
pSymbol->Name[MAX_STRING_LEN-1] = 0;
/*
// Make the symbol readable for humans
UnDecorateSymbolName( pSym->Name, lpszNonUnicodeUnDSymbol, BUFFERSIZE,
UNDNAME_COMPLETE |
UNDNAME_NO_THISTYPE |
UNDNAME_NO_SPECIAL_SYMS |
UNDNAME_NO_MEMBER_TYPE |
UNDNAME_NO_MS_KEYWORDS |
UNDNAME_NO_ACCESS_SPECIFIERS );
*/
// pSymbol->Name
const char * pFunc = pSymbol->Name;
// Get file/line number
IMAGEHLP_LINE64 theLine = { 0 };
theLine.SizeOfStruct = sizeof(theLine);
DWORD dwDisplacement; if (SymGetSymFromAddr64(hProcess, ip, &dwDisplacement, pSymbol))
if (!SymGetLineFromAddr64(hProcess, ip, &dwDisplacement, &theLine)) {
{ pSymbol->Name[MAX_STRING_LEN-1] = 0;
nvDebug("unknown(%08X) : %s\n", (uint32)ip, pFunc);
} /*
else // Make the symbol readable for humans
{ UnDecorateSymbolName( pSym->Name, lpszNonUnicodeUnDSymbol, BUFFERSIZE,
/* UNDNAME_COMPLETE |
const char* pFile = strrchr(theLine.FileName, '\\'); UNDNAME_NO_THISTYPE |
if ( pFile == NULL ) pFile = theLine.FileName; UNDNAME_NO_SPECIAL_SYMS |
else pFile++; UNDNAME_NO_MEMBER_TYPE |
*/ UNDNAME_NO_MS_KEYWORDS |
const char * pFile = theLine.FileName; UNDNAME_NO_ACCESS_SPECIFIERS );
*/
int line = theLine.LineNumber;
// pSymbol->Name
nvDebug("%s(%d) : %s\n", pFile, line, pFunc); const char * pFunc = pSymbol->Name;
}
} // Get file/line number
IMAGEHLP_LINE64 theLine = { 0 };
theLine.SizeOfStruct = sizeof(theLine);
DWORD dwDisplacement;
if (!SymGetLineFromAddr64(hProcess, ip, &dwDisplacement, &theLine))
{
nvDebug("unknown(%08X) : %s\n", (uint32)ip, pFunc);
}
else
{
/*
const char* pFile = strrchr(theLine.FileName, '\\');
if ( pFile == NULL ) pFile = theLine.FileName;
else pFile++;
*/
const char * pFile = theLine.FileName;
int line = theLine.LineNumber;
nvDebug("%s(%d) : %s\n", pFile, line, pFunc);
}
} }
}
} }
@ -294,13 +294,13 @@ namespace
# if NV_CC_GNUC // defined(HAVE_CXXABI_H) # if NV_CC_GNUC // defined(HAVE_CXXABI_H)
char * begin = strchr(string_array[i], '('); char * begin = strchr(string_array[i], '(');
char * end = strchr(string_array[i], '+'); char * end = strchr(string_array[i], '+');
if( begin != 0 && begin < end ) { if (begin != 0 && begin < end) {
int stat; int stat;
*end = '\0'; *end = '\0';
*begin = '\0'; *begin = '\0';
char * module = string_array[i]; char * module = string_array[i];
char * name = abi::__cxa_demangle(begin+1, 0, 0, &stat); char * name = abi::__cxa_demangle(begin+1, 0, 0, &stat);
if( name == NULL || begin[1] != '_' || begin[2] != 'Z' ) { if (name == NULL || stat != 0) {
nvDebug( " In: [%s] '%s'\n", module, begin+1 ); nvDebug( " In: [%s] '%s'\n", module, begin+1 );
} }
else { else {

View File

@ -166,8 +166,8 @@ namespace nv
inline float square(float f) { return f * f; } inline float square(float f) { return f * f; }
inline int square(int i) { return i * i; } inline int square(int i) { return i * i; }
inline float cube(float f) { return f * f; } inline float cube(float f) { return f * f * f; }
inline int cube(int i) { return i * i; } inline int cube(int i) { return i * i * i; }
// @@ Float to int conversions to be optimized at some point. See: // @@ Float to int conversions to be optimized at some point. See:
// http://cbloomrants.blogspot.com/2009/01/01-17-09-float-to-int.html // http://cbloomrants.blogspot.com/2009/01/01-17-09-float-to-int.html
@ -189,10 +189,37 @@ namespace nv
return int(ceilf(f)); return int(ceilf(f));
} }
inline float frac(float f) inline float frac(float f)
{ {
return f - floor(f); return f - floor(f);
} }
inline float fround(float f)
{
// @@ Do something better.
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

View File

@ -32,7 +32,7 @@ namespace nv
struct CompressorInterface struct CompressorInterface
{ {
virtual ~CompressorInterface() {} virtual ~CompressorInterface() {}
virtual void compress(nvtt::InputFormat inputFormat, nvtt::AlphaMode alphaMode, uint w, uint h, const void * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions) = 0; virtual void compress(nvtt::AlphaMode alphaMode, uint w, uint h, const float * rgba, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions) = 0;
}; };
} // nv namespace } // nv namespace

View File

@ -28,112 +28,105 @@
namespace nv namespace nv
{ {
struct ColorBlock; struct ColorBlock;
// Fast CPU compressors. // Fast CPU compressors.
struct FastCompressorDXT1 : public FixedBlockCompressor struct FastCompressorDXT1 : public FixedBlockCompressor
{ {
virtual void compressBlock(ColorBlock & rgba, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output); virtual void compressBlock(ColorBlock & rgba, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output);
virtual uint blockSize() const { return 8; } virtual uint blockSize() const { return 8; }
}; };
struct FastCompressorDXT1a : public FixedBlockCompressor struct FastCompressorDXT1a : public FixedBlockCompressor
{ {
virtual void compressBlock(ColorBlock & rgba, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output); virtual void compressBlock(ColorBlock & rgba, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output);
virtual uint blockSize() const { return 8; } virtual uint blockSize() const { return 8; }
}; };
struct FastCompressorDXT3 : public FixedBlockCompressor struct FastCompressorDXT3 : public FixedBlockCompressor
{ {
virtual void compressBlock(ColorBlock & rgba, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output); virtual void compressBlock(ColorBlock & rgba, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output);
virtual uint blockSize() const { return 16; } virtual uint blockSize() const { return 16; }
}; };
struct FastCompressorDXT5 : public FixedBlockCompressor struct FastCompressorDXT5 : public FixedBlockCompressor
{ {
virtual void compressBlock(ColorBlock & rgba, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output); virtual void compressBlock(ColorBlock & rgba, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output);
virtual uint blockSize() const { return 16; } virtual uint blockSize() const { return 16; }
}; };
struct FastCompressorDXT5n : public FixedBlockCompressor struct FastCompressorDXT5n : public FixedBlockCompressor
{ {
virtual void compressBlock(ColorBlock & rgba, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output); virtual void compressBlock(ColorBlock & rgba, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output);
virtual uint blockSize() const { return 16; } virtual uint blockSize() const { return 16; }
}; };
// Normal CPU compressors. // Normal CPU compressors.
struct NormalCompressorDXT1 : public FixedBlockCompressor struct NormalCompressorDXT1 : public FixedBlockCompressor
{ {
virtual void compressBlock(ColorBlock & rgba, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output); virtual void compressBlock(ColorBlock & rgba, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output);
virtual uint blockSize() const { return 8; } virtual uint blockSize() const { return 8; }
}; };
struct NormalCompressorDXT1a : public FixedBlockCompressor struct NormalCompressorDXT1a : public FixedBlockCompressor
{ {
virtual void compressBlock(ColorBlock & rgba, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output); virtual void compressBlock(ColorBlock & rgba, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output);
virtual uint blockSize() const { return 8; } virtual uint blockSize() const { return 8; }
}; };
struct NormalCompressorDXT3 : public FixedBlockCompressor struct NormalCompressorDXT3 : public FixedBlockCompressor
{ {
virtual void compressBlock(ColorBlock & rgba, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output); virtual void compressBlock(ColorBlock & rgba, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output);
virtual uint blockSize() const { return 16; } virtual uint blockSize() const { return 16; }
}; };
struct NormalCompressorDXT5 : public FixedBlockCompressor struct NormalCompressorDXT5 : public FixedBlockCompressor
{ {
virtual void compressBlock(ColorBlock & rgba, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output); virtual void compressBlock(ColorBlock & rgba, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output);
virtual uint blockSize() const { return 16; } virtual uint blockSize() const { return 16; }
}; };
struct NormalCompressorDXT5n : public FixedBlockCompressor struct NormalCompressorDXT5n : public FixedBlockCompressor
{ {
virtual void compressBlock(ColorBlock & rgba, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output); virtual void compressBlock(ColorBlock & rgba, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output);
virtual uint blockSize() const { return 16; } virtual uint blockSize() const { return 16; }
}; };
// External compressors. // External compressors.
#if defined(HAVE_S3QUANT)
struct S3CompressorDXT1 : public CompressorInterface
{
virtual void compress(nvtt::InputFormat inputFormat, nvtt::AlphaMode alphaMode, uint w, uint h, void * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions);
};
#endif
#if defined(HAVE_ATITC) #if defined(HAVE_ATITC)
struct AtiCompressorDXT1 : public CompressorInterface struct AtiCompressorDXT1 : public CompressorInterface
{ {
virtual void compress(nvtt::InputFormat inputFormat, nvtt::AlphaMode alphaMode, uint w, uint h, void * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions); virtual void compress(nvtt::InputFormat inputFormat, nvtt::AlphaMode alphaMode, uint w, uint h, void * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions);
}; };
struct AtiCompressorDXT5 : public CompressorInterface struct AtiCompressorDXT5 : public CompressorInterface
{ {
virtual void compress(nvtt::InputFormat inputFormat, nvtt::AlphaMode alphaMode, uint w, uint h, void * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions); virtual void compress(nvtt::InputFormat inputFormat, nvtt::AlphaMode alphaMode, uint w, uint h, void * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions);
}; };
#endif #endif
#if defined(HAVE_SQUISH) #if defined(HAVE_SQUISH)
struct SquishCompressorDXT1 : public CompressorInterface struct SquishCompressorDXT1 : public CompressorInterface
{ {
virtual void compress(nvtt::InputFormat inputFormat, nvtt::AlphaMode alphaMode, uint w, uint h, void * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions); virtual void compress(nvtt::InputFormat inputFormat, nvtt::AlphaMode alphaMode, uint w, uint h, void * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions);
}; };
#endif #endif
#if defined(HAVE_D3DX) #if defined(HAVE_D3DX)
struct D3DXCompressorDXT1 : public CompressorInterface struct D3DXCompressorDXT1 : public CompressorInterface
{ {
virtual void compress(nvtt::InputFormat inputFormat, nvtt::AlphaMode alphaMode, uint w, uint h, void * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions); virtual void compress(nvtt::InputFormat inputFormat, nvtt::AlphaMode alphaMode, uint w, uint h, void * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions);
}; };
#endif #endif
#if defined(HAVE_STB) #if defined(HAVE_STB)
struct StbCompressorDXT1 : public FixedBlockCompressor struct StbCompressorDXT1 : public FixedBlockCompressor
{ {
virtual void compressBlock(ColorBlock & rgba, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output); virtual void compressBlock(ColorBlock & rgba, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output);
virtual uint blockSize() const { return 8; } virtual uint blockSize() const { return 8; }
}; };
#endif #endif
} // nv namespace } // nv namespace

View File

@ -44,87 +44,75 @@ using namespace nv;
using namespace nvtt; using namespace nvtt;
void FixedBlockCompressor::compress(nvtt::InputFormat inputFormat, nvtt::AlphaMode alphaMode, uint w, uint h, const void * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions) void FixedBlockCompressor::compress(nvtt::AlphaMode alphaMode, uint w, uint h, const float * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions)
{ {
const uint bs = blockSize(); const uint bs = blockSize();
const uint bw = (w + 3) / 4; const uint bw = (w + 3) / 4;
const uint bh = (h + 3) / 4; const uint bh = (h + 3) / 4;
#if defined(HAVE_OPENMP) #if defined(HAVE_OPENMP)
bool singleThreaded = false; bool singleThreaded = false;
#else #else
bool singleThreaded = true; bool singleThreaded = true;
#endif #endif
// Use a single thread to compress small textures. // Use a single thread to compress small textures.
if (bw * bh < 16) singleThreaded = true; if (bw * bh < 16) singleThreaded = true;
if (singleThreaded) if (singleThreaded)
{ {
nvDebugCheck(bs <= 16); nvDebugCheck(bs <= 16);
uint8 mem[16]; // @@ Output one row at a time! uint8 mem[16]; // @@ Output one row at a time!
for (int y = 0; y < int(h); y += 4) { for (int y = 0; y < int(h); y += 4) {
for (uint x = 0; x < w; x += 4) { for (uint x = 0; x < w; x += 4) {
ColorBlock rgba; ColorBlock rgba;
if (inputFormat == nvtt::InputFormat_BGRA_8UB) { rgba.init(w, h, data, x, y);
rgba.init(w, h, (const uint *)data, x, y);
}
else {
nvDebugCheck(inputFormat == nvtt::InputFormat_RGBA_32F);
rgba.init(w, h, (const float *)data, x, y);
}
compressBlock(rgba, alphaMode, compressionOptions, mem); compressBlock(rgba, alphaMode, compressionOptions, mem);
if (outputOptions.outputHandler != NULL) { if (outputOptions.outputHandler != NULL) {
outputOptions.outputHandler->writeData(mem, bs); outputOptions.outputHandler->writeData(mem, bs);
} }
} }
} }
} }
#if defined(HAVE_OPENMP) #if defined(HAVE_OPENMP)
else else
{ {
const uint size = bs * bw * bh; const uint size = bs * bw * bh;
uint8 * mem = new uint8[size]; uint8 * mem = new uint8[size];
#pragma omp parallel #pragma omp parallel
{ {
#pragma omp for #pragma omp for
for (int i = 0; i < int(bw*bh); i++) for (int i = 0; i < int(bw*bh); i++)
{ {
const uint x = i % bw; const uint x = i % bw;
const uint y = i / bw; const uint y = i / bw;
ColorBlock rgba; ColorBlock rgba;
if (inputFormat == nvtt::InputFormat_BGRA_8UB) { rgba.init(w, h, data, 4*x, 4*y);
rgba.init(w, h, (uint *)data, 4*x, 4*y);
}
else {
nvDebugCheck(inputFormat == nvtt::InputFormat_RGBA_32F);
rgba.init(w, h, (float *)data, 4*x, 4*y);
}
uint8 * ptr = mem + (y * bw + x) * bs; uint8 * ptr = mem + (y * bw + x) * bs;
compressBlock(rgba, alphaMode, compressionOptions, ptr); compressBlock(rgba, alphaMode, compressionOptions, ptr);
} // omp for } // omp for
} // omp parallel } // omp parallel
if (outputOptions.outputHandler != NULL) { if (outputOptions.outputHandler != NULL) {
outputOptions.outputHandler->writeData(mem, size); outputOptions.outputHandler->writeData(mem, size);
}
delete [] mem;
} }
delete [] mem;
}
#endif #endif
} }
#include "bc6h/tile.h" #include "bc6h/tile.h"
void TileCompressor::compress(InputFormat inputFormat, AlphaMode alphaMode, uint w, uint h, const void * data, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) void TileCompressor::compress(AlphaMode alphaMode, uint w, uint h, const float * data, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions)
{ {
const uint bs = blockSize(); const uint bs = blockSize();
const uint bw = (w + 3) / 4; const uint bw = (w + 3) / 4;
@ -141,13 +129,7 @@ void TileCompressor::compress(InputFormat inputFormat, AlphaMode alphaMode, uint
for (uint x = 0; x < w; x += 4) { for (uint x = 0; x < w; x += 4) {
Tile tile; Tile tile;
if (inputFormat == nvtt::InputFormat_BGRA_8UB) { //tile.init((const float *)data, w, h, x, y);
//tile.init((const uint *)data, w, h, x, y);
}
else {
nvDebugCheck(inputFormat == nvtt::InputFormat_RGBA_32F);
//tile.init((const float *)data, w, h, x, y);
}
compressBlock(tile, alphaMode, compressionOptions, mem); compressBlock(tile, alphaMode, compressionOptions, mem);

View File

@ -30,23 +30,23 @@ class Tile;
namespace nv namespace nv
{ {
struct ColorBlock; struct ColorBlock;
struct FixedBlockCompressor : public CompressorInterface struct FixedBlockCompressor : public CompressorInterface
{ {
virtual void compress(nvtt::InputFormat inputFormat, nvtt::AlphaMode alphaMode, uint w, uint h, const void * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions); virtual void compress(nvtt::AlphaMode alphaMode, uint w, uint h, const float * rgba, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions);
virtual void compressBlock(ColorBlock & rgba, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output) = 0; virtual void compressBlock(ColorBlock & rgba, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output) = 0;
virtual uint blockSize() const = 0; virtual uint blockSize() const = 0;
}; };
struct TileCompressor : public CompressorInterface struct TileCompressor : public CompressorInterface
{ {
virtual void compress(nvtt::InputFormat inputFormat, nvtt::AlphaMode alphaMode, uint w, uint h, const void * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions); virtual void compress(nvtt::AlphaMode alphaMode, uint w, uint h, const float * rgba, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions);
virtual void compressBlock(Tile & tile, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output) = 0; virtual void compressBlock(Tile & tile, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output) = 0;
virtual uint blockSize() const = 0; virtual uint blockSize() const = 0;
}; };
} // nv namespace } // nv namespace

View File

@ -39,19 +39,19 @@ using namespace nvtt;
namespace namespace
{ {
inline void convert_to_a8r8g8b8(const void * src, void * dst, uint w) inline void convert_to_a8r8g8b8(const void * src, void * dst, uint w)
{ {
memcpy(dst, src, 4 * w); memcpy(dst, src, 4 * w);
} }
inline void convert_to_x8r8g8b8(const void * src, void * dst, uint w) inline void convert_to_x8r8g8b8(const void * src, void * dst, uint w)
{ {
memcpy(dst, src, 4 * w); memcpy(dst, src, 4 * w);
} }
static uint16 to_half(float f) static uint16 to_half(float f)
{ {
union { float f; uint32 u; } c; union { float f; uint32 u; } c;
c.f = f; c.f = f;
return half_from_float(c.u); return half_from_float(c.u);
} }
@ -121,8 +121,10 @@ namespace
void PixelFormatConverter::compress(nvtt::InputFormat inputFormat, nvtt::AlphaMode alphaMode, uint w, uint h, const void * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions) void PixelFormatConverter::compress(nvtt::AlphaMode /*alphaMode*/, uint w, uint h, const float * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions)
{ {
nvDebugCheck (compressionOptions.format == nvtt::Format_RGBA);
uint bitCount; uint bitCount;
uint rmask, rshift, rsize; uint rmask, rshift, rsize;
uint gmask, gshift, gsize; uint gmask, gshift, gsize;
@ -193,89 +195,65 @@ void PixelFormatConverter::compress(nvtt::InputFormat inputFormat, nvtt::AlphaMo
const uint * src = (const uint *)data + y * w; const uint * src = (const uint *)data + y * w;
const float * fsrc = (const float *)data + y * w; const float * fsrc = (const float *)data + y * w;
if (inputFormat == nvtt::InputFormat_BGRA_8UB && compressionOptions.pixelType == nvtt::PixelType_UnsignedNorm && bitCount == 32 && rmask == 0xFF0000 && gmask == 0xFF00 && bmask == 0xFF && amask == 0xFF000000) BitStream stream(dst);
{
convert_to_a8r8g8b8(src, dst, w);
}
else
{
BitStream stream(dst);
for (uint x = 0; x < w; x++) for (uint x = 0; x < w; x++)
{
float r = fsrc[x + 0 * wh];
float g = fsrc[x + 1 * wh];
float b = fsrc[x + 2 * wh];
float a = fsrc[x + 3 * wh];
if (compressionOptions.pixelType == nvtt::PixelType_Float)
{ {
float r, g, b, a; if (rsize == 32) stream.putFloat(r);
else if (rsize == 16) stream.putHalf(r);
if (inputFormat == nvtt::InputFormat_BGRA_8UB) { if (gsize == 32) stream.putFloat(g);
Color32 c = Color32(src[x]); else if (gsize == 16) stream.putHalf(g);
r = float(c.r) / 255.0f;
g = float(c.g) / 255.0f;
b = float(c.b) / 255.0f;
a = float(c.a) / 255.0f;
}
else {
nvDebugCheck (inputFormat == nvtt::InputFormat_RGBA_32F);
//r = ((float *)src)[4 * x + 0]; // Color components not interleaved. if (bsize == 32) stream.putFloat(b);
//g = ((float *)src)[4 * x + 1]; else if (bsize == 16) stream.putHalf(b);
//b = ((float *)src)[4 * x + 2];
//a = ((float *)src)[4 * x + 3];
r = fsrc[x + 0 * wh];
g = fsrc[x + 1 * wh];
b = fsrc[x + 2 * wh];
a = fsrc[x + 3 * wh];
}
if (compressionOptions.pixelType == nvtt::PixelType_Float) if (asize == 32) stream.putFloat(a);
{ else if (asize == 16) stream.putHalf(a);
if (rsize == 32) stream.putFloat(r);
else if (rsize == 16) stream.putHalf(r);
if (gsize == 32) stream.putFloat(g);
else if (gsize == 16) stream.putHalf(g);
if (bsize == 32) stream.putFloat(b);
else if (bsize == 16) stream.putHalf(b);
if (asize == 32) stream.putFloat(a);
else if (asize == 16) stream.putHalf(a);
}
else
{
Color32 c;
if (compressionOptions.pixelType == nvtt::PixelType_UnsignedNorm) {
c.r = uint8(clamp(r * 255, 0.0f, 255.0f));
c.g = uint8(clamp(g * 255, 0.0f, 255.0f));
c.b = uint8(clamp(b * 255, 0.0f, 255.0f));
c.a = uint8(clamp(a * 255, 0.0f, 255.0f));
}
// @@ Add support for nvtt::PixelType_SignedInt, nvtt::PixelType_SignedNorm, nvtt::PixelType_UnsignedInt
uint p = 0;
p |= PixelFormat::convert(c.r, 8, rsize) << rshift;
p |= PixelFormat::convert(c.g, 8, gsize) << gshift;
p |= PixelFormat::convert(c.b, 8, bsize) << bshift;
p |= PixelFormat::convert(c.a, 8, asize) << ashift;
stream.putBits(p, bitCount);
// Output one byte at a time.
/*for (uint i = 0; i < byteCount; i++)
{
*(dst + x * byteCount + i) = (p >> (i * 8)) & 0xFF;
}*/
}
} }
else
// Zero padding.
stream.align(compressionOptions.pitchAlignment);
nvDebugCheck(stream.ptr == dst + pitch);
/*for (uint x = w * byteCount; x < pitch; x++)
{ {
*(dst + x) = 0; Color32 c;
}*/ if (compressionOptions.pixelType == nvtt::PixelType_UnsignedNorm) {
c.r = uint8(clamp(r * 255, 0.0f, 255.0f));
c.g = uint8(clamp(g * 255, 0.0f, 255.0f));
c.b = uint8(clamp(b * 255, 0.0f, 255.0f));
c.a = uint8(clamp(a * 255, 0.0f, 255.0f));
}
// @@ Add support for nvtt::PixelType_SignedInt, nvtt::PixelType_SignedNorm, nvtt::PixelType_UnsignedInt
uint p = 0;
p |= PixelFormat::convert(c.r, 8, rsize) << rshift;
p |= PixelFormat::convert(c.g, 8, gsize) << gshift;
p |= PixelFormat::convert(c.b, 8, bsize) << bshift;
p |= PixelFormat::convert(c.a, 8, asize) << ashift;
stream.putBits(p, bitCount);
// Output one byte at a time.
/*for (uint i = 0; i < byteCount; i++)
{
*(dst + x * byteCount + i) = (p >> (i * 8)) & 0xFF;
}*/
}
} }
// Zero padding.
stream.align(compressionOptions.pitchAlignment);
nvDebugCheck(stream.ptr == dst + pitch);
/*for (uint x = w * byteCount; x < pitch; x++)
{
*(dst + x) = 0;
}*/
outputOptions.writeData(dst, pitch); outputOptions.writeData(dst, pitch);
} }

View File

@ -29,9 +29,9 @@
namespace nv namespace nv
{ {
struct PixelFormatConverter : public CompressorInterface struct PixelFormatConverter : public CompressorInterface
{ {
virtual void compress(nvtt::InputFormat inputFormat, nvtt::AlphaMode alphaMode, uint w, uint h, const void * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions); virtual void compress(nvtt::AlphaMode alphaMode, uint w, uint h, const float * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions);
}; };
} // nv namespace } // nv namespace

View File

@ -55,7 +55,7 @@ static Color32 toRgbe8(float r, float g, float b)
} }
void CompressorRGBE::compress(nvtt::InputFormat inputFormat, nvtt::AlphaMode alphaMode, uint w, uint h, const void * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions) void CompressorRGBE::compress(nvtt::AlphaMode /*alphaMode*/, uint w, uint h, const float * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions)
{ {
nvDebugCheck (compressionOptions.format == nvtt::Format_RGBE); nvDebugCheck (compressionOptions.format == nvtt::Format_RGBE);
@ -63,39 +63,25 @@ void CompressorRGBE::compress(nvtt::InputFormat inputFormat, nvtt::AlphaMode alp
uint srcPlane = w * h; uint srcPlane = w * h;
// Allocate output scanline. // Allocate output scanline.
Color32 * dst = new Color32[w]; Color32 * dst = new Color32[w];
for (uint y = 0; y < h; y++) for (uint y = 0; y < h; y++)
{ {
const uint * src = (const uint *)data + y * srcPitch; const float * src = (const float *)data + y * srcPitch;
const float * fsrc = (const float *)data + y * srcPitch;
for (uint x = 0; x < w; x++) for (uint x = 0; x < w; x++)
{ {
float r, g, b; float r = src[x + 0 * srcPlane];
float g = src[x + 1 * srcPlane];
if (inputFormat == nvtt::InputFormat_BGRA_8UB) { float b = src[x + 2 * srcPlane];
Color32 c = Color32(src[x]);
r = float(c.r) / 255.0f;
g = float(c.g) / 255.0f;
b = float(c.b) / 255.0f;
}
else {
nvDebugCheck (inputFormat == nvtt::InputFormat_RGBA_32F);
// Color components not interleaved.
r = fsrc[x + 0 * srcPlane];
g = fsrc[x + 1 * srcPlane];
b = fsrc[x + 2 * srcPlane];
}
dst[x] = toRgbe8(r, g, b); dst[x] = toRgbe8(r, g, b);
} }
if (outputOptions.outputHandler != NULL) if (outputOptions.outputHandler != NULL)
{ {
outputOptions.outputHandler->writeData(dst, w * 4); outputOptions.outputHandler->writeData(dst, w * 4);
} }
} }
delete [] dst; delete [] dst;

View File

@ -30,7 +30,7 @@ namespace nv
{ {
struct CompressorRGBE : public CompressorInterface struct CompressorRGBE : public CompressorInterface
{ {
virtual void compress(nvtt::InputFormat inputFormat, nvtt::AlphaMode alphaMode, uint w, uint h, const void * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions); virtual void compress(nvtt::AlphaMode alphaMode, uint w, uint h, const float * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions);
}; };
} // nv namespace } // nv namespace

File diff suppressed because it is too large Load Diff

View File

@ -32,54 +32,49 @@
namespace nv namespace nv
{ {
class Image; class Image;
} }
namespace nvtt namespace nvtt
{ {
struct Mipmap; struct Mipmap;
struct Compressor::Private struct Compressor::Private
{ {
Private() {} Private() {}
bool compress(const InputOptions::Private & inputOptions, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const; bool compress(const TexImage & tex, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const;
bool compress(const InputOptions::Private & inputOptions, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const;
bool compress(AlphaMode alphaMode, int w, int h, int d, const float * data, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const;
bool compress2D(InputFormat inputFormat, AlphaMode alphaMode, int w, int h, const void * data, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const; //int estimateSize(const InputOptions::Private & inputOptions, const CompressionOptions::Private & compressionOptions) const;
int estimateSize(const InputOptions::Private & inputOptions, const CompressionOptions::Private & compressionOptions) const; bool outputHeader(const TexImage & tex, int mipmapCount, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const;
bool outputHeader(const InputOptions::Private & inputOptions, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const;
bool outputHeader(const TexImage & tex, int mipmapCount, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions); nv::CompressorInterface * chooseCpuCompressor(const CompressionOptions::Private & compressionOptions) const;
nv::CompressorInterface * chooseGpuCompressor(const CompressionOptions::Private & compressionOptions) const;
private: //bool compressMipmaps(uint f, const InputOptions::Private & inputOptions, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const;
bool outputHeader(const InputOptions::Private & inputOptions, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const; //bool initMipmap(Mipmap & mipmap, const InputOptions::Private & inputOptions, uint w, uint h, uint d, uint f, uint m) const;
nv::CompressorInterface * chooseCpuCompressor(const CompressionOptions::Private & compressionOptions) const; //int findExactMipmap(const InputOptions::Private & inputOptions, uint w, uint h, uint d, uint f) const;
nv::CompressorInterface * chooseGpuCompressor(const CompressionOptions::Private & compressionOptions) const; //int findClosestMipmap(const InputOptions::Private & inputOptions, uint w, uint h, uint d, uint f) const;
bool compressMipmaps(uint f, const InputOptions::Private & inputOptions, const CompressionOptions::Private & compressionOptions, const OutputOptions::Private & outputOptions) const; //void downsampleMipmap(Mipmap & mipmap, const InputOptions::Private & inputOptions) const;
//void scaleMipmap(Mipmap & mipmap, const InputOptions::Private & inputOptions, uint w, uint h, uint d) const;
bool initMipmap(Mipmap & mipmap, const InputOptions::Private & inputOptions, uint w, uint h, uint d, uint f, uint m) const; //void premultiplyAlphaMipmap(Mipmap & mipmap, const InputOptions::Private & inputOptions) const;
//void processInputImage(Mipmap & mipmap, const InputOptions::Private & inputOptions) const;
int findExactMipmap(const InputOptions::Private & inputOptions, uint w, uint h, uint d, uint f) const; //void quantizeMipmap(Mipmap & mipmap, const CompressionOptions::Private & compressionOptions) const;
int findClosestMipmap(const InputOptions::Private & inputOptions, uint w, uint h, uint d, uint f) const;
void downsampleMipmap(Mipmap & mipmap, const InputOptions::Private & inputOptions) const;
void scaleMipmap(Mipmap & mipmap, const InputOptions::Private & inputOptions, uint w, uint h, uint d) const;
void premultiplyAlphaMipmap(Mipmap & mipmap, const InputOptions::Private & inputOptions) const;
void processInputImage(Mipmap & mipmap, const InputOptions::Private & inputOptions) const;
void quantizeMipmap(Mipmap & mipmap, const CompressionOptions::Private & compressionOptions) const;
public: bool cudaSupported;
bool cudaEnabled;
bool cudaSupported; nv::AutoPtr<nv::CudaContext> cuda;
bool cudaEnabled;
nv::AutoPtr<nv::CudaContext> cuda; };
};
} // nvtt namespace } // nvtt namespace

View File

@ -37,519 +37,311 @@ using namespace nvtt;
namespace namespace
{ {
static uint countMipmaps(int w, int h, int d) static uint countMipmaps(int w, int h, int d)
{ {
uint mipmap = 0; uint mipmap = 0;
while (w != 1 || h != 1 || d != 1) { while (w != 1 || h != 1 || d != 1) {
w = max(1, w / 2); w = max(1, w / 2);
h = max(1, h / 2); h = max(1, h / 2);
d = max(1, d / 2); d = max(1, d / 2);
mipmap++; mipmap++;
} }
return mipmap + 1; return mipmap + 1;
} }
// 1 -> 1, 2 -> 2, 3 -> 2, 4 -> 4, 5 -> 4, ...
static uint previousPowerOfTwo(const uint v)
{
return nextPowerOfTwo(v + 1) / 2;
}
static uint nearestPowerOfTwo(const uint v)
{
const uint np2 = nextPowerOfTwo(v);
const uint pp2 = previousPowerOfTwo(v);
if (np2 - v <= v - pp2)
{
return np2;
}
else
{
return pp2;
}
}
// 1 -> 1, 2 -> 2, 3 -> 2, 4 -> 4, 5 -> 4, ...
static uint previousPowerOfTwo(const uint v)
{
return nextPowerOfTwo(v + 1) / 2;
}
static uint nearestPowerOfTwo(const uint v)
{
const uint np2 = nextPowerOfTwo(v);
const uint pp2 = previousPowerOfTwo(v);
if (np2 - v <= v - pp2)
{
return np2;
}
else
{
return pp2;
}
}
} // namespace } // namespace
/// Constructor. /// Constructor.
InputOptions::InputOptions() : m(*new InputOptions::Private()) InputOptions::InputOptions() : m(*new InputOptions::Private())
{ {
reset(); reset();
} }
// Delete images. // Delete images.
InputOptions::~InputOptions() InputOptions::~InputOptions()
{ {
resetTextureLayout(); resetTextureLayout();
delete &m; delete &m;
} }
// Reset input options. // Reset input options.
void InputOptions::reset() void InputOptions::reset()
{ {
m.wrapMode = WrapMode_Mirror; m.wrapMode = WrapMode_Mirror;
m.textureType = TextureType_2D; m.textureType = TextureType_2D;
m.inputFormat = InputFormat_BGRA_8UB; m.inputFormat = InputFormat_BGRA_8UB;
m.alphaMode = AlphaMode_None; m.alphaMode = AlphaMode_None;
m.inputGamma = 2.2f; m.inputGamma = 2.2f;
m.outputGamma = 2.2f; m.outputGamma = 2.2f;
m.colorTransform = ColorTransform_None;
m.linearTransform = Matrix(identity);
for (int i = 0; i < 4; i++) m.colorOffsets[i] = 0;
for (int i = 0; i < 4; i++) m.swizzleTransform[i] = i;
m.generateMipmaps = true; m.generateMipmaps = true;
m.maxLevel = -1; m.maxLevel = -1;
m.mipmapFilter = MipmapFilter_Box; m.mipmapFilter = MipmapFilter_Box;
m.kaiserWidth = 3; m.kaiserWidth = 3;
m.kaiserAlpha = 4.0f; m.kaiserAlpha = 4.0f;
m.kaiserStretch = 1.0f; m.kaiserStretch = 1.0f;
m.isNormalMap = false; m.isNormalMap = false;
m.normalizeMipmaps = true; m.normalizeMipmaps = true;
m.convertToNormalMap = false; m.convertToNormalMap = false;
m.heightFactors.set(0.0f, 0.0f, 0.0f, 1.0f); m.heightFactors.set(0.0f, 0.0f, 0.0f, 1.0f);
m.bumpFrequencyScale = Vector4(1.0f, 0.5f, 0.25f, 0.125f) / (1.0f + 0.5f + 0.25f + 0.125f); m.bumpFrequencyScale = Vector4(1.0f, 0.5f, 0.25f, 0.125f) / (1.0f + 0.5f + 0.25f + 0.125f);
m.maxExtent = 0;
m.roundMode = RoundMode_None;
m.premultiplyAlpha = false; m.maxExtent = 0;
m.roundMode = RoundMode_None;
} }
// Setup the input image. // Setup the input image.
void InputOptions::setTextureLayout(TextureType type, int width, int height, int depth /*= 1*/) void InputOptions::setTextureLayout(TextureType type, int width, int height, int depth /*= 1*/)
{ {
// Validate arguments. // Validate arguments.
nvCheck(width >= 0); nvCheck(width >= 0);
nvCheck(height >= 0); nvCheck(height >= 0);
nvCheck(depth >= 0); nvCheck(depth >= 0);
// Correct arguments. // Correct arguments.
if (width == 0) width = 1; if (width == 0) width = 1;
if (height == 0) height = 1; if (height == 0) height = 1;
if (depth == 0) depth = 1; if (depth == 0) depth = 1;
// Delete previous images. // Delete previous images.
resetTextureLayout(); resetTextureLayout();
m.textureType = type;
// Allocate images.
m.mipmapCount = countMipmaps(width, height, depth);
m.faceCount = (type == TextureType_Cube) ? 6 : 1;
m.imageCount = m.mipmapCount * m.faceCount;
m.images = new Private::InputImage[m.imageCount];
for(uint f = 0; f < m.faceCount; f++)
{
uint w = width;
uint h = height;
uint d = depth;
for (uint mipLevel = 0; mipLevel < m.mipmapCount; mipLevel++) m.textureType = type;
{ m.width = width;
Private::InputImage & img = m.images[f * m.mipmapCount + mipLevel]; m.height = height;
img.width = w; m.depth = depth;
img.height = h;
img.depth = d; // Allocate images.
img.mipLevel = mipLevel; m.faceCount = (type == TextureType_2D) ? 1 : 6;
img.face = f; m.mipmapCount = countMipmaps(width, height, depth);
m.imageCount = m.mipmapCount * m.faceCount;
img.uint8data = NULL; m.images = new void *[m.imageCount];
img.floatdata = NULL;
memset(m.images, 0, sizeof(void *) * m.imageCount);
w = max(1U, w / 2);
h = max(1U, h / 2); /*for (uint f = 0; f < m.faceCount; f++)
d = max(1U, d / 2); {
} uint w = width;
} uint h = height;
uint d = depth;
for (uint mipLevel = 0; mipLevel < m.mipmapCount; mipLevel++)
{
Private::InputImage & img = m.images[f * m.mipmapCount + mipLevel];
img.width = w;
img.height = h;
img.depth = d;
img.mipLevel = mipLevel;
img.face = f;
img.uint8data = NULL;
img.floatdata = NULL;
w = max(1U, w / 2);
h = max(1U, h / 2);
d = max(1U, d / 2);
}
}*/
} }
void InputOptions::resetTextureLayout() void InputOptions::resetTextureLayout()
{ {
if (m.images != NULL) if (m.images != NULL)
{ {
// Delete image array. // Delete image array.
delete [] m.images; delete [] m.images;
m.images = NULL; m.images = NULL;
m.faceCount = 0; m.faceCount = 0;
m.mipmapCount = 0; m.mipmapCount = 0;
m.imageCount = 0; m.imageCount = 0;
} }
} }
// Copies the data to our internal structures. // Copies the data to our internal structures.
bool InputOptions::setMipmapData(const void * data, int width, int height, int depth /*= 1*/, int face /*= 0*/, int mipLevel /*= 0*/) bool InputOptions::setMipmapData(const void * data, int width, int height, int depth /*= 1*/, int face /*= 0*/, int mipLevel /*= 0*/)
{ {
nvCheck(depth == 1); if (depth != 1) {
return false;
const int idx = face * m.mipmapCount + mipLevel; }
if (face >= m.faceCount) {
if (m.images[idx].width != width || m.images[idx].height != height || m.images[idx].depth != depth || m.images[idx].mipLevel != mipLevel || m.images[idx].face != face) return false;
{ }
// Invalid dimension or index. if (mipLevel >= m.mipmapCount) {
return false; return false;
} }
switch(m.inputFormat)
{
case InputFormat_BGRA_8UB:
if (Image * image = new nv::Image())
{
image->allocate(width, height);
memcpy(image->pixels(), data, width * height * 4);
m.images[idx].uint8data = image;
}
else
{
// @@ Out of memory error.
return false;
}
break;
case InputFormat_RGBA_32F:
if (FloatImage * image = new nv::FloatImage())
{
const float * floatData = (const float *)data;
image->allocate(4, width, height);
for (int c = 0; c < 4; c++)
{
float * channel = image->channel(c);
for (int i = 0; i < width * height; i++)
{
channel[i] = floatData[i*4 + c];
}
}
m.images[idx].floatdata = image;
}
else
{
// @@ Out of memory error.
return false;
}
break;
default:
return false;
}
return true;
}
const int idx = mipLevel * m.faceCount + face;
if (idx >= m.imageCount) {
return false;
}
// Copies data // Compute expected width, height and depth for this mipLevel. Return false if it doesn't match.
bool InputOptions::setMipmapChannelData(const void * data, int channel, int width, int height, int depth /*= 1*/, int face /*= 0*/, int mipLevel /*= 0*/) int w = m.width;
{ int h = m.height;
nvCheck(depth == 1); int d = m.depth;
nvCheck(channel >= 0 && channel < 4); for (int i = 0; i < mipLevel; i++) {
w = max(1, w/2);
const int idx = face * m.mipmapCount + mipLevel; h = max(1, h/2);
d = max(1, d/2);
if (m.images[idx].width != width || m.images[idx].height != height || m.images[idx].depth != depth || m.images[idx].mipLevel != mipLevel || m.images[idx].face != face) }
{ if (w != width || h != height || d != depth) {
// Invalid dimension or index. return false;
return false; }
}
// Allocate image if not allocated already.
if (m.inputFormat == InputFormat_BGRA_8UB)
{
m.images[idx].floatdata = NULL;
if (m.images[idx].uint8data == NULL)
{
m.images[idx].uint8data = new Image();
m.images[idx].uint8data->allocate(width, height);
m.images[idx].uint8data->fill(Color32(0,0,0,0));
}
}
else if (m.inputFormat == InputFormat_RGBA_32F)
{
m.images[idx].uint8data = NULL;
if (m.images[idx].floatdata == NULL)
{
m.images[idx].floatdata = new FloatImage();
m.images[idx].floatdata->allocate(4, width, height);
m.images[idx].floatdata->clear();
}
int imageSize = width * height * depth * 4;
} if (m.inputFormat == InputFormat_BGRA_8UB)
else {
{ imageSize *= sizeof(uint8);
m.images[idx].floatdata = NULL; }
m.images[idx].uint8data = NULL; else if (m.inputFormat == InputFormat_RGBA_16F)
return false; {
} imageSize *= sizeof(uint16);
}
else if (m.inputFormat == InputFormat_RGBA_32F)
{
imageSize *= sizeof(float);
}
else
{
return false;
}
// Copy channel data to image. m.images[idx] = new uint8[imageSize];
if (m.inputFormat == InputFormat_BGRA_8UB) if (m.images[idx] == NULL) {
{ // Out of memory.
// @@ TODO return false;
} }
else if (m.inputFormat == InputFormat_RGBA_32F)
{
const float * floatData = (const float *)data;
float * channelPtr = m.images[idx].floatdata->channel(channel);
for (int i = 0; i < width * height; i++) memcpy(m.images[idx], data, imageSize);
{
channelPtr[i] = floatData[i];
}
}
return true; return true;
} }
/// Describe the format of the input. /// Describe the format of the input.
void InputOptions::setFormat(InputFormat format) void InputOptions::setFormat(InputFormat format)
{ {
m.inputFormat = format; m.inputFormat = format;
} }
/// Set the way the input alpha channel is interpreted. /// Set the way the input alpha channel is interpreted.
void InputOptions::setAlphaMode(AlphaMode alphaMode) void InputOptions::setAlphaMode(AlphaMode alphaMode)
{ {
m.alphaMode = alphaMode; m.alphaMode = alphaMode;
} }
/// Set gamma settings. /// Set gamma settings.
void InputOptions::setGamma(float inputGamma, float outputGamma) void InputOptions::setGamma(float inputGamma, float outputGamma)
{ {
m.inputGamma = inputGamma; m.inputGamma = inputGamma;
m.outputGamma = outputGamma; m.outputGamma = outputGamma;
} }
/// Set texture wrappign mode. /// Set texture wrappign mode.
void InputOptions::setWrapMode(WrapMode mode) void InputOptions::setWrapMode(WrapMode mode)
{ {
m.wrapMode = mode; m.wrapMode = mode;
} }
/// Set mipmap filter. /// Set mipmap filter.
void InputOptions::setMipmapFilter(MipmapFilter filter) void InputOptions::setMipmapFilter(MipmapFilter filter)
{ {
m.mipmapFilter = filter; m.mipmapFilter = filter;
} }
/// Set mipmap generation. /// Set mipmap generation.
void InputOptions::setMipmapGeneration(bool enabled, int maxLevel/*= -1*/) void InputOptions::setMipmapGeneration(bool enabled, int maxLevel/*= -1*/)
{ {
m.generateMipmaps = enabled; m.generateMipmaps = enabled;
m.maxLevel = maxLevel; m.maxLevel = maxLevel;
} }
/// Set Kaiser filter parameters. /// Set Kaiser filter parameters.
void InputOptions::setKaiserParameters(float width, float alpha, float stretch) void InputOptions::setKaiserParameters(float width, float alpha, float stretch)
{ {
m.kaiserWidth = width; m.kaiserWidth = width;
m.kaiserAlpha = alpha; m.kaiserAlpha = alpha;
m.kaiserStretch = stretch; m.kaiserStretch = stretch;
} }
/// Indicate whether input is a normal map or not. /// Indicate whether input is a normal map or not.
void InputOptions::setNormalMap(bool b) void InputOptions::setNormalMap(bool b)
{ {
m.isNormalMap = b; m.isNormalMap = b;
} }
/// Enable normal map conversion. /// Enable normal map conversion.
void InputOptions::setConvertToNormalMap(bool convert) void InputOptions::setConvertToNormalMap(bool convert)
{ {
m.convertToNormalMap = convert; m.convertToNormalMap = convert;
} }
/// Set height evaluation factors. /// Set height evaluation factors.
void InputOptions::setHeightEvaluation(float redScale, float greenScale, float blueScale, float alphaScale) void InputOptions::setHeightEvaluation(float redScale, float greenScale, float blueScale, float alphaScale)
{ {
// Do not normalize height factors. // Do not normalize height factors.
// float total = redScale + greenScale + blueScale + alphaScale; // float total = redScale + greenScale + blueScale + alphaScale;
m.heightFactors = Vector4(redScale, greenScale, blueScale, alphaScale); m.heightFactors = Vector4(redScale, greenScale, blueScale, alphaScale);
} }
/// Set normal map conversion filter. /// Set normal map conversion filter.
void InputOptions::setNormalFilter(float small, float medium, float big, float large) void InputOptions::setNormalFilter(float small, float medium, float big, float large)
{ {
float total = small + medium + big + large; float total = small + medium + big + large;
m.bumpFrequencyScale = Vector4(small, medium, big, large) / total; m.bumpFrequencyScale = Vector4(small, medium, big, large) / total;
} }
/// Enable mipmap normalization. /// Enable mipmap normalization.
void InputOptions::setNormalizeMipmaps(bool normalize) void InputOptions::setNormalizeMipmaps(bool normalize)
{ {
m.normalizeMipmaps = normalize; m.normalizeMipmaps = normalize;
}
/// Set color transform.
void InputOptions::setColorTransform(ColorTransform t)
{
m.colorTransform = t;
}
// Set linear transform for the given channel.
void InputOptions::setLinearTransform(int channel, float w0, float w1, float w2, float w3)
{
nvCheck(channel >= 0 && channel < 4);
m.linearTransform(channel, 0) = w0;
m.linearTransform(channel, 1) = w1;
m.linearTransform(channel, 2) = w2;
m.linearTransform(channel, 3) = w3;
}
void InputOptions::setLinearTransform(int channel, float w0, float w1, float w2, float w3, float offset)
{
nvCheck(channel >= 0 && channel < 4);
setLinearTransform(channel, w0, w1, w2, w3);
m.colorOffsets[channel] = offset;
}
void InputOptions::setSwizzleTransform(int x, int y, int z, int w)
{
nvCheck(x >= 0 && x <= 6);
nvCheck(y >= 0 && y <= 6);
nvCheck(z >= 0 && z <= 6);
nvCheck(w >= 0 && w <= 6);
m.swizzleTransform[0] = x;
m.swizzleTransform[1] = y;
m.swizzleTransform[2] = z;
m.swizzleTransform[3] = w;
} }
void InputOptions::setMaxExtents(int e) void InputOptions::setMaxExtents(int e)
{ {
nvDebugCheck(e > 0); nvDebugCheck(e > 0);
m.maxExtent = e; m.maxExtent = e;
} }
void InputOptions::setRoundMode(RoundMode mode) void InputOptions::setRoundMode(RoundMode mode)
{ {
m.roundMode = mode; m.roundMode = mode;
}
void InputOptions::setPremultiplyAlpha(bool b)
{
m.premultiplyAlpha = b;
}
void InputOptions::Private::computeTargetExtents() const
{
nvCheck(images != NULL);
uint maxExtent = this->maxExtent;
if (roundMode != RoundMode_None)
{
// rounded max extent should never be higher than original max extent.
maxExtent = previousPowerOfTwo(maxExtent);
}
uint w = images->width;
uint h = images->height;
uint d = images->depth;
nvDebugCheck(w > 0);
nvDebugCheck(h > 0);
nvDebugCheck(d > 0);
// Scale extents without changing aspect ratio.
uint maxwhd = max(max(w, h), d);
if (maxExtent != 0 && maxwhd > maxExtent)
{
w = max((w * maxExtent) / maxwhd, 1U);
h = max((h * maxExtent) / maxwhd, 1U);
d = max((d * maxExtent) / maxwhd, 1U);
}
// Round to power of two.
if (roundMode == RoundMode_ToNextPowerOfTwo)
{
w = nextPowerOfTwo(w);
h = nextPowerOfTwo(h);
d = nextPowerOfTwo(d);
}
else if (roundMode == RoundMode_ToNearestPowerOfTwo)
{
w = nearestPowerOfTwo(w);
h = nearestPowerOfTwo(h);
d = nearestPowerOfTwo(d);
}
else if (roundMode == RoundMode_ToPreviousPowerOfTwo)
{
w = previousPowerOfTwo(w);
h = previousPowerOfTwo(h);
d = previousPowerOfTwo(d);
}
this->targetWidth = w;
this->targetHeight = h;
this->targetDepth = d;
this->targetMipmapCount = countMipmaps(w, h, d);
}
// Return real number of mipmaps, including first level.
// computeTargetExtents should have been called before.
int InputOptions::Private::realMipmapCount() const
{
int mipmapCount = targetMipmapCount;
if (!generateMipmaps) mipmapCount = 1;
else if (maxLevel != -1 && maxLevel < mipmapCount - 1) mipmapCount = maxLevel + 1;
return mipmapCount;
}
const Image * InputOptions::Private::image(uint face, uint mipmap) const
{
nvDebugCheck(face < faceCount);
nvDebugCheck(mipmap < mipmapCount);
const InputImage & image = this->images[face * mipmapCount + mipmap];
nvDebugCheck(image.face == face);
nvDebugCheck(image.mipLevel == mipmap);
return image.uint8data.ptr();
}
const Image * InputOptions::Private::image(uint idx) const
{
nvDebugCheck(idx < faceCount * mipmapCount);
const InputImage & image = this->images[idx];
return image.uint8data.ptr();
}
const FloatImage * InputOptions::Private::floatImage(uint idx) const
{
nvDebugCheck(idx < faceCount * mipmapCount);
const InputImage & image = this->images[idx];
return image.floatdata.ptr();
} }

View File

@ -34,89 +34,49 @@
namespace nvtt namespace nvtt
{ {
struct InputOptions::Private struct InputOptions::Private
{ {
Private() : images(NULL) {} Private() : images(NULL) {}
WrapMode wrapMode;
TextureType textureType;
InputFormat inputFormat;
AlphaMode alphaMode;
uint faceCount;
uint mipmapCount;
uint imageCount;
struct InputImage;
InputImage * images;
// Gamma conversion.
float inputGamma;
float outputGamma;
// Color transform.
ColorTransform colorTransform;
nv::Matrix linearTransform;
float colorOffsets[4];
uint swizzleTransform[4];
// Mipmap generation options.
bool generateMipmaps;
int maxLevel;
MipmapFilter mipmapFilter;
// Kaiser filter parameters.
float kaiserWidth;
float kaiserAlpha;
float kaiserStretch;
// Normal map options.
bool isNormalMap;
bool normalizeMipmaps;
bool convertToNormalMap;
nv::Vector4 heightFactors;
nv::Vector4 bumpFrequencyScale;
// Adjust extents.
uint maxExtent;
RoundMode roundMode;
bool premultiplyAlpha;
// @@ These are computed in nvtt::compress, so they should be mutable or stored elsewhere... WrapMode wrapMode;
mutable uint targetWidth; TextureType textureType;
mutable uint targetHeight; InputFormat inputFormat;
mutable uint targetDepth; AlphaMode alphaMode;
mutable uint targetMipmapCount;
void computeTargetExtents() const;
int realMipmapCount() const;
const nv::Image * image(uint face, uint mipmap) const;
const nv::Image * image(uint idx) const;
const nv::FloatImage * floatImage(uint idx) const; uint width;
uint height;
uint depth;
uint faceCount;
uint mipmapCount;
uint imageCount;
}; void ** images;
// Internal image structure. // Gamma conversion.
struct InputOptions::Private::InputImage float inputGamma;
{ float outputGamma;
InputImage() {}
// Mipmap generation options.
bool hasValidData() const { return uint8data != NULL || floatdata != NULL; } bool generateMipmaps;
int maxLevel;
int mipLevel; MipmapFilter mipmapFilter;
int face;
// Kaiser filter parameters.
int width; float kaiserWidth;
int height; float kaiserAlpha;
int depth; float kaiserStretch;
nv::AutoPtr<nv::Image> uint8data; // Normal map options.
nv::AutoPtr<nv::FloatImage> floatdata; bool isNormalMap;
}; bool normalizeMipmaps;
bool convertToNormalMap;
nv::Vector4 heightFactors;
nv::Vector4 bumpFrequencyScale;
// Adjust extents.
uint maxExtent;
RoundMode roundMode;
};
} // nvtt namespace } // nvtt namespace

View File

@ -54,7 +54,7 @@ namespace
return d * d; return d * d;
} }
static uint nearestGreen4(uint green, uint maxGreen, uint minGreen) /*static uint nearestGreen4(uint green, uint maxGreen, uint minGreen)
{ {
uint bias = maxGreen + (maxGreen - minGreen) / 6; uint bias = maxGreen + (maxGreen - minGreen) / 6;
@ -62,7 +62,7 @@ namespace
if (maxGreen - minGreen != 0) index = clamp(3 * (bias - green) / (maxGreen - minGreen), 0U, 3U); if (maxGreen - minGreen != 0) index = clamp(3 * (bias - green) / (maxGreen - minGreen), 0U, 3U);
return (index * minGreen + (3 - index) * maxGreen) / 3; return (index * minGreen + (3 - index) * maxGreen) / 3;
} }*/
static int computeGreenError(const ColorBlock & rgba, const BlockDXT1 * block, int bestError = INT_MAX) static int computeGreenError(const ColorBlock & rgba, const BlockDXT1 * block, int bestError = INT_MAX)
{ {
@ -164,7 +164,7 @@ namespace
return (index * minAlpha + (7 - index) * maxAlpha) / 7; return (index * minAlpha + (7 - index) * maxAlpha) / 7;
} }
static uint computeAlphaError8(const ColorBlock & rgba, const AlphaBlockDXT5 * block, int bestError = INT_MAX) /*static uint computeAlphaError8(const ColorBlock & rgba, const AlphaBlockDXT5 * block, int bestError = INT_MAX)
{ {
int totalError = 0; int totalError = 0;
@ -182,7 +182,7 @@ namespace
} }
return totalError; return totalError;
} }*/
static uint computeAlphaError(const ColorBlock & rgba, const AlphaBlockDXT5 * block, int bestError = INT_MAX) static uint computeAlphaError(const ColorBlock & rgba, const AlphaBlockDXT5 * block, int bestError = INT_MAX)
{ {

File diff suppressed because it is too large Load Diff

View File

@ -42,6 +42,8 @@ namespace nvtt
public: public:
Private() Private()
{ {
nvDebugCheck( refCount() == 0 );
type = TextureType_2D; type = TextureType_2D;
wrapMode = WrapMode_Mirror; wrapMode = WrapMode_Mirror;
alphaMode = AlphaMode_None; alphaMode = AlphaMode_None;
@ -49,8 +51,10 @@ namespace nvtt
imageArray.resize(1, NULL); imageArray.resize(1, NULL);
} }
Private(const Private & p) // Copy ctor. inits refcount to 0. Private(const Private & p) : RefCounted() // Copy ctor. inits refcount to 0.
{ {
nvDebugCheck( refCount() == 0 );
type = p.type; type = p.type;
wrapMode = p.wrapMode; wrapMode = p.wrapMode;
alphaMode = p.alphaMode; alphaMode = p.alphaMode;

View File

@ -262,7 +262,7 @@ static int clamp(double r, double low, double high)
// match the tonemapping function used by exrdisplay // match the tonemapping function used by exrdisplay
static void tonemap(const Vector3 &in, double exposure, Vector3 &out) /*static void tonemap(const Vector3 &in, double exposure, Vector3 &out)
{ {
double r,g,b; double r,g,b;
unsigned short h; unsigned short h;
@ -325,7 +325,7 @@ static void tonemap(const Vector3 &in, double exposure, Vector3 &out)
out.x = clamp (r, 0, 255); out.x = clamp (r, 0, 255);
out.y = clamp (g, 0, 255); out.y = clamp (g, 0, 255);
out.z = clamp (b, 0, 255); out.z = clamp (b, 0, 255);
} }*/
static void mpsnrmap(const Vector3 &in, int exposure, Vector3 &out) static void mpsnrmap(const Vector3 &in, int exposure, Vector3 &out)
{ {

View File

@ -124,38 +124,45 @@ CudaCompressor::CudaCompressor(CudaContext & ctx) : m_ctx(ctx)
} }
void CudaCompressor::compress(nvtt::InputFormat inputFormat, nvtt::AlphaMode alphaMode, uint w, uint h, const void * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions) void CudaCompressor::compress(nvtt::AlphaMode alphaMode, uint w, uint h, const float * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions)
{ {
nvDebugCheck(cuda::isHardwarePresent()); nvDebugCheck(cuda::isHardwarePresent());
#if defined HAVE_CUDA #if defined HAVE_CUDA
// Allocate image as a cuda array. // Allocate image as a cuda array.
const uint count = w * h;
Color32 * tmp = malloc<Color32>(count);
for (int i = 0; i < count; i++) {
tmp[i].r = clamp(data[i + count*0], 0.0f, 1.0f) * 255;
tmp[i].g = clamp(data[i + count*1], 0.0f, 1.0f) * 255;
tmp[i].b = clamp(data[i + count*2], 0.0f, 1.0f) * 255;
tmp[i].a = clamp(data[i + count*3], 0.0f, 1.0f) * 255;
}
cudaArray * d_image; cudaArray * d_image;
if (inputFormat == nvtt::InputFormat_BGRA_8UB) cudaChannelFormatDesc channelDesc = cudaCreateChannelDesc(8, 8, 8, 8, cudaChannelFormatKindUnsigned);
{ cudaMallocArray(&d_image, &channelDesc, w, h);
cudaChannelFormatDesc channelDesc = cudaCreateChannelDesc(8, 8, 8, 8, cudaChannelFormatKindUnsigned);
cudaMallocArray(&d_image, &channelDesc, w, h);
const int imageSize = w * h * sizeof(uint); cudaMemcpyToArray(d_image, 0, 0, tmp, count * sizeof(Color32), cudaMemcpyHostToDevice);
cudaMemcpyToArray(d_image, 0, 0, data, imageSize, cudaMemcpyHostToDevice);
}
else
{
#pragma NV_MESSAGE("FIXME: Floating point textures not really supported by CUDA compressors.") // @@ What's missing???
cudaChannelFormatDesc channelDesc = cudaCreateChannelDesc(32, 32, 32, 32, cudaChannelFormatKindFloat);
cudaMallocArray(&d_image, &channelDesc, w, h);
const int imageSize = w * h * sizeof(uint); free(tmp);
cudaMemcpyToArray(d_image, 0, 0, data, imageSize, cudaMemcpyHostToDevice);
} // To avoid the copy we could keep the data in floating point format, but the channels are not interleaved like the kernel expects.
/*
cudaChannelFormatDesc channelDesc = cudaCreateChannelDesc(32, 32, 32, 32, cudaChannelFormatKindFloat);
cudaMallocArray(&d_image, &channelDesc, w, h);
const int imageSize = w * h * sizeof(float) * 4;
cudaMemcpyToArray(d_image, 0, 0, data, imageSize, cudaMemcpyHostToDevice);
*/
// Image size in blocks. // Image size in blocks.
const uint bw = (w + 3) / 4; const uint bw = (w + 3) / 4;
const uint bh = (h + 3) / 4; const uint bh = (h + 3) / 4;
const uint bs = blockSize(); const uint bs = blockSize();
const uint blockNum = bw * bh; const uint blockNum = bw * bh;
const uint compressedSize = blockNum * bs; //const uint compressedSize = blockNum * bs;
void * h_result = ::malloc(min(blockNum, MAX_BLOCKS) * bs); void * h_result = ::malloc(min(blockNum, MAX_BLOCKS) * bs);
@ -192,9 +199,8 @@ void CudaCompressor::compress(nvtt::InputFormat inputFormat, nvtt::AlphaMode alp
cudaFreeArray(d_image); cudaFreeArray(d_image);
#else #else
outputOptions.error(Error_CudaError); outputOptions.error(Error_CudaError);
#endif #endif
} }
#if defined HAVE_CUDA #if defined HAVE_CUDA

View File

@ -53,7 +53,7 @@ namespace nv
{ {
CudaCompressor(CudaContext & ctx); CudaCompressor(CudaContext & ctx);
virtual void compress(nvtt::InputFormat inputFormat, nvtt::AlphaMode alphaMode, uint w, uint h, const void * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions); virtual void compress(nvtt::AlphaMode alphaMode, uint w, uint h, const float * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions);
virtual void setup(cudaArray * image, const nvtt::CompressionOptions::Private & compressionOptions) = 0; virtual void setup(cudaArray * image, const nvtt::CompressionOptions::Private & compressionOptions) = 0;
virtual void compressBlocks(uint first, uint count, uint w, uint h, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output) = 0; virtual void compressBlocks(uint first, uint count, uint w, uint h, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output) = 0;

View File

@ -29,459 +29,440 @@
#if NVTT_SHARED #if NVTT_SHARED
#if defined _WIN32 || defined WIN32 || defined __NT__ || defined __WIN32__ || defined __MINGW32__ #if defined _WIN32 || defined WIN32 || defined __NT__ || defined __WIN32__ || defined __MINGW32__
# ifdef NVTT_EXPORTS # ifdef NVTT_EXPORTS
# define NVTT_API __declspec(dllexport) # define NVTT_API __declspec(dllexport)
# else # else
# define NVTT_API __declspec(dllimport) # define NVTT_API __declspec(dllimport)
# endif # endif
#endif #endif
#if defined __GNUC__ >= 4 #if defined __GNUC__ >= 4
# ifdef NVTT_EXPORTS # ifdef NVTT_EXPORTS
# define NVTT_API __attribute__((visibility("default"))) # define NVTT_API __attribute__((visibility("default")))
# endif # endif
#endif #endif
#endif // NVTT_SHARED #endif // NVTT_SHARED
#if !defined NVTT_API #if !defined NVTT_API
# define NVTT_API # define NVTT_API
#endif #endif
#define NVTT_VERSION 20100 #define NVTT_VERSION 20100
#define NVTT_FORBID_COPY(Class) \ #define NVTT_FORBID_COPY(Class) \
private: \ private: \
Class(const Class &); \ Class(const Class &); \
void operator=(const Class &); \ void operator=(const Class &); \
public: public:
#define NVTT_DECLARE_PIMPL(Class) \ #define NVTT_DECLARE_PIMPL(Class) \
public: \ public: \
struct Private; \ struct Private; \
Private & m Private & m
// Public interface. // Public interface.
namespace nvtt namespace nvtt
{ {
// Forward declarations. // Forward declarations.
struct TexImage; struct TexImage;
/// Supported compression formats.
enum Format
{
// No compression.
Format_RGB,
Format_RGBA = Format_RGB,
// DX9 formats.
Format_DXT1,
Format_DXT1a, // DXT1 with binary alpha.
Format_DXT3,
Format_DXT5,
Format_DXT5n, // Compressed HILO: R=1, G=y, B=0, A=x
// DX10 formats.
Format_BC1 = Format_DXT1,
Format_BC1a = Format_DXT1a,
Format_BC2 = Format_DXT3,
Format_BC3 = Format_DXT5,
Format_BC3n = Format_DXT5n,
Format_BC4, // ATI1
Format_BC5, // 3DC, ATI2
Format_DXT1n,// Not supported on CPU yet. /// Supported compression formats.
Format_CTX1, // Not supported on CPU yet. enum Format
//Format_YCoCg_DXT5, // Not supported yet. {
// No compression.
Format_RGB,
Format_RGBA = Format_RGB,
Format_BC6, // Not supported yet. // DX9 formats.
Format_BC7, // Not supported yet. Format_DXT1,
Format_DXT1a, // DXT1 with binary alpha.
Format_DXT3,
Format_DXT5,
Format_DXT5n, // Compressed HILO: R=1, G=y, B=0, A=x
// DX10 formats.
Format_BC1 = Format_DXT1,
Format_BC1a = Format_DXT1a,
Format_BC2 = Format_DXT3,
Format_BC3 = Format_DXT5,
Format_BC3n = Format_DXT5n,
Format_BC4, // ATI1
Format_BC5, // 3DC, ATI2
Format_DXT1n, // Not supported on CPU yet.
Format_CTX1, // Not supported on CPU yet.
Format_BC6, // Not supported yet.
Format_BC7, // Not supported yet.
Format_RGBE, Format_RGBE,
}; };
/// Pixel types. These basically indicate how the output should be interpreted, but do not have any influence over the input. /// Pixel types. These basically indicate how the output should be interpreted, but do not have any influence over the input.
enum PixelType enum PixelType
{ {
PixelType_UnsignedNorm, PixelType_UnsignedNorm = 0,
PixelType_SignedNorm, // Not supported yet. PixelType_SignedNorm = 1, // Not supported yet.
PixelType_UnsignedInt, // Not supported yet. PixelType_UnsignedInt = 2, // Not supported yet.
PixelType_SignedInt, // Not supported yet. PixelType_SignedInt = 3, // Not supported yet.
PixelType_Float, PixelType_Float = 4,
PixelType_UnsignedFloat, PixelType_UnsignedFloat = 5,
}; };
/// Quality modes.
enum Quality
{
Quality_Fastest,
Quality_Normal,
Quality_Production,
Quality_Highest,
};
/// Compression options. This class describes the desired compression format and other compression settings. /// Quality modes.
struct CompressionOptions enum Quality
{ {
NVTT_FORBID_COPY(CompressionOptions); Quality_Fastest,
NVTT_DECLARE_PIMPL(CompressionOptions); Quality_Normal,
Quality_Production,
Quality_Highest,
};
NVTT_API CompressionOptions(); /// Compression options. This class describes the desired compression format and other compression settings.
NVTT_API ~CompressionOptions(); struct CompressionOptions
{
NVTT_API void reset(); NVTT_FORBID_COPY(CompressionOptions);
NVTT_DECLARE_PIMPL(CompressionOptions);
NVTT_API void setFormat(Format format);
NVTT_API void setQuality(Quality quality);
NVTT_API void setColorWeights(float red, float green, float blue, float alpha = 1.0f);
NVTT_API void setExternalCompressor(const char * name);
// Set color mask to describe the RGB/RGBA format. NVTT_API CompressionOptions();
NVTT_API void setPixelFormat(unsigned int bitcount, unsigned int rmask, unsigned int gmask, unsigned int bmask, unsigned int amask); NVTT_API ~CompressionOptions();
NVTT_API void setPixelFormat(unsigned char rsize, unsigned char gsize, unsigned char bsize, unsigned char asize);
NVTT_API void reset();
NVTT_API void setPixelType(PixelType pixelType);
NVTT_API void setFormat(Format format);
NVTT_API void setQuality(Quality quality);
NVTT_API void setColorWeights(float red, float green, float blue, float alpha = 1.0f);
NVTT_API void setExternalCompressor(const char * name);
// Set color mask to describe the RGB/RGBA format.
NVTT_API void setPixelFormat(unsigned int bitcount, unsigned int rmask, unsigned int gmask, unsigned int bmask, unsigned int amask);
NVTT_API void setPixelFormat(unsigned char rsize, unsigned char gsize, unsigned char bsize, unsigned char asize);
NVTT_API void setPixelType(PixelType pixelType);
NVTT_API void setPitchAlignment(int pitchAlignment); NVTT_API void setPitchAlignment(int pitchAlignment);
NVTT_API void setQuantization(bool colorDithering, bool alphaDithering, bool binaryAlpha, int alphaThreshold = 127); NVTT_API void setQuantization(bool colorDithering, bool alphaDithering, bool binaryAlpha, int alphaThreshold = 127);
}; };
/* /*
// DXGI_FORMAT_R16G16_FLOAT // DXGI_FORMAT_R16G16_FLOAT
compressionOptions.setPixelType(PixelType_Float); compressionOptions.setPixelType(PixelType_Float);
compressionOptions.setPixelFormat2(16, 16, 0, 0); compressionOptions.setPixelFormat2(16, 16, 0, 0);
// DXGI_FORMAT_R32G32B32A32_FLOAT
compressionOptions.setPixelType(PixelType_Float);
compressionOptions.setPixelFormat2(32, 32, 32, 32);
*/
/// Wrap modes. // DXGI_FORMAT_R32G32B32A32_FLOAT
enum WrapMode compressionOptions.setPixelType(PixelType_Float);
{ compressionOptions.setPixelFormat2(32, 32, 32, 32);
WrapMode_Clamp, */
WrapMode_Repeat,
WrapMode_Mirror,
};
/// Texture types.
enum TextureType
{
TextureType_2D,
TextureType_Cube,
// TextureType_3D,
};
/// Input formats.
enum InputFormat
{
InputFormat_BGRA_8UB,
InputFormat_RGBA_32F,
};
/// Mipmap downsampling filters.
enum MipmapFilter
{
MipmapFilter_Box, ///< Box filter is quite good and very fast.
MipmapFilter_Triangle, ///< Triangle filter blurs the results too much, but that might be what you want.
MipmapFilter_Kaiser, ///< Kaiser-windowed Sinc filter is the best downsampling filter.
};
/// Texture resize filters.
enum ResizeFilter
{
ResizeFilter_Box,
ResizeFilter_Triangle,
ResizeFilter_Kaiser,
ResizeFilter_Mitchell,
};
/// Color transformation.
enum ColorTransform
{
ColorTransform_None,
ColorTransform_Linear, ///< Not implemented.
ColorTransform_Swizzle, ///< Not implemented.
ColorTransform_YCoCg, ///< Transform into r=Co, g=Cg, b=0, a=Y
ColorTransform_ScaledYCoCg, ///< Not implemented.
};
/// Extents rounding mode.
enum RoundMode
{
RoundMode_None,
RoundMode_ToNextPowerOfTwo,
RoundMode_ToNearestPowerOfTwo,
RoundMode_ToPreviousPowerOfTwo,
};
/// Alpha mode.
enum AlphaMode
{
AlphaMode_None,
AlphaMode_Transparency,
AlphaMode_Premultiplied,
};
/// Input options. Specify format and layout of the input texture.
struct InputOptions
{
NVTT_FORBID_COPY(InputOptions);
NVTT_DECLARE_PIMPL(InputOptions);
NVTT_API InputOptions(); /// Wrap modes.
NVTT_API ~InputOptions(); enum WrapMode
{
// Set default options. WrapMode_Clamp,
NVTT_API void reset(); WrapMode_Repeat,
WrapMode_Mirror,
// Setup input layout. };
NVTT_API void setTextureLayout(TextureType type, int w, int h, int d = 1);
NVTT_API void resetTextureLayout();
// Set mipmap data. Copies the data.
NVTT_API bool setMipmapData(const void * data, int w, int h, int d = 1, int face = 0, int mipmap = 0);
NVTT_API bool setMipmapChannelData(const void * data, int channel, int w, int h, int d = 1, int face = 0, int mipmap = 0);
// Describe the format of the input.
NVTT_API void setFormat(InputFormat format);
// Set the way the input alpha channel is interpreted. @@ Not implemented!
NVTT_API void setAlphaMode(AlphaMode alphaMode);
// Set gamma settings.
NVTT_API void setGamma(float inputGamma, float outputGamma);
// Set texture wrapping mode.
NVTT_API void setWrapMode(WrapMode mode);
// Set mipmapping options.
NVTT_API void setMipmapFilter(MipmapFilter filter);
NVTT_API void setMipmapGeneration(bool enabled, int maxLevel = -1);
NVTT_API void setKaiserParameters(float width, float alpha, float stretch);
// Set normal map options. /// Texture types.
NVTT_API void setNormalMap(bool b); enum TextureType
NVTT_API void setConvertToNormalMap(bool convert); {
NVTT_API void setHeightEvaluation(float redScale, float greenScale, float blueScale, float alphaScale); TextureType_2D,
NVTT_API void setNormalFilter(float sm, float medium, float big, float large); TextureType_Cube,
NVTT_API void setNormalizeMipmaps(bool b); // TextureType_3D,
};
// Set color transforms.
NVTT_API void setColorTransform(ColorTransform t);
NVTT_API void setLinearTransform(int channel, float w0, float w1, float w2, float w3);
NVTT_API void setLinearTransform(int channel, float w0, float w1, float w2, float w3, float offset);
NVTT_API void setSwizzleTransform(int x, int y, int z, int w);
// Set resizing options.
NVTT_API void setMaxExtents(int d);
NVTT_API void setRoundMode(RoundMode mode);
// Set whether or not to premultiply color by alpha /// Input formats.
NVTT_API void setPremultiplyAlpha(bool b); enum InputFormat
}; {
InputFormat_BGRA_8UB, // Normalized [0, 1] 8 bit fixed point.
InputFormat_RGBA_16F, // 16 bit floating point.
/// Output handler. InputFormat_RGBA_32F, // 32 bit floating point.
struct OutputHandler };
{
virtual ~OutputHandler() {}
/// Indicate the start of a new compressed image that's part of the final texture.
virtual void beginImage(int size, int width, int height, int depth, int face, int miplevel) = 0;
/// Output data. Compressed data is output as soon as it's generated to minimize memory allocations.
virtual bool writeData(const void * data, int size) = 0;
};
/// Error codes. /// Mipmap downsampling filters.
enum Error enum MipmapFilter
{ {
Error_Unknown, MipmapFilter_Box, ///< Box filter is quite good and very fast.
Error_InvalidInput, MipmapFilter_Triangle, ///< Triangle filter blurs the results too much, but that might be what you want.
Error_UnsupportedFeature, MipmapFilter_Kaiser, ///< Kaiser-windowed Sinc filter is the best downsampling filter.
Error_CudaError, };
Error_FileOpen,
Error_FileWrite,
Error_UnsupportedOutputFormat,
};
/// Error handler.
struct ErrorHandler
{
virtual ~ErrorHandler() {}
// Signal error.
virtual void error(Error e) = 0;
};
/// Container. /// Texture resize filters.
enum Container enum ResizeFilter
{ {
Container_DDS, ResizeFilter_Box,
Container_DDS10, ResizeFilter_Triangle,
}; ResizeFilter_Kaiser,
ResizeFilter_Mitchell,
};
/// Output Options. This class holds pointers to the interfaces that are used to report the output of /// Extents rounding mode.
/// the compressor to the user. enum RoundMode
struct OutputOptions {
{ RoundMode_None,
NVTT_FORBID_COPY(OutputOptions); RoundMode_ToNextPowerOfTwo,
NVTT_DECLARE_PIMPL(OutputOptions); RoundMode_ToNearestPowerOfTwo,
RoundMode_ToPreviousPowerOfTwo,
};
NVTT_API OutputOptions(); /// Alpha mode.
NVTT_API ~OutputOptions(); enum AlphaMode
{
// Set default options. AlphaMode_None,
NVTT_API void reset(); AlphaMode_Transparency,
AlphaMode_Premultiplied,
NVTT_API void setFileName(const char * fileName); };
NVTT_API void setOutputHandler(OutputHandler * outputHandler);
NVTT_API void setErrorHandler(ErrorHandler * errorHandler);
NVTT_API void setOutputHeader(bool outputHeader); /// Input options. Specify format and layout of the input texture.
NVTT_API void setContainer(Container container); struct InputOptions
{
NVTT_FORBID_COPY(InputOptions);
NVTT_DECLARE_PIMPL(InputOptions);
NVTT_API InputOptions();
NVTT_API ~InputOptions();
// Set default options.
NVTT_API void reset();
// Setup input layout.
NVTT_API void setTextureLayout(TextureType type, int w, int h, int d = 1);
NVTT_API void resetTextureLayout();
// Set mipmap data. Copies the data.
NVTT_API bool setMipmapData(const void * data, int w, int h, int d = 1, int face = 0, int mipmap = 0);
// Describe the format of the input.
NVTT_API void setFormat(InputFormat format);
// Set the way the input alpha channel is interpreted. @@ Not implemented!
NVTT_API void setAlphaMode(AlphaMode alphaMode);
// Set gamma settings.
NVTT_API void setGamma(float inputGamma, float outputGamma);
// Set texture wrapping mode.
NVTT_API void setWrapMode(WrapMode mode);
// Set mipmapping options.
NVTT_API void setMipmapFilter(MipmapFilter filter);
NVTT_API void setMipmapGeneration(bool enabled, int maxLevel = -1);
NVTT_API void setKaiserParameters(float width, float alpha, float stretch);
// Set normal map options.
NVTT_API void setNormalMap(bool b);
NVTT_API void setConvertToNormalMap(bool convert);
NVTT_API void setHeightEvaluation(float redScale, float greenScale, float blueScale, float alphaScale);
NVTT_API void setNormalFilter(float sm, float medium, float big, float large);
NVTT_API void setNormalizeMipmaps(bool b);
// Set resizing options.
NVTT_API void setMaxExtents(int d);
NVTT_API void setRoundMode(RoundMode mode);
};
/// Output handler.
struct OutputHandler
{
virtual ~OutputHandler() {}
/// Indicate the start of a new compressed image that's part of the final texture.
virtual void beginImage(int size, int width, int height, int depth, int face, int miplevel) = 0;
/// Output data. Compressed data is output as soon as it's generated to minimize memory allocations.
virtual bool writeData(const void * data, int size) = 0;
};
/// Error codes.
enum Error
{
Error_Unknown,
Error_InvalidInput,
Error_UnsupportedFeature,
Error_CudaError,
Error_FileOpen,
Error_FileWrite,
Error_UnsupportedOutputFormat,
};
/// Error handler.
struct ErrorHandler
{
virtual ~ErrorHandler() {}
// Signal error.
virtual void error(Error e) = 0;
};
/// Container.
enum Container
{
Container_DDS,
Container_DDS10,
};
/// Output Options. This class holds pointers to the interfaces that are used to report the output of
/// the compressor to the user.
struct OutputOptions
{
NVTT_FORBID_COPY(OutputOptions);
NVTT_DECLARE_PIMPL(OutputOptions);
NVTT_API OutputOptions();
NVTT_API ~OutputOptions();
// Set default options.
NVTT_API void reset();
NVTT_API void setFileName(const char * fileName);
NVTT_API void setOutputHandler(OutputHandler * outputHandler);
NVTT_API void setErrorHandler(ErrorHandler * errorHandler);
NVTT_API void setOutputHeader(bool outputHeader);
NVTT_API void setContainer(Container container);
NVTT_API void setUserVersion(int version); NVTT_API void setUserVersion(int version);
}; };
/// Context. /// Context.
struct Compressor struct Compressor
{ {
NVTT_FORBID_COPY(Compressor); NVTT_FORBID_COPY(Compressor);
NVTT_DECLARE_PIMPL(Compressor); NVTT_DECLARE_PIMPL(Compressor);
NVTT_API Compressor(); NVTT_API Compressor();
NVTT_API ~Compressor(); NVTT_API ~Compressor();
// Context settings. // Context settings.
NVTT_API void enableCudaAcceleration(bool enable); NVTT_API void enableCudaAcceleration(bool enable);
NVTT_API bool isCudaAccelerationEnabled() const; NVTT_API bool isCudaAccelerationEnabled() const;
// InputOptions api. // InputOptions API.
NVTT_API bool process(const InputOptions & inputOptions, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const; NVTT_API bool process(const InputOptions & inputOptions, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const;
NVTT_API int estimateSize(const InputOptions & inputOptions, const CompressionOptions & compressionOptions) const; NVTT_API int estimateSize(const InputOptions & inputOptions, const CompressionOptions & compressionOptions) const;
// RAW api. // TexImage API.
NVTT_API bool compress2D(InputFormat format, int w, int h, void * data, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const; NVTT_API bool outputHeader(const TexImage & tex, int mipmapCount, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const;
//ßNVTT_API bool compress3D(InputFormat format, int w, int h, int d, void * data, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const; NVTT_API bool compress(const TexImage & tex, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const;
NVTT_API int estimateSize(int w, int h, int d, const CompressionOptions & compressionOptions) const; NVTT_API int estimateSize(const TexImage & tex, int mipmapCount, const CompressionOptions & compressionOptions) const;
// TexImage api. // Raw API.
NVTT_API TexImage createTexImage() const; NVTT_API bool compress(int w, int h, int d, const float * rgba, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const;
NVTT_API bool outputHeader(const TexImage & tex, int mipmapCount, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const; NVTT_API int estimateSize(int w, int h, int d, int mipmapCount, const CompressionOptions & compressionOptions) const;
NVTT_API bool compress(const TexImage & tex, const CompressionOptions & compressionOptions, const OutputOptions & outputOptions) const; };
NVTT_API int estimateSize(const TexImage & tex, const CompressionOptions & compressionOptions) const;
};
// "Compressor" is deprecated. This should have been called "Context" // "Compressor" is deprecated. This should have been called "Context"
typedef Compressor Context; typedef Compressor Context;
/// DXT decoder.
enum Decoder
{
Decoder_Reference,
Decoder_NV5x,
};
/// A texture mipmap. /// DXT decoder.
struct TexImage enum Decoder
{ {
NVTT_API TexImage(const TexImage & tex); Decoder_Reference,
NVTT_API ~TexImage(); Decoder_NV5x,
};
NVTT_API void operator=(const TexImage & tex); /// A texture mipmap.
struct TexImage
{
NVTT_API TexImage();
NVTT_API TexImage(const TexImage & tex);
NVTT_API ~TexImage();
// Texture parameters. NVTT_API void operator=(const TexImage & tex);
NVTT_API void setTextureType(TextureType type);
NVTT_API void setWrapMode(WrapMode mode);
NVTT_API void setAlphaMode(AlphaMode alphaMode);
NVTT_API void setNormalMap(bool isNormalMap);
// Accessors. // Texture parameters.
NVTT_API int width() const; NVTT_API void setTextureType(TextureType type);
NVTT_API int height() const; NVTT_API void setWrapMode(WrapMode mode);
NVTT_API int depth() const; NVTT_API void setAlphaMode(AlphaMode alphaMode);
NVTT_API int faceCount() const; NVTT_API void setNormalMap(bool isNormalMap);
NVTT_API TextureType textureType() const;
NVTT_API WrapMode wrapMode() const; // Accessors.
NVTT_API AlphaMode alphaMode() const; NVTT_API int width() const;
NVTT_API bool isNormalMap() const; NVTT_API int height() const;
NVTT_API int countMipmaps() const; NVTT_API int depth() const;
NVTT_API int faceCount() const;
NVTT_API TextureType textureType() const;
NVTT_API WrapMode wrapMode() const;
NVTT_API AlphaMode alphaMode() const;
NVTT_API bool isNormalMap() const;
NVTT_API int countMipmaps() const;
NVTT_API float alphaTestCoverage(float alphaRef = 0.5) const; NVTT_API float alphaTestCoverage(float alphaRef = 0.5) const;
// Texture data. // Texture data.
NVTT_API bool load(const char * fileName); NVTT_API bool load(const char * fileName);
NVTT_API bool save(const char * fileName) const; NVTT_API bool save(const char * fileName) const;
NVTT_API bool setImage2D(InputFormat format, int w, int h, int idx, const void * data); NVTT_API bool setImage2D(InputFormat format, int w, int h, int idx, const void * data);
NVTT_API bool setImage2D(InputFormat format, int w, int h, int idx, const void * r, const void * g, const void * b, const void * a); NVTT_API bool setImage2D(InputFormat format, int w, int h, int idx, const void * r, const void * g, const void * b, const void * a);
NVTT_API bool setImage2D(Format format, Decoder decoder, int w, int h, int idx, const void * data); NVTT_API bool setImage2D(Format format, Decoder decoder, int w, int h, int idx, const void * data);
// Resizing methods. // Resizing methods.
NVTT_API void resize(int w, int h, ResizeFilter filter); NVTT_API void resize(int w, int h, ResizeFilter filter);
NVTT_API void resize(int maxExtent, RoundMode mode, ResizeFilter filter); NVTT_API void resize(int w, int h, ResizeFilter filter, float filterWidth, const float * params = 0);
NVTT_API bool buildNextMipmap(MipmapFilter filter); NVTT_API void resize(int maxExtent, RoundMode mode, ResizeFilter filter);
NVTT_API void resize(int maxExtent, RoundMode mode, ResizeFilter filter, float filterWidth, const float * params = 0);
// Color transforms. NVTT_API bool buildNextMipmap(MipmapFilter filter);
NVTT_API void toLinear(float gamma); NVTT_API bool buildNextMipmap(MipmapFilter filter, float filterWidth, const float * params = 0);
NVTT_API void toGamma(float gamma);
NVTT_API void transform(const float w0[4], const float w1[4], const float w2[4], const float w3[4], const float offset[4]); // Color transforms.
NVTT_API void swizzle(int r, int g, int b, int a); NVTT_API void toLinear(float gamma);
NVTT_API void scaleBias(int channel, float scale, float bias); NVTT_API void toGamma(float gamma);
NVTT_API void transform(const float w0[4], const float w1[4], const float w2[4], const float w3[4], const float offset[4]);
NVTT_API void swizzle(int r, int g, int b, int a);
NVTT_API void scaleBias(int channel, float scale, float bias);
NVTT_API void clamp(int channel, float low = 0.0f, float high = 1.0f); NVTT_API void clamp(int channel, float low = 0.0f, float high = 1.0f);
NVTT_API void packNormal(); NVTT_API void packNormal();
NVTT_API void expandNormal(); NVTT_API void expandNormal();
NVTT_API void blend(float r, float g, float b, float a, float t); NVTT_API void blend(float r, float g, float b, float a, float t);
NVTT_API void premultiplyAlpha(); NVTT_API void premultiplyAlpha();
NVTT_API void toGreyScale(float redScale, float greenScale, float blueScale, float alphaScale); NVTT_API void toGreyScale(float redScale, float greenScale, float blueScale, float alphaScale);
NVTT_API void setBorder(float r, float g, float b, float a); NVTT_API void setBorder(float r, float g, float b, float a);
NVTT_API void fill(float r, float g, float b, float a); NVTT_API void fill(float r, float g, float b, float a);
NVTT_API void scaleAlphaToCoverage(float coverage, float alphaRef = 0.5f); NVTT_API void scaleAlphaToCoverage(float coverage, float alphaRef = 0.5f);
NVTT_API bool normalizeRange(float * rangeMin, float * rangeMax); NVTT_API bool normalizeRange(float * rangeMin, float * rangeMax);
NVTT_API void toRGBM(float range = 1.0f, float threshold = 0.0f);
NVTT_API void toYCoCg();
NVTT_API void blockScaleCoCg(int bits = 5, float threshold = 0.0f);
// Set normal map options. // @@ Add quantization methods.
NVTT_API void toNormalMap(float sm, float medium, float big, float large);
//NVTT_API void toHeightMap();
NVTT_API void normalizeNormalMap();
// Error compare. // Set normal map options.
NVTT_API float rootMeanSquaredError_rgb(const TexImage & reference) const; NVTT_API void toNormalMap(float sm, float medium, float big, float large);
NVTT_API float rootMeanSquaredError_alpha(const TexImage & reference) const; NVTT_API void normalizeNormalMap();
// Error compare.
NVTT_API float rootMeanSquaredError_rgb(const TexImage & reference) const;
NVTT_API float rootMeanSquaredError_alpha(const TexImage & reference) const;
// Geometric transforms. // Geometric transforms.
NVTT_API void flipVertically(); NVTT_API void flipVertically();
// Copy image data. // Copy image data.
NVTT_API bool copyChannel(const TexImage & srcImage, int srcChannel); NVTT_API bool copyChannel(const TexImage & srcImage, int srcChannel);
NVTT_API bool copyChannel(const TexImage & srcImage, int srcChannel, int dstChannel); NVTT_API bool copyChannel(const TexImage & srcImage, int srcChannel, int dstChannel);
private: private:
TexImage(); void detach();
void detach(); friend struct Compressor::Private;
friend struct Compressor; struct Private;
struct Private; Private * m;
Private * m; };
};
// Return string for the given error code. // Return string for the given error code.
NVTT_API const char * errorString(Error e); NVTT_API const char * errorString(Error e);
// Return NVTT version. // Return NVTT version.
NVTT_API unsigned int version(); NVTT_API unsigned int version();
// Set callbacks.
//NVTT_API void setErrorCallback(ErrorCallback callback);
//NVTT_API void setMemoryCallbacks(...);
} // nvtt namespace } // nvtt namespace
#endif // NVTT_H #endif // NVTT_H

View File

@ -89,16 +89,6 @@ void nvttSetInputOptionsNormalizeMipmaps(NvttInputOptions * inputOptions, NvttBo
inputOptions->setNormalizeMipmaps(b != NVTT_False); inputOptions->setNormalizeMipmaps(b != NVTT_False);
} }
void nvttSetInputOptionsColorTransform(NvttInputOptions * inputOptions, NvttColorTransform t)
{
inputOptions->setColorTransform((nvtt::ColorTransform)t);
}
void nvttSetInputOptionsLinearTransfrom(NvttInputOptions * inputOptions, int channel, float w0, float w1, float w2, float w3)
{
inputOptions->setLinearTransform(channel, w0, w1, w2, w3);
}
void nvttSetInputOptionsMaxExtents(NvttInputOptions * inputOptions, int dim) void nvttSetInputOptionsMaxExtents(NvttInputOptions * inputOptions, int dim)
{ {
inputOptions->setMaxExtents(dim); inputOptions->setMaxExtents(dim);

View File

@ -123,13 +123,6 @@ typedef enum
NVTT_MipmapFilter_Kaiser, NVTT_MipmapFilter_Kaiser,
} NvttMipmapFilter; } NvttMipmapFilter;
/// Color transformation.
typedef enum
{
NVTT_ColorTransform_None,
NVTT_ColorTransform_Linear,
} NvttColorTransform;
/// Extents rounding mode. /// Extents rounding mode.
typedef enum typedef enum
{ {
@ -195,8 +188,6 @@ NVTT_API void nvttSetInputOptionsConvertToNormalMap(NvttInputOptions * inputOpti
NVTT_API void nvttSetInputOptionsHeightEvaluation(NvttInputOptions * inputOptions, float redScale, float greenScale, float blueScale, float alphaScale); NVTT_API void nvttSetInputOptionsHeightEvaluation(NvttInputOptions * inputOptions, float redScale, float greenScale, float blueScale, float alphaScale);
NVTT_API void nvttSetInputOptionsNormalFilter(NvttInputOptions * inputOptions, float sm, float medium, float big, float large); NVTT_API void nvttSetInputOptionsNormalFilter(NvttInputOptions * inputOptions, float sm, float medium, float big, float large);
NVTT_API void nvttSetInputOptionsNormalizeMipmaps(NvttInputOptions * inputOptions, NvttBoolean b); NVTT_API void nvttSetInputOptionsNormalizeMipmaps(NvttInputOptions * inputOptions, NvttBoolean b);
NVTT_API void nvttSetInputOptionsColorTransform(NvttInputOptions * inputOptions, NvttColorTransform t);
NVTT_API void nvttSetInputOptionsLinearTransform(NvttInputOptions * inputOptions, int channel, float w0, float w1, float w2, float w3);
NVTT_API void nvttSetInputOptionsMaxExtents(NvttInputOptions * inputOptions, int dim); NVTT_API void nvttSetInputOptionsMaxExtents(NvttInputOptions * inputOptions, int dim);
NVTT_API void nvttSetInputOptionsRoundMode(NvttInputOptions * inputOptions, NvttRoundMode mode); NVTT_API void nvttSetInputOptionsRoundMode(NvttInputOptions * inputOptions, NvttRoundMode mode);

View File

@ -38,7 +38,7 @@ int main(int argc, char *argv[])
context.enableCudaAcceleration(false); context.enableCudaAcceleration(false);
// Load input image. // Load input image.
nvtt::TexImage image = context.createTexImage(); nvtt::TexImage image;
if (!image.load(inputFileName)) { if (!image.load(inputFileName)) {
return EXIT_FAILURE; return EXIT_FAILURE;
} }

View File

@ -43,7 +43,7 @@ int main(int argc, char *argv[])
context.enableCudaAcceleration(false); context.enableCudaAcceleration(false);
// Load color map. // Load color map.
nvtt::TexImage colorMap = context.createTexImage(); nvtt::TexImage colorMap;
if (!colorMap.load(inputFileNameColor)) { if (!colorMap.load(inputFileNameColor)) {
printf("Image '%s' could not be loaded.\n", inputFileNameColor); printf("Image '%s' could not be loaded.\n", inputFileNameColor);
return EXIT_FAILURE; return EXIT_FAILURE;
@ -63,9 +63,8 @@ int main(int argc, char *argv[])
colorOutputOptions.setFileName(outputFileNameColor.str()); colorOutputOptions.setFileName(outputFileNameColor.str());
// Load normal map. // Load normal map.
nvtt::TexImage normalMap = context.createTexImage(); nvtt::TexImage normalMap;
if (inputFileNameNormal != NULL) { if (inputFileNameNormal != NULL) {
normalMap = context.createTexImage();
if (!normalMap.load(inputFileNameColor)) { if (!normalMap.load(inputFileNameColor)) {
printf("Image '%s' could not be loaded.\n", inputFileNameNormal); printf("Image '%s' could not be loaded.\n", inputFileNameNormal);
return EXIT_FAILURE; return EXIT_FAILURE;

View File

@ -37,6 +37,7 @@
#include <stdlib.h> // free #include <stdlib.h> // free
#include <string.h> // memcpy #include <string.h> // memcpy
#include "../tools/cmdline.h"
using namespace nv; using namespace nv;
@ -294,11 +295,15 @@ float rmsError(const Image * a, const Image * b)
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
const uint version = nvtt::version(); MyAssertHandler assertHandler;
const uint major = version / 100; MyMessageHandler messageHandler;
const uint minor = version % 100;
printf("NVIDIA Texture Tools %u.%u - Copyright NVIDIA Corporation 2007 - 2008\n\n", major, minor); const uint version = nvtt::version();
const uint major = version / 100 / 100;
const uint minor = (version / 100) % 100;
const uint rev = version % 100;
printf("NVIDIA Texture Tools %u.%u.%u - Copyright NVIDIA Corporation 2007\n\n", major, minor, rev);
int set = 0; int set = 0;
bool fast = false; bool fast = false;

View File

@ -32,36 +32,36 @@
struct MyMessageHandler : public nv::MessageHandler { struct MyMessageHandler : public nv::MessageHandler {
MyMessageHandler() { MyMessageHandler() {
nv::debug::setMessageHandler( this ); nv::debug::setMessageHandler( this );
} }
~MyMessageHandler() { ~MyMessageHandler() {
nv::debug::resetMessageHandler(); nv::debug::resetMessageHandler();
} }
virtual void log( const char * str, va_list arg ) { virtual void log( const char * str, va_list arg ) {
va_list val; va_list val;
va_copy(val, arg); va_copy(val, arg);
vfprintf(stderr, str, arg); vfprintf(stderr, str, arg);
va_end(val); va_end(val);
} }
}; };
struct MyAssertHandler : public nv::AssertHandler { struct MyAssertHandler : public nv::AssertHandler {
MyAssertHandler() { MyAssertHandler() {
nv::debug::setAssertHandler( this ); nv::debug::setAssertHandler( this );
} }
~MyAssertHandler() { ~MyAssertHandler() {
nv::debug::resetAssertHandler(); nv::debug::resetAssertHandler();
} }
// Handler method, note that func might be NULL! // Handler method, note that func might be NULL!
virtual int assertion( const char *exp, const char *file, int line, const char *func ) { virtual int assertion( const char *exp, const char *file, int line, const char *func ) {
fprintf(stderr, "Assertion failed: %s\nIn %s:%d\n", exp, file, line); fprintf(stderr, "Assertion failed: %s\nIn %s:%d\n", exp, file, line);
nv::debug::dumpInfo(); nv::debug::dumpInfo();
exit(1); exit(1);
} }
}; };

View File

@ -412,10 +412,10 @@ int main(int argc, char *argv[])
inputOptions.setFormat(nvtt::InputFormat_RGBA_32F); inputOptions.setFormat(nvtt::InputFormat_RGBA_32F);
inputOptions.setTextureLayout(nvtt::TextureType_2D, image->width(), image->height()); inputOptions.setTextureLayout(nvtt::TextureType_2D, image->width(), image->height());
for (uint i = 0; i < image->componentNum(); i++) /*for (uint i = 0; i < image->componentNum(); i++)
{ {
inputOptions.setMipmapChannelData(image->channel(i), i, image->width(), image->height()); inputOptions.setMipmapChannelData(image->channel(i), i, image->width(), image->height());
} }*/
} }
else else
{ {
@ -450,8 +450,11 @@ int main(int argc, char *argv[])
inputOptions.setAlphaMode(nvtt::AlphaMode_None); inputOptions.setAlphaMode(nvtt::AlphaMode_None);
} }
inputOptions.setRoundMode(nvtt::RoundMode_ToNearestPowerOfTwo); // Block compressed textures with mipmaps must be powers of two.
//if (!noMipmaps && format != nvtt::Format_RGB)
{
inputOptions.setRoundMode(nvtt::RoundMode_ToNearestPowerOfTwo);
}
if (normal) if (normal)
{ {
@ -471,11 +474,11 @@ int main(int argc, char *argv[])
inputOptions.setMipmapGeneration(false); inputOptions.setMipmapGeneration(false);
} }
if (premultiplyAlpha) /*if (premultiplyAlpha)
{ {
inputOptions.setPremultiplyAlpha(true); inputOptions.setPremultiplyAlpha(true);
inputOptions.setAlphaMode(nvtt::AlphaMode_Premultiplied); inputOptions.setAlphaMode(nvtt::AlphaMode_Premultiplied);
} }*/
inputOptions.setMipmapFilter(mipmapFilter); inputOptions.setMipmapFilter(mipmapFilter);

View File

@ -169,14 +169,14 @@ int main(int argc, char *argv[])
nv::FloatImage fimage(&image); nv::FloatImage fimage(&image);
fimage.toLinear(0, 3, gamma); fimage.toLinear(0, 3, gamma);
#if 0 #if 1
nv::AutoPtr<nv::FloatImage> fresult(fimage.resize(*filter, uint(image.width() * scale), uint(image.height() * scale), wrapMode)); nv::AutoPtr<nv::FloatImage> fresult(fimage.resize(*filter, uint(image.width() * scale), uint(image.height() * scale), wrapMode));
nv::AutoPtr<nv::Image> result(fresult->createImageGammaCorrect(gamma)); nv::AutoPtr<nv::Image> result(fresult->createImageGammaCorrect(gamma));
result->setFormat(nv::Image::Format_ARGB); result->setFormat(nv::Image::Format_ARGB);
nv::StdOutputStream stream(output); nv::StdOutputStream stream(output.str());
nv::ImageIO::save(output, stream, result.ptr()); nv::ImageIO::save(output.str(), stream, result.ptr());
#endif #endif
return 0; return 0;
} }